We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Thinking in Functional Style using F# and (some) C#

00:00

Formal Metadata

Title
Thinking in Functional Style using F# and (some) C#
Title of Series
Number of Parts
110
Author
License
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
Functional Programming has been around for a while, but it is gaining popularity, especially due to direct support in languages on the JVM and the CLR. Writing code in functional style is not about syntax. It is a paradigm shift. In this presentation, using examples from F# and C#, you will learn how to write code in functional style. We will start out discussing the elements of functional programming and then look at examples of some common operations and how you can implement those in functional style. Thinking in Functional Style using F# and (some) C#Functional Programming has been around for a while, but it is gaining popularity, especially due to direct support in languages on the JVM and the CLR. Writing code in functional style is not about syntax. It is a paradigm shift. In this presentation, using examples from F# and C#, you will learn how to write code in functional style. We will start out discussing the elements of functional programming and then look at examples of some common operations and how you can implement those in functional style.
23
63
77
Computer programmingFunctional programmingFunction (mathematics)Imperative programmingTotal S.A.Link (knot theory)EmailSoftware developerBitMultiplication signWhiteboardIntegrated development environmentFunctional programmingCartesian coordinate systemMereologyProgramming languageState of matterTransformation (genetics)Operating systemNoise (electronics)Core dumpElectronic mailing listBookmark (World Wide Web)Statement (computer science)Arithmetic meanCodeRight angleStructured programmingError messageBoss CorporationPresentation of a groupShared memoryComputer programmingComputing platformExpressionFrame problemCrash (computing)WordDependent and independent variablesImperative programmingWritingFunctional programmingObject-oriented programmingNumberCoprocessorMultiplicationThread (computing)Concurrency (computer science)Order (biology)Different (Kate Ryan album)CollisionReading (process)CodeDegree (graph theory)Term (mathematics)Multi-core processorSingle-precision floating-point formatSoftware developerLambda calculusSlide ruleComputer animation
Computer programmingFunctional programmingFunction (mathematics)Imperative programmingTotal S.A.Link (knot theory)EmailSoftware developerSample (statistics)Multiplication signExpressionBitFunctional programmingFlow separationProgramming languageMulti-core processorCodePairwise comparisonLine (geometry)Operator (mathematics)NumberContext awarenessMathematicianCode refactoringJava appletCartesian coordinate systemDecimalError messageCategory of beingLetterpress printingMultiplicationCore dumpChainVariable (mathematics)ResultantDisk read-and-write headCASE <Informatik>SequenceStatement (computer science)WordState of matterMereologyDevice driverComputer programmingFunctional programmingRight angle1 (number)System callDivisorNatural numberProgrammer (hardware)CompilerPRINCE2Confidence intervalOrder (biology)Length of staySemiconductor memoryFile viewerImperative programmingStaff (military)Projective planeDifferent (Kate Ryan album)Computer animation
AutocovarianceComputer programmingFunction (mathematics)Functional programmingImperative programmingTotal S.A.Link (knot theory)EmailSoftware developerSystem programmingGeneric programmingSample (statistics)Fluid staticsOvalNumberCountingVideo game consoleWritingInterior (topology)CodecCartesian coordinate systemFunctional programmingWordType theoryOrder (biology)CircleLambda calculusProgramming languageTerm (mathematics)IterationCoefficient of determinationProgrammschleifeElectronic mailing listMultiplication signObject-oriented programmingArrow of timeParameter (computer programming)Right angleFunctional programmingNumberMereologyMechanism designPrice indexElement (mathematics)CASE <Informatik>System callFitness functionSpacetimeLine (geometry)Computer programmingBitLoop (music)Letterpress printingJava appletCellular automatonPoint (geometry)2 (number)FamilyGraph coloringOperator (mathematics)CountingExpressionResultantAlgebraic closurePerimeterLecture/Conference
NumberSoftware developerElectronic mailing listOrder (biology)BitElement (mathematics)Parameter (computer programming)Functional programmingIterationCodeStructured programmingArithmetic meanChainProgramming languageComputer programmingNumberFormal grammarWordRight angleAreaLetterpress printingElectronic mailing listCodecContext awarenessVariable (mathematics)CASE <Informatik>MetreRational numberProcess (computing)2 (number)WebsiteProgrammschleifeMechanism designControl flowComputer animation
Link (knot theory)Software developerComputer programmingFunction (mathematics)Functional programmingImperative programmingTotal S.A.EmailChi-squared distributionVideo game consoleGeneric programmingSystem programmingSample (statistics)NumberWritingOvalFluid staticsCountingError messageDynamic random-access memoryWebsiteFunctional programmingMathematicsOrder (biology)CodeControl flowLevel (video gaming)Functional programmingBitTask (computing)NumberElement (mathematics)2 (number)Multiplication signPoint (geometry)Equaliser (mathematics)IntegerElectronic mailing listParameter (computer programming)Loop (music)Statement (computer science)Right angleEnumerated typeError messageCASE <Informatik>Touch typingGreatest elementFunction (mathematics)Logic programmingOperator (mathematics)Doubling the cubeSelectivity (electronic)Computer animation
NumberSoftware developerElectronic mailing listComputer programmingFunction (mathematics)Functional programmingTotal S.A.Imperative programmingLink (knot theory)EmailOperator (mathematics)MappingImperative programmingNumberFunction (mathematics)Total S.A.outputElement (mathematics)Variable (mathematics)Electronic mailing list1 (number)Context awarenessDisk read-and-write headMoment (mathematics)Line (geometry)Object-oriented programmingCodeRight anglePoint (geometry)MathematicsSpeicherbereinigungFunctional programmingNeuroinformatikCodeDifferent (Kate Ryan album)Series (mathematics)SynchronizationFunctional programmingSemiconductor memoryLevel (video gaming)CASE <Informatik>Multiplication signResultantChainWater vaporError messageComputer animation
NumberSoftware developerTotal S.A.Electronic mailing listSample (statistics)Element (mathematics)Row (database)ResultantSystem callParallel portDifferent (Kate Ryan album)Point (geometry)ChainDependent and independent variablesCodeFunctional programmingOperator (mathematics)Total S.A.NumberContext awarenessSpecial functionsLine (geometry)Parameter (computer programming)Right angleReduction of orderImperative programmingIterationEqualiser (mathematics)Equals signVariable (mathematics)Error messageSet (mathematics)Analytic continuationEndliche ModelltheorieExact sequenceArmProcess (computing)CASE <Informatik>Data storage deviceMultiplication signINTEGRALGastropod shellQuicksortBuffer overflowComputer animation
Total S.A.NumberElectronic mailing listLink (knot theory)Computer programmingFunctional programmingEmailFunction (mathematics)Imperative programmingSoftware developerJava appletAutocovariancePoisson-KlammerMathematicsSound effectBitTransformation (genetics)Nominal numberSoftwareState of matterDecision theoryCodeComputer programmingPoint (geometry)NumberCartesian coordinate systemHeegaard splittingRight angleMultiplication signProduct (business)Set (mathematics)Online helpFunctional programmingHeat transferDirection (geometry)Shape (magazine)Moment (mathematics)Goodness of fitObject-oriented programmingTerm (mathematics)Form (programming)Order (biology)Logic programmingKey (cryptography)Insertion lossSystem programmingClosed setProgramming languageBeat (acoustics)SummierbarkeitJava appletErlang distributionComputer animation
Total S.A.NumberElectronic mailing listSoftware developerDigital filterOperator (mathematics)BitResultantCASE <Informatik>NumberPoint (geometry)Functional programmingElectronic mailing listError messageCylinder (geometry)Loop (music)Cone penetration testElement (mathematics)Boolean algebraLevel (video gaming)SubsetFunction (mathematics)2 (number)MereologyMappingState of matterComputer animation
Sample (statistics)Context awarenessToken ringFile formatSoftware developerField (computer science)Error messageNumberDigital filterElectronic mailing listFinite element methodData typeExecution unitTotal S.A.Bit2 (number)Error messageResultantElectronic mailing listOperator (mathematics)Element (mathematics)Functional programmingNumberSemiconductor memoryComputer programmingPoint (geometry)Line (geometry)CodeFunctional programmingTotal S.A.EmailLetterpress printingWordDisk read-and-write headStructured programmingNetwork topologyMultiplication signMappingSeries (mathematics)SequenceTransformation (genetics)Parameter (computer programming)Programming paradigmProgramming languageFigurate numberDataflowData structureCASE <Informatik>Hand fanData storage deviceSystem callType theoryInteger factorizationEqualiser (mathematics)Online helpContext awarenessAlgebraic closureLevel (video gaming)DivisorRational numberDifferent (Kate Ryan album)Right angleCombinational logic19 (number)Boolean algebraKey (cryptography)Computer animation
Software developerNormed vector spaceClient (computing)Line (geometry)System programmingLengthIntelSystem on a chipFinite-state machineConstructor (object-oriented programming)Error messageSample (statistics)Electronic mailing listDigital filterCode2 (number)Multiplication signObject-oriented programmingBitElectronic mailing listReduction of orderFunctional programmingSystem callDrop (liquid)Symbol tableTransformation (genetics)Data structureOperator (mathematics)State of matterExpected valueWeb 2.0ParsingTupleResultantConnected spaceLogic programmingLetterpress printingRight angleTask (computing)Arithmetic meanBookmark (World Wide Web)Structured programmingClient (computing)Point (geometry)Process (computing)Programming paradigmLevel (video gaming)Parameter (computer programming)Endliche ModelltheorieComa BerenicesShift operatorReal numberComputer animation
Computer programmingFunctional programmingFunction (mathematics)Imperative programmingTotal S.A.Link (knot theory)EmailSoftware developerCodeTerm (mathematics)Computer programmingProgramming paradigmRight angleMultiplication signShift operatorMulti-core processorSoftwareComputer animation
Transcript: English(auto-generated)
All right, good morning. Welcome to the session on thinking in functional style in F-sharp and some C-sharp. My name is Venkat Subramanyam. We're going to talk about functional programming. Best time to ask a question or make a comment is when you have it, so please don't wait until the very end. Just about any time is a great time for questions, comments.
If you do have a question or a comment, do draw my attention. If you raise your hand, I may not be able to see you. So just start speaking or just call out my name or make some noise that draws attention towards you, and I'll yield to you and respond to your question or comment. We're going to talk about functional programming. I'm going to do a little bit of talking,
quite a bit of coding. I'm not going to use any slides here in this presentation. I'm going to just write some code, play with some examples. I'll write a little bit more F-sharp than C-sharp, but certainly I'll show you some features in C-sharp. Pretty much what we're going to talk about here, you could be doing it in almost any language today on the modern operating systems
and most of the platforms today. So with Lambda expressions available in most languages shouldn't be a problem at all. So let's start with functional programming. So what is a functional language? Before I get to the question, it kind of intrigues me to even think about this. If some languages are functional,
does it mean other languages are dysfunctional? It kind of makes me wonder, right? So what's a functional language? What is it really about? So if you go back to thinking about programming and back in time, structural programming, one of the things that Dijkstra talked about was go-tos are evil. Every time somebody writes a go-to statement,
Dijkstra moves in his grave, right? Because you don't want to be writing go-to statements. But it doesn't mean that go-tos doesn't happen in the code. In a similar way, one of the things that functional programming talks about is to write assignment-less programming. And when it comes to assignment-less programming, you really want to program with immutability where nothing really changes.
And that really puts a little bit of a burden on us, because then we are focusing on thinking about, how in the world do I really write any practical application where nothing really changes? So even though immutability is a very important part of functional programming, that is not really
the most important, in my opinion. It's really about transformation of state rather than mutability of state. And that's kind of what I want to arrive at today in this discussion. So I'll start out by talking about functional programming just a little bit. We'll spend a little bit of time about mutability and immutability. Then we'll talk about pure functions. We'll talk about higher-order functions. And then we'll talk about a few ways
to use these higher-order functions in writing code that shows the difference between imperative style versus functional style of coding. And then, of course, eventually, finally, we'll talk about how we could actually apply this to some real example. We'll take an example of function composition that shows how elegantly we can put this together
to do something useful. So in terms of functional programming itself, there is this concept of function purity that we are interested in developing. And when it comes to programming, this really has been around. So let's take a look at an example for a minute. Don't worry about being wrong.
I'm wrong most of the time, or my wife says that quite often. But the question is, what year do you think object-oriented programming was created? Just throw a number at me. Very close enough, 1967. When do you think most people got excited about OOP?
Not last week. Not in Bob's talk yesterday. When was it? 90s, right? Early 90s, late 80s. And what made that happen? It's OK. You can say it. C++, right?
Yeah, C++ made that happen. And certainly, it took a good 23 years for this concept to really become mainstream. If OOP was a human, it had a terrible childhood, right? Nobody wanted to even look at this guy. Until 23 years old, oh, isn't he cute?
Let's pay attention to this guy, right? And functional programming has been around even longer, for about 50 years now. Scary. And finally, we are paying attention to it. Why so? And the reason is, about 2003 time frame, an engineer walked up his boss and said, it ran really fast before it melted. He was talking about the chips.
And we had to really go to multi-core processors. Well, OK, what's the big deal? We could program multi-threading in most of the languages today. What difference does it make? Well, it turns out, on a single processor, multi-threading is more multi-tasking. On a multi-core processor, you really have threads running on steroids concurrently. And it turns out that developing concurrent
applications in traditional way is extremely difficult. It is very error-prone. So what is causing this error? One of the things that causes this error is the so-called shared mutability. And shared mutability really is a big deal,
because when you think about mutability, mutability itself is not a big deal. You're modifying some data. What about sharing? Sharing is a good thing. Remember what mom told you, right? Share, that's a good thing to do. But shared mutability is devil's work. And the minute you bring shared mutability into picture, you have to worry about making sure multiple threads don't collide and crash
and change the data at the same time, and the code becomes extremely complex. And what do you do to avoid this problem? You start putting locks around your code. And when you do that, just because you put locks doesn't mean your code is correct. And there's no language today, there's no environment today that tells you that you have done the locking correctly
at the right place at the right time to the right degree. And so most of the concurrent applications out there are broken, and we just don't know it. It's extremely hard to write such code. One way to solve this problem is to remove the problem at the very fundamental root, and that is to really create what is called a pure functional code.
A pure functional code is a code that doesn't modify anything. Now, functional programming has been exciting for two categories of people. One is mathematicians and people who are interested in proving correctness of code. I don't think anybody here is interested in correctness code, right? We are interested in living on the edge. Who cares about correctness, right? Well, but they care about it.
They want to know if the code is correct. And it's easier to prove correctness of a code if it doesn't mutate anything. It's easier to establish concepts in that regard. But the other reason why purity is interesting is imagine for a minute that you have two expressions on your hand. This brings back fond memories, by the way.
This was a long time ago, several years ago. I was working on a project, and this was a C++ application, and we had a wonderful programmer, and he screamed one evening, and he found out that there was one expression in our application that was yielding some wrong results.
It was giving an error at the seventh decimal place. You know what? I would have ignored that for the most part. But this guy was so meticulous. He spends three nights in the room working on this problem. How do we know nobody could go near him, right? Well, he hasn't shovered for three days. And this guy comes out after three days and says, I found the problem, and some moron had written this code
where they are incrementing the variable twice in one expression. And in his book, Beyond Stool Strip clearly says, don't do this. And the reason is because it's very difficult to predict the sequence in which these operations have to happen. So in other words, when a code has mutability in place, it's extremely hard to predict the behavior of the code.
But imagine for a minute I have two expressions on my hand where the expressions don't depend on each other, but the net result of them are going to be used further down in the chain. What I can do is I can run as a compiler, I can say I want to run the expression one first, and then I want to run expression two.
That's perfectly fine. But I also, at will, can decide to run expression two first, and then I can run expression one. Or more interesting, I can delegate these two expressions to run concurrently on multi-core processors across multiple cores if I want to. And so this, by the way, is called the referential transparency.
In other words, if functions are pure, it's much easier for referential transparency to be implemented. It becomes a lot more easier to work with the code. So functional code are much more safer to work with in this particular context. So one of the major problems is the shared mutable state.
Now, unfortunately, languages like Java and C Sharp, are, it's a common practice to use mutability in code. But better languages actually don't allow you to do that. If you consider a pure functional language, in a pure functional language, you will never be able to modify a variable once you create it.
But F Sharp is not a pure functional language. It's a hybrid functional language. It's a hybrid functional language because it allows you to do stuff like you do in C Sharp, more of an imperative style with mutability, but it also allows you to do with functional style of coding if you're interested. So for example, if I were to create a variable
called temperature over here, and let's say set the value to maybe a plus and 25 degrees, as the weather is mostly this week, and we could then say print out the value of the temperature for me, and I could say here is the temperature value, and sure enough, it is 25.
I change the value of temperature, lower it just a little bit to a more comfortable level, maybe, and then we want to ask what the temperature is. Again, we can say give me the value of temperature, and as you see, the temperature value did not change at all. Now you're wondering what in the world happened here,
and the reason is what really was happening on line number four is not an assignment, but rather a comparison operation that was happening. So for example, if I were to put a print statement before this and ask him what the value in this particular context is, you will notice that it tells me that it is a false,
and the reason is that the value of temperature right now is not equal to a value of 15. So as we are used to the equals in language like C sharp, we kind of look at it like an assignment, but it's really a comparison operation. In other words, variables are unbounded,
and the minute they are bounded, you can only compare them. But if you really want mutability, you can do that in C sharp also, and in F sharp also, and the way to do that is to really create a variable that allows mutation. But C sharp wants to shame you a little bit for doing that. So they force you to use a special keyword called mutable,
so you kind of hang your head low when you do this and say, yes, I really am creating a mutable variable. And then, of course, you can modify the variable in this context, and then you can say temperature is 15, and you are able to modify the variable in this context
using a different syntax in this particular case. So F sharp really allows mutability, but it is not a preferred way. I like this because it's easy to quickly grep in the code and look for places you are using mutable variables, do a quick code review, and say, hey, why can't we rewrite this, refactor this code, so that it's more immutable in nature,
so it's easier to grasp this than not having a special syntax for this purposes. So mutability is really a critical thing, but what about this purity of functions? So in terms of functional style of programming, I'm going to draw two distinctions here. Imagine drawing two circles, a small circle
and a bigger circle. And the small circle, of course, is more encompassing. It contains more features. The bigger circle is a little loose and has lesser features. At the outer circle, I'm going to put words like higher order functions. And what that means is you can create functions
within functions, return function from functions, and then you can send functions to functions and so on. In other words, you can compose your application using functions. If you draw that outer circle as higher order functions, a lot of languages fit into that outer circle today. For example, F sharp fits into that outer circle. C sharp fits into the outer circle today
because of lambda expressions. Java 8 will fit into that circle. Groovy, Scala, you know, so many other languages you can think of fit into that outer circle. Erlang, Haskell, Clojure, all of those fit into it. But the inner circle I want to draw is a more restrictive circle where the language enforces purity.
And only a few languages come into that inner circle, like languages that really enforce purity where you cannot mutate anything at all whatsoever. If that is the inner circle, then I would move F sharp to the border of that circle and Scala to the border of the circle because those languages do provide a way
to enforce immutability, but they also provide mechanisms to break away from them so they're not very pure in that regard. But then language like Erlang has more purity built into them, so they clearly fit into this inner circle of very pure functional languages. So in terms of purity, what is the benefit of purity?
The benefit of purity, like I talked about, is the referential transparency. You can reorder functions at will, and it becomes easier for really creating concurrent applications. But what about higher order functions? We can create higher order functions in most languages today. Let's start with an example in C sharp
and work with a little bit of an example of higher order function. So let's say I have a list of numbers on hand, and this list of numbers is going to be, let's simply say that I'm going to have just a bunch of values given to this. So this is going to be, let's say, a few values that I can think of here,
and I want to loop through these values and print these values, pretty common operation, but a very simple operation also. Now we all know one way to do this, right? For int i equal to zero, i less than numbers dot count, and this is the part where you have to pause
and ask yourselves, is it less than or less than or equal to? That is called a self-inflicted wound, right? There is no reason to suffer through those any more in programming, and this is so archaic way of doing it, but sure, that's definitely an option available for us. And then we can, of course, print the value in this case
and I could say this is going to be the numbers i that I want to print, maybe I'll give a space here, and then when we are done with this, we'll just give a empty line for it to print the values out. But of course, a better way to program this in C sharp is to use a for each statement, where we could go through the numbers and right off the bat we can see how lightweight this is, relatively speaking,
and then we could say the number e itself I want to print, no need to mess with the indices values, that becomes a lot more easier to work with. But of course, you don't have to work through that much effort also in C sharp any more, so you could use more of a higher order function in this case. So you could simply say, why not take the numbers
and call a for each on it directly, where I'm going to receive an element and I'm going to simply ask him to print the value of the element I have on hand, and in this case, I'm going to print the element e given to me. So if you look at this example here, what I'm doing is to use a higher order function,
but what in the world is a higher order function? Just look at this part for a second, we'll get back to this more, but to us, most of us, we could say a function contains four things. A function has a name, a function has a body, a function has a return type, and a function has a parameter list.
So given a name, a parameter list, a return type, and a body, we could argue the body is the most important thing in a function. So in this function, this is a function we are sending to the for each function, so the for each function is considered to be the higher order function. And the reason for each is a higher order function is
the function says, I am really elevating myself, not just asking for objects to be sent to me, but I'm even willing to accept functions from you, so it's really a higher order function that you can pass functions to this function, you can return functions from functions, you can also create functions within functions as well.
Now in this case, the for each higher order function is receiving a function, and to the right of this arrow is the body of the function you are trying to send to this function. So of the four things I talked about, we covered the body. What about the parameter list? The parameter list is to the left of the arrow,
right there. What about the return type? The return type is inferred. Hey, what about the name of this function? Well, what's in the name, it's anonymous, we don't care to give a name for this function. So the for each function is a higher order function that accepted this function as a parameter, and we pass to it, and as a result, we moved away from
what is a traditional external iterator to more of a nice and concise internal iterator. An external iterator is kind of like a rude dog in the house. It just sits on your mat, and you have to ask it to move, and every time you have to push it, it doesn't want to move a foot, right?
What is an internal iterator? Completely relieves the duties from your hands. It says, I will do the looping. You simply tell me what you want to achieve for each of the iterations in the loop. So as a result, it's a lot more concise, and it takes away the tedious effort and lets you focus on the real essence
of what you're trying to do. In a similar way, we could use higher order functions in F sharp. I'll give you two examples of how we could do this here. So let's say numbers equals a list of numbers I want to create, one to six, by the way, and I want to print these numbers. I'm not going to go through an external iteration here.
Well, actually, let's do that. Why not? So because F sharp is a hybrid language, it allows you to do both ways of doing things, but we should have the wisdom to choose the right way to do stuff in this particular context. So you could say, for example, for element E in numbers, and you could ask him to do, and you can ask him to print, in this case,
the value of the element itself that you have on hand, and when you are done, of course, I want him to print, in this case, an empty list for us. So that could be an example of how we could print the values using an imperative style and through a traditional looping mechanism, we could do that.
But we don't have to do coding like that in F sharp. A more idiomatic way, I think that is the most important thing. When you program in languages, it's really not about the syntax of a language. I mean, honestly, I could program in about maybe 10 different languages comfortably, but every language is painful to me as I begin to learn
because the syntax never seems to stick into my fingers. Until I code enough, I can't remember those things. But learning the syntax is of no use at all because the real essence in a language is not in its syntax, but in its idioms. Now, think about this for a minute. Idioms are really the problematic areas,
but also fun areas also. I can speak English, actually I can speak English barely as my English teacher would like to remind me. And when I can speak English, but I go to different countries, and what really twists me off is, when they speak English, it's not that I cannot understand the words they speak, but I don't know the idioms they speak.
So I cannot just look up a dictionary and say, what do those words mean? And when you put the words together, it means something absurd and nonsense and definitely doesn't mean what they actually said. Because idioms are structured based on culture and context, and there's always a story behind idioms as they were created.
So learning a language involves learning the structure and the grammar of the language, but also learning the idioms when you learn in a society. And normally you learn the idioms in a society when you live in the society for a while, and you kind of ask people, what does that mean? Why did you say that? In a similar way, when you program in a language,
it's not about the syntax of the language, but we have to pick up the idioms. How do people who are common in that language program in that language? The idiomatic style of the language is important for us to understand. So what I'm going to do here is to tell that I want to take the numbers over here, and I'm going to call an iterator.
And to the iterator, I'm going to pass the print function, and I tell the print function to print over here an element that I want to print. But what in the world is this element? Well, you're going to say fun e. And the reason why you use fun here is it really is fun to program in F sharp, right? So that's why you say it's a function that you're
defining, an anonymous function you are defining. And the parameter of this function takes this e, and then print is going to print that function. And this is going to operate on the numbers collection you are utilizing. Now, that is one way to write the code in F sharp, but you don't have to put that much effort in F sharp
to do this. You could also do the same thing by calling iterator. And you can simply specify here the print function itself over here, if you will. And you can tell him I want to simply print the variables I have on hand for whatever the variable given to me from the numbers over here. And you can see that he's able to print that right here
off the bat without us having to do any extra work. So you can see that in this particular case, the print function knows that it needs two parameters. And it also knows that the second parameter is really going to be passed through from the parameter this anonymous function is receiving.
So F sharp really saves a bit of an effort on your shoulders. It says you don't have to write a stupid code that just simply receives a parameter only to pass it down the chain. I will do the job for you. You just take care of the other parameters needed in this particular function. In a similar way, if this function
were to take two parameters, but those really are what you receive as parameters, you can completely drop the parameters and just drop the function name in there. And it will receive the parameters and chain it through. So it really saves the effort. You're not really writing useless code. And you can just focus on the most important code you want to write. So that is an example of the code in F sharp
using higher order functions and more of an idiomatic style of writing this code. By the way, I'm writing quite a bit of code here. You can download the code from my website later on if you're interested. And you can play with it. The fun about code is you can work with it, break it, change it, evolve it. Certainly you can download it anytime you want to
from that website. So I'm talking about the functional style, the higher order functions here quite a bit. But how does this really map over to an imperative versus a functional style of coding? So let's take a look at two examples of this. Let's first look at C sharp for a minute. Imagine for a minute you are given the task of doubling each of the numbers given to you.
So that's what you've been asked to do. So how would you double the values in the list in a traditional C sharp code? So it looks something like this, right? You say list integer doubled, but it's really doubled boring way of doing it, right?
Because we have done this before. And equals to new list of integer. And then what do you do after this? You say for element e in numbers. And then you say double the boring dot add e times 2. And when you are done with it, you
can say element in doubled boring. And then you can print out the value at this point. And you can say this is going to be the value in the element that you want to print. And then you can specify the value that you have printed so far. So that is basically the code that is going to loop through and print the values in this particular collection.
Now look at this example for a second. What did I do wrong? Anybody see what the problem is? At the end, I'm missing a curly brace at the very end. That would actually help to put it. Thank you for debugging that. I should have stayed with that error. It was fewer errors. OK, so what's the problem now?
For each, thank you. So another for each, of course. Are we done with this? All right. So right there, that was a lot of code to write. No wonder there's more mistakes to make over there. By the way, we all have done code like this, right?
Yeah? How do you feel about this code when you write it? You feel dirty, don't you? You don't feel energetic. You go home, what do you say? You say, don't touch me. I have to shower first, right? And you feel like you have to cleanse yourself before you go home, right?
Because that is so boring code to write. Doesn't have any useful stuff other than one little logic hidden somewhere deep in there. We shouldn't be writing code like that. Why don't we try something a little differently? Let's kind of comment that out for a second. And let's simply say, hey, why not simply say, output for me.
Well, actually, let's create a collection right now. So we could say list integer doubled equals. And let's simply say at this point, the doubled value is going to be numbers dot select. Well, what do I want to select? Given an element that is given to me, I want to select an element times 2 as a parameter.
So for each of the elements var e in doubled now, I can simply print out the value of the element given to me. So we could use an internal iterator as well. But the essence, really, in this particular case, really, is looking at the select statement itself that we are really interested in working through
in this particular code example, right? So basically, what we are doing here is asking him to loop through. Let me make sure I didn't comment out more than I should comment out. That should really be down here. So let's put that here. Let me get rid of this for a second.
So right there is the list. OK, let's try this one more time. So list of integer, I want to create doubled equals. And I want to simply say, in this particular case, the numbers dot select. And what do I want to select with this? Given an element e, I'm interested in returning an e times 2. That's what I'm really interested in selecting
at this particular point. And of course, he's complaining I can't put it into a list over here. It's an enumeration I'm getting. So now I can say, for each of the elements e in doubled, I can simply ask him to print the value out, which is going to be the element in this particular case. So you can see how we can use
more of an imperative style versus a functional style that you saw in the bottom to really do the operation in the case of f sharp. In a similar way, you can do this in c sharp, rather. In a similar way, you can do this in f sharp as well. We already have the numbers on hand. But I want to really perform this operation.
But really think about this. If you have a collection of data coming in, you're applying certain operation on each of the elements. But they are pretty much independent of each other. And the output you get is a computation applied on the input that has really no mutability involved in this context.
You get a series of input, and you get a series of output. It nicely flows through this. So in that regard, I can simply say here, I want to simply print, in this case, the object I have on hand. And the object I have on hand is numbers.map. And what do I want to do the mapping for?
Given an element, return to me e times 2. That's what the mapping I want to apply. And this is going to be on the list.map. And it's going to apply on the numbers that's given to me on hand. That's the operation I want to perform. So you can see how it's able to apply this operation on each of the elements. So you're saying, given this particular numbers object,
I want you to transform that numbers object using this transformational function. So it's a mapping of input to an output. If you are in doubt at this point, you can look at, for example, the original numbers
object given to you. And you will notice that the original object has been untainted because it's completely immutable and sitting nicely in the memory. We didn't mess with it. So you can see how concise this operation is when you're trying to perform this in imperative style versus a functional style of coding. Just becomes a lot easier to work with.
Now, we can take this further and operate on several other things. You say, OK, Venkat, that was kind of simple. You really took over this particular value and applied this function on these values. And then you got a result. No big deal. But what if you really had to perform a mutation in your code?
For example, let's say I want to total the age of everybody in this room. And how would I total the age of everybody in this room? I'm going to put a zero on the wall here and say, everybody come over here and add your age to the number on the wall. Now I have to police and make sure everybody falls in a line.
Nobody tries to run over here together. I got to worry about synchronization issue and all of that, right? But let's try to do this a little differently. And the way we are going to do this is imagine for a minute that I'm going to ask everybody here to total the age of everybody
in this room. Collectively, we're going to work together. And we're going to start with this gentleman over here. Well, he's not laughing. He's kind of grim at this point. No, I'm not going to ask for your real age. That's OK. So the way we're going to do this is the following. Imagine I have a special Post-it note. This Post-it note is special in that it's a write once
Post-it note. You cannot rewrite on it. You cannot erase what's there. You cannot change what's there. So that's pretty much a done deal once you write once on it. So I'm going to put a zero on this Post-it note. And I'm going to give it to you. What's your name, sir? Mohammed is going to get that Post-it note from me. And he sees a value of zero, because zero
is the age of everybody to his left right now. And he is going to take his own age. And he's going to total to the value of zero. So he's got his age in his mind. But he has to pass it to, what's your name, sir? He's going to pass it to Ivar. How is that going to happen? Because he's not allowed to change this, right?
What are his options? He could create a new one, isn't it? So this is an aha moment for me one day. One of the things that is very beneficial to have for functional programming is automatic garbage collection. Can you imagine writing functional code in C++? Every few lines you have to put a delete.
That would suck, right? So in this case, Mohammed doesn't care about this. He takes this Post-it note with a zero, totals his age to it, creates a new Post-it note, sends it down the chain, and discards it. Make sense? Let's put that in code and see how that's going to work. Let's do this in an imperative style first,
in a style you don't want to do first, so we can compare it and see how this works. Imagine the numbers are the ones I want to total. So I'm going to say let total equal to zero. But I cannot change the value of total, right? So how do we really make sure I can change this value of total? What should I do?
I have to shame myself first. That's correct. So I have to say mutable, followed by putting my head down. Yes, I created a mutable variable. That's what I did. Then I say for element e in numbers, I can say total is equal to the total value, past value,
plus the element. So when we are done with it, we can say total is, and we could specify the value of total that we have on hand. That is an imperative style of coding, isn't it? So we are simply asking him to run through the total. So total is equal to zero. Let's see where the error comes from, numbers equal to.
So what's he complaining about? Line number four, he's not happy. So right there is numbers, do, and ask him to run through it. So right there is total is 21. But that's an imperative style of coding, right? That's what we are doing, asking him to loop through and mutate the variable continuously.
But we're going to write this code in a way not a single variable is tortured or mutated in the code. How could we possibly do that? So I'm going to use a special function. I'm going to say, in this case, let's call this total mutable
to make it really obvious that we created a mutable variable. So that's the total mutable that we used. And now I'm going to create, in this case, total mutable. There we go. And in this case, what I'm going to do is to use let total equals. But what is this value really going to be equal to?
Lister.reduce. So reduce is a function I'm going to use where the reduce function says, given a collection, I'm going to reduce it to a single value. But how am I going to reduce it? So what the reduce function? We talked about internal iterators before. This is a special internal iterator.
The for each we talked about, or the iter we talked about, simply applies the function to each of the elements in the collection. That's all it does. But reduce is special. It is an iterator, all right. But what it does is it starts with the collection given to it and says, I'm going to take the first two elements,
apply the operation, get a result, and then I'm going to move to the next element, take the result and the next element, apply the operation, get the result, move to the next element, apply this result and the next element again. So it kind of cascades through. And the last operation it performs, the result it gets,
it says, oh, there's no more element. Here you go and gives you the result at that point. This is kind of like you passing the value down the chain and what I get back over here in the very end is the age of everybody in this row. Now imagine what the beauty of this is. I could start with him here and we could pass the immutable posted notes along the way.
And finally, the gentleman up there is going to give me the age of everybody in the room which will be some value or an overflow. No, I'm just kidding, right? So it'll be some value, right? That's one way to do it. But that's a sequential way of doing it. But on the other hand, we could do this a little differently.
We could say, let each person in each of the row on the first seat start this. So we can go in parallel now and everybody is totaling in each of the row and the people on the last seat in each of the row have one additional responsibility. They have to pass the posted notes up the chain.
Now we can finish this in as many rows as there are, that less time, right? Because we are doing it concurrently and then we can do it sequentially. That operation there would be the reduce operation where we take all these set of data and we shrink it back to one value in the very end. So how would this really look like?
So the reduce function is going to work with numbers collection. But what's the operation we want to perform here? I want to perform the operation of add it. So what in the world is add it? So add it is going to be a function I want to create which takes two numbers, n1 and n2 as parameters.
And what does it do? Returns n1 plus n2 as the value for it. That's all I'm going to do, right? So all that add it method does is, it simply, or you can call it add two if you want to. Doesn't matter, right? So we'll call it add two. So add two is a function that is going to take
number one and number two and simply add them. So the add two function is going to just add through the values. And notice in this particular case, when I finish this, I ask him, total is, and percent d in this case, total, and he's going to tell me what the total is and it better be the same value.
So we can see how we applied the reduce method to do the same operation, but we did not modify a single variable in this context. How in the world did this do the job? The way it did it is, the reduce method says, I'm going to take the numbers given to me, I'm going to take the first two elements, call the add two method, it gives me a result,
I'm going to then take the result and the third element and call add two, take the result and the fourth element call add two, take the result and the fifth element call add two, and continue along the way until I finish the elements and give you the result on hand. So that is a pure immutable approach to go through
the exercise of doing what we did earlier with full mutability at this point. So we can see how we could even remove mutability from code quite a bit along the way. But the real point of all of this really is, not about removing mutability, but it is really about state transformation.
So what does that really mean? So if you ask me, how do you build an application where nothing changes, I would say that's very simple. It starts with the main, with the curly bracket open, immediately ends, where nothing changes, right? Well, of course, something has to change in the system for things to take effect. But it really is a rethinking of the way
we design software. In a way, we have designed software and object-oriented programming. Alan Keyes, who coined the term uh-oh, really didn't mean it to kind of shape it the way it did. But kind of the languages like C++ and Java and C-sharp kind of drove it along one direction, which is to take objects and beat on it
and keep mutating it. That's really not a, yeah, that's one way to develop software, but it doesn't have to be the way to develop software. So let's think about this a little bit, how this would work. So I'm going to ask Muhammad's help again one more time. Let's say for a minute I have with me 10 chronos, and I need a change for it, right?
I want to ask him to split it into two. I give it to Muhammad and say, Muhammad, could you do me a favor? Could you please split this 10 chronos into two? And if he stands up and tears it into two pieces, I'll be very unhappy with him, right? Because when I asked him to split it, I didn't ask him to tear it into two pieces. What is he going to do?
He's going to take the money I give, put it in his pocket, and then take five bills and give it to me. That's what he's going to do, right? Or if he doesn't have it, he's going to take some of the change he has, send it to the person next to him and say, hey, do you have some more change for these denominations? And eventually I get something.
So if you look at a dollar bill or a currency, that's a great example. We convert currencies not by tearing them into pieces. We convert currencies by receiving some and creating some, and we really transform the states as we go through. And some agencies, of course, take money as they transform it, like I lost some money along the way
when I had to convert my dollar bills to chronos along the way, right? So it's a transformational approach. So think about a functional programming rather than looking at a system as state mutation. Look at a system as a state transformation. Go ahead, please.
Yes. So his question was, this was a simple example we looked at,
but what if we have to take a number and sum it and then take a product out of it and then continue along with it? Can you give an example of it? Right. So yeah, so if you want to really manipulate various different values in the collection, can you look at an example of that? I'll create an example in a few minutes of going through a set of transformation.
From that, you should be able to extrapolate and see how you will be able to apply that. So we'll come back, and then I'll check back with you to see if that example was enough for you. Otherwise, we can take it offline and we can create an example which will be a little bit more intricate, absolutely. But the example I'm going to give you should give you an idea about how we can achieve that. So stay with me for a few minutes to look at that.
So think about this not as a state mutation or a state modification, but more of a state transformation along the way. So it's no surprise that F sharp and more so functional programming languages like Scala and Erlang and stuff like that are really being used more
in a financial industry because they seem to have gotten a good handle on this, where they receive some data and then they go through these transformations to really make decisions. So there's a nice transformational logic in place of holding those in. How do we apply some of those? I want to give you an example of that here.
But before I go to that example, I'll give you two examples here. Let's say for a minute I really want to, I'll give you two examples, one with these numbers. Then I'll create a little bit more realistic example after that. So let's say for a minute, and this kind of goes into something that you talked about, I want to take only even numbers and double them
and total them. That's what I want to do. So take only even numbers and then double them and then total them. If you really want to do some other operation after it, sure, you can just pass the list along the way and you can achieve that if you want to. So let's start with a little bit of a baby step
and then I'll combine it together. So let's say for a minute, let even only equals numbers dot filter. So I'm going to take this collection. We looked at a map function a few minutes ago. What does a map do? Map says, given this input, create an output of the same size, but the operation has been applied on each element.
Filter is different. Given an element of this collection, create me a smaller potentially set of collection. It's kind of like a cone operation rather than a cylinder operation. You're reducing it to a smaller subset. It could be zero or it could be the same number or anything in between those two values.
So filter it. What is the function I want to apply for this? The function I want to apply is e is actually even. So we could say, give me an element where the element is actually an even number. So you can apply this filter operation on him. And then you're telling him on what do you want to apply.
I want to apply this on numbers, if you will. So you're asking him to apply the filter operation on the numbers in this particular case. And he says, I'm going to loop through these. And what does the filter say? Filter says, I'm going to call a function which is going to yield a Boolean result. And as long as the result is true,
I will accept this member. If the result is a false, I will reject this number given to me. That is what this is going to do in this particular case. So that is all we are asking him to do at this particular point. And then what do I do? I want to print this particular function that we created. So I'm going to just ask him to print the even only numbers
that were created by this particular operation. So not sure exactly what the error in this particular case is. Let's take a look at the error result that's given here. Six warning possible. So he's giving us a bit of a warning. Let's run through it and see if the result is still produced. Oh, that was actually an error.
So let me lower the font and look at the error here. Bear with me for a second. Sorry, say that again. Oh, of course, my mind doesn't switch between languages so quickly. It's got to be list filter. You are correct, absolutely correct.
This is where, when you flip between languages, your brain doesn't follow through and the fingers doesn't respond automatically. All right, so in C sharp, you would say collection dot something, right? Whereas in F sharp, you call a static function on it so my brain doesn't switch so easily. Thank you for the help. So right there, we call the list dot filter.
Now I have even numbers only. That makes sense, right? But I want to double these values. How do I do that? So let doubled equals. And then we could say list dot map. And here is the function I want to create. And it returns an element times two. And what is the collection I'm going to work with? It is the even only that I want to work with.
So now I can print the doubled values here. So we'll call it doubled. So this is going to be a double of each of the values. But I want to total the numbers together, remember? So we could say totaled. And what is this now? Let totaled equals list dot reduce method that we created a few minutes ago.
And now what does the reduce do? It takes two numbers, right? n1 and n2 as parameters, returns n1 plus n2 as a value. And what is he working on? On doubled, obviously, in this case. And he's going to give us a total of the values of even numbers doubled. And you can see the result being produced at this point
is the double of those values. But I don't have to go through this much effort to do this, as you will see here in just a second. So notice how I'm going to rewrite this in a different way. So let's go ahead and comment this out for a second so we can see the difference, how this looks when we are done with it. So let's first start with numbers.
And I want to print all the numbers out. So I'm going to apply a function composition operation. And I'm going to say list dot iter. And what do I want to do in the iteration? In the iteration, I want to simply print the function. And I want to print each of the elements in the collection. And that is all I'm going to do here is print the numbers.
But I really don't want to print the numbers, remember? I want to print the total of, the double of, the even numbers. So let's get the even numbers first. So the next operation I perform here is over here is a list. And list dot, hmm, what should I apply?
Of course, the filter operation. What is the function? Function is nothing but the e mod 2 is equal to 0 is the function I want to apply. And notice how he's able to filter the even numbers out and print it. Nice flow functional transformation happening here.
So the numbers that you send here is passed as a parameter here for you. And the result of that is passed as a parameter here for you. And it just flows through this context very nicely. But I really want to reduce this, but only after I double the values. So list dot map, and the function I want to apply here
is going to be e times 2 is the mapping I want to apply. Those values are mapped already. Now I want to take this value one more time. And this time, I want to reduce the values. And the reduce value is going to be a function which takes a number 1 and number 2.
And I want him to do n1 plus n2 as an operation. Or if you had written an add 2 function, you can simply put the word add 2 right there and end of story. We'll do that in a second after we finish this to see how that's going to look like. So in this example, the list dot reduce is going to take the result of this operation.
And the function is going to take n1 and n2. And he is going to return n1 plus n2 as a result. Let's see what the error here is. It's a list that we are sending back to him. There's a type mismatch. Let's see what the type mismatch is coming from, 19. So in this case, he's complaining. It's no longer an iterator, right?
Because we reduced it to a single value. So this is going to be a printf of the total value that we got eventually. So we could just say print that value. We could even say print. In this case, we could say something like print line. So print fn. And what are we going to print here?
So we could say this is going to be total is, and then we could print the total value that we want to print out. So that is going to be the last result to pass to him. He's print fn, sorry. So that's the total value we want to print at the very end, and the same result as the previous time, as you can see in this particular case. So the point really is you don't have to go through the steps
and store these temporary values, but you certainly can. So my recommendation to you is start with the code in the top, right? And if you have to apply these successive transformations, build these intermediate results, make that code work. I'm a huge fan of this mantra,
make it work, make it better. So first make it work. Write those series of transformations. Once you know what transformations you have to apply, then see if you can just compose them as a sequence of operations, and then put together. And if you can't figure that out, we can talk offline right after, or just drop me an email and we can definitely go into it.
But what you're saying seems to be simply fitting into one of these combinations, right? So just up, right, again, spend some time thinking about it, and see how you can apply it. If you can't, ping me and we can definitely take a look at it. But I still feel that what you're trying to do is going to fit into one of these paradigms.
Excellent question. I was waiting for you to ask that question. Thank you for asking that. So certainly, you're looking at this and saying, okay, this is all cool, but darn it, how in the world is memory going to shine in this particular case? Absolutely, that's a big concern.
There are two answers to it. One is, yes, it's going to have a bigger demand on memory, but there are ways to avoid that. One way to avoid that is you cleverly use data structures that help you with it. One is you try to perform operations on the head of list, so you don't have to mutate a list to add elements to the list itself. And so you can keep the list immutable,
but you can keep adding elements to the head by concatenating new references to it. So that is one way to solve it. The other way to solve it is there are some data structures that have been introduced recently. One of them is called TRIES, T-R-I-E-S. And TRIES is an immutable collection, which is a very high branching factor tree structure.
And you can support, for example, a tree structure with 32 or more children. And Phil Bagwell introduced TRIES, and Richard Kihoo introduced Closure, uses TRIES with immutable collections within Closure, supported in Scala also today. So when you're programming in functional languages,
you would end up using more of these immutable data structures that will ease the demand on memory usage, because they will selectively make copies of the data structure, rather than making copies of the entire collection. So your point is well taken. You don't want to use traditional data structures to program functional style of code. You want to use more functional data structures
to do that, and then you get a better performance in memory. So take a look at TRIES and related data structures, and then you can begin to use some of those. So let's see how we could put this to a slightly different use. I'm going to go to Yahoo and ask for some financial data. And the way I'm going to do that is to write a little code here, you can see, not too hard.
What I'm doing here is to call a getPrice method. It takes a ticker name as a parameter, create a web client, download the data from the web, and get the data and parse through it, and simply get the price of that. But this is going to be a bit slow to run. So I'm going to, for a few minutes,
mock it away, and then simply return a stale value for us. I'll simply say if the ticker is equal to apple, then return $600, otherwise return $22. So that's my mock the way. We'll eventually remove that once we get the code to work.
Otherwise, I'm going to waste my time waiting for the web to respond with the connection here. I don't even know how fast the connection is. I've got some tickers on hand. Let's see how we can apply this. So here's my task on hand. Get the top stock less than $500.
So that's what I want to do. I want to get the top stock less than $500. Let's build this in steps. So tickers, and I want to simply print out the tickers value that I get from this. So how would I do that? So let's go ahead and simply say all that I want to do is to print out, so print function here, an object I want to print.
And what's the object I want to print? Just the tickers. So very trivial so far. It's going to just print the values I've been given in the stickers themselves. That's all I'm going to do. So let's try this. Let me get this back to you. So let's remove this for a second. Let's get this code to work first. Oh, I know why. So there we go.
So we are asking the ticker symbols to be printed. Now what's the problem in this code? I want him to get me the tickers. If the ticker, not tickers, tickers. There we go. All right. Cool. So the next step, of course, is I want the tickers and the prices, isn't it? So let's ask that apply process.
So I can say list.map a function with a ticker symbol. What's he going to do? Oh, gosh. I have a ticker on hand, but I need a collection of tickers and prices. What kind of data structure could I use for that? It's a collection, all right, but collection of what?
One of my favorite data structures is a tuple. Some people call it tuple, but a tuple. So what's a tuple? Tuple is just a collection of data, very lightweight, immutable. So here's a tuple. The ticker symbol itself. And what is the next thing I want to put here? The get price for the ticker. So that is basically a simple call to it.
Notice that Apple is 600 in the mock.value. Everything else is 22.22. So we got the prices. Now I have a collection. Notice I transformation. I transform from a collection of tickers to a collection of tickers and prices. Make sense? All right. So then what am I going to do? Well, I want to filter now.
And what do I want to filter? Filter on a function. This takes a ticker price as a value, a tuple, right? And what is he going to do? Well, I want to filter only prices less than 500, meaning I'm going to drop Apple from this, right? So how would this work? So second value from the ticker price is less than 500.
So I'm telling him, go to the second price. And if the second entry in the tuple is the price, is less than 500, grab it, otherwise reject it. Notice Apple got dropped. Everything else is in here. What's the next thing I want to do? OK, I have all the stocks which are less than 500.
But I want to pick the one that is the highest price. What kind of operation could I perform for that? To take from all of these and get one out of it? A reduce, absolutely. So a list.reduce, and I'm going to take a function.
This takes a price one and a price two. And what is this going to do? If the second of TP1 is greater than the second of TP2, then give me TP1. Else, give me the total price, the ticker price of two.
So that is going to give me one of those. But of course, that's all marked up data. Let's go remove this from here and run it with real code. And it's going to the web right now, asking for the data. And this takes anywhere from 20 seconds to three days to run.
And so we can kind of wait for it to run. While it's waiting, let's talk about what we have done so far. So notice this example. We have a collection of ticker symbols. We are going out to Yahoo, grabbing all the price values. Then we are applying the filtering on it. Then we are applying the reduction on it. Then we are saying, here's the value that you're expecting.
And the value right there is QCOM as of yesterday, $58 in price. So that is an example of how we could use more of a functional style of coding to transform the data. So notice it's a state transformational logic, rather than a state mutational logic that you're applying in this particular example.
And you're able to achieve the result. So I hope that gives you an idea about what this can do, in terms of the style of programming. It is a shift in paradigm. It is a way for us to redesign and rethink how we develop software. But it's definitely a very exciting way to do stuff. This really has a bearing on our ability
to develop code with more efficiency. In terms of correctness and also with multi-core processors, it really becomes useful. I haven't quite gotten into the multi-core efficiencies, but that's all I can cover for what we have on hand right now. So I hope that was really useful for you. Thank you very much for your time.