 Hello and warm welcome to everyone joining this session today. Now we have Nikhil with us to talk about implementing event-driven microservices architecture in functional language. Thanks a lot Nikhil for making the time for us and without any further delay over to you Nikhil. Alright, thanks a lot for the lovely introduction. Let me share my screen please. Hi everyone. So my talk is about implementing event-driven microservices in a functional language and the way I've structured this talk is that my code samples etc is kind of in F sharp but generally the talk is very much general functional language. So if you're not from an F sharp dot net background still like probably 80 90% off of the material still will be relevant to you because I understand that not every people have different preferences for languages right so I'm coming from Scala is coming from Haskell so I've tried to make it as general as possible. And predominantly I have two objectives for this talk. My objective is that I want to explain why functional programming in general is a great paradigm for implementing event-driven microservices and I'll explain a little bit about microservices and little bit about what I mean by event-driven microservices. And secondly, now that we understand why functional programming is a great paradigm. So let me actually go and how we implement certain constructs using common programming language constructs that practically all functional programming languages have. So these are two objectives but before I start there I'll start with a little bit way back on monolithic right this is the old school approach that we had in the good old days. So all of this connected to database multiple clients are connecting to it. Everything is very easy easy to test easy to deploy etc but it has its own challenges so it's easy to develop and test but it doesn't scale. And the reason why it doesn't scale is that when you have a large code base, right, the development gets slower. It takes more time to test, it takes more time to deploy and there's a lot of team interdependencies, right. That you have only one services and there are a number of teams that are working on this one service. So what team one does will affect team two, what team two does will affect team three and if team one has to deploy but team two is not ready it has to wait. So in a large organization these monolithic models don't really work and that's the reason why we come back to microservices. Basic stuff microservices are small autonomous services right so instead of having a system consist of one big service you divide it into small, smaller set of services that communicate with each other using lightweight mechanism right typically rest API, etc, etc. So that's what a microservices is. Microservices is a big topic I can't cover anything more because of lack of time but I have some excellent resources on microservices in fact there are conferences dedicated specifically to microservices but that's the gist of it. So there are advantages to microservices independent realizability right I each team owns one particular service and they can release that service they have full control about it also it provides the better scaling properties. For example, let's say a certain part of your system is overloaded you can scale up that services but you don't really have to scale everything up you can only selectively scale up the parts that are heavily used as opposed to monolithic because there is one service when you scale everything right or you scale down everything here you can selectively scale. So a lot better efficient utilization of your resources. There's a technology heterogeneity right they are different services somebody can use salah somebody can use Java somebody can use, I don't know C++ other people can use.net. You don't really have to set with one set of technologies because microservices communicate with each other using lightweight protocol. There's a lot of resilience building. If if one particular service fails that service fails but the rest of the services are still working right because failures happen at scale. Whereas in a monolithic if your service scales that's it you're done. If there is one exception in one part of the code, it will bring down the entire system whereas in microservices you have one small exception in one service. And at best it actually brings down that particular service and typically organizations have like hundreds thousands of services. Also ease of migration right if you want to migrate and this is a very common and probably I would say single best single most useful purpose for microservice that technology stack gets really done so let's say you want to migrate migrate the services you can just migrate them one by one as opposed to migrating all of them together. So that gives you less, less risk of migration there's a, there's an interesting story about it that Facebook started programming its services in PHP. And then they realized that PHP doesn't scale, but they didn't had a microservice architecture they had a monolithic. So if you have to now migrate to something more than PHP you just can't because you basically literally rewriting the entire PHP which is not feasible. The other solution was a little different days kind of said okay fine we can't really migrate off PHP, but you know, let's just make PHP faster and they came up with their own language called hack and hip hop virtual machine etc etc. But the point I'm making is had they used microservice architecture this problem wouldn't have happened in the first place. This is actually a very real problem. So what is a functional programming from a functional programming point of view, what is a microservice, or what is a service in general actual. When you think about a service, mathematically, a service is a function takes an input gives you an output. Right. And, and I'll cover this in details but let's say if you're using pure functional programming languages most of these functions don't have side effects. So you don't really have a state. And typically when you implement services the general rule of thumb is that most of the services that should be, it's always a good idea to implement them as pure services for several reasons they're easy to develop easy to test etc etc. But, but there will be services that would not basically be pure they will have some attached database because you do have a persistence layer. So in these services we don't really have side effects, except logging logging we don't really consider it as a side effect so even if you have print of statements it's okay because logging does not alter your state, right services don't have states so that's why logging as a side effect is okay but I in general is not. So that's the functional view of a microservice. There are services that are somewhat non functional, they will have attached databases right you will have services with database. So, you can think of database as a, as a state. Okay. So there what you have is, you have an input and you have an output so a service would manipulate that state so it's a function that takes the input and takes the state. Okay. And then gives you an output and alters a new state as out, right so that's that's the non impure service which is usually the minority and all the side effects at IO etc, writing to database with the exception of logging will fall in this category. So that's the kind of functional view. So what we try to do is when we have these bunch of services typically organizations have hundreds, sometimes thousands of services I know what has about 7000 microservices so quite a lot, as you imagine. And this was like few years ago I don't know what they have it now. Although I think they themselves somewhere I read themselves really like that they have way to services that they were talking about merging some of those services. So the number might have come down but again my information is a little bit old here. So that's a functional view of microservice and it maps very well to functional programming because at the end functional programming is all about functions and you can think of functions as microservice and we'll talk about this mapping. In a short while but the question is, what's wrong with object oriented programming why, why should we not use object oriented from what makes functional programming so good. So you have object oriented more programming models right it models an application as an object with state. So you have classes you have private functions you have public functions and then you have private members and you just modify that is essentially what you're doing is modifying states. But when you think about services. Most of the services don't have states so it's kind of contradictory. Why would you have object oriented programming. Why, I mean, I think most of the time it's just because object oriented programming becomes kind of a de facto it's prevalent in the industry so everybody thinks this is the way to do it. Right, it's just prevalent is really people don't think about it it's just the de facto way of doing it. I would argue that this is not the best we're doing it functional programming is far suited for implementing such services. Although most of the modern object oriented programming these days implement a lot of functional programming so the line between what is. You know if you look at C sharp Java they have like lambda functions they have a lot of stuff now C sharp particularly is very functional in nature so there's always a line between what is object oriented and what is functional and that's kind of nevertheless. That's the problem with object oriented programming object oriented programming comes from imperative programming and imperative programming was basically invented to interact with Van Newman hardware. Right. But when you think about it microservices most of the services are hosted on a cloud or some kind of platform like Kubernetes etc they don't actually interact with hardware they almost always run on some kind of intermediate virtual machine or something like that. That's why it's kind of contradictory. It doesn't make sense to use object oriented program or imperative stroke programming to use the services. And one of the key key aspects that people would justify why they would use object oriented programming like Java C sharp is that they are mainstream languages they have a very good ecosystem. The argument itself is not wrong, it is correct I mean the number of libraries that Java or C sharp particularly Java would have is huge and enormous. So that part. Yes. However, most of the languages, not most but some of these languages like F sharp Scala, they can interpret with C sharp or Java seamlessly. Even if you use functional programming to implement these services you're not being siloed in you can still use the excellent ecosystem of languages that you have in in the object oriented world. So the question is how do we model them I'll just minimize this. How do I model them. I kind of talked about service as a function so when you think about service that services in the world you're talking about basically functions in the functional programming language is pretty much a one on one mapping there. And then, and we'll talk about events what is event modeling a little later but when you think about events think of them as triggers information that goes in the service or the input for effects right these events. These events can be modeled with alzabric data types so every language has alzabric data types F sharp has disconnected unions Scala has type classes. Sorry, not type classes case classes. Depending on the language you use every language will have its own but basically this is one of the hallmark of functional programming that you do have alzabric data types that can be used to model these events very effectively. These events generally tend to be immutable because there's an event that happened something happened you can't go back in time and change it. Right. And when you think about functional programming, it's very much based on immutability for most parts. Right. I mean Haskell languages like Haskell have a pure programming. And we talked about mostly stateless services most of the services don't have state to manipulate with which also maps very well with functional programming that most of the code with your skilled functional programmer would write is actually pure code right there's no side effects. The point I'm trying to make is that functional programming basically captures the behavior of service architecture very naturally so you have the physical model of how services are and you have the model of how programming languages and there is a near one on one mapping where you can translate everything from the service model to the functional programming model very easily. And again examples are in F sharp but you can rewrite the examples and pretty much every state you have an input pipe I imagine you have some kind of merchant service item name I can do you have like an output I you're checking an inventory you're talking about an inventory service so I have some item and I have some name of that item or I have some reference number SKU screw basically, and I want to check if the item is an inventory if it is how many quantities were there if item is not an inventory when can I expect it so there's a date and time, or the item is not sold so I can model these input and output very nicely using discriminated unions of a shop and for scholar folks they can use case classes. And then, essentially, a catalog search function simply becomes a function with input and output in fact, when you look at the practical implementation of how people implement the services and functional programming languages what they basically do is they would write all the inputs and all the output for different services. And their, their code then simply becomes a transformation from one input to another output it's even an object oriented programming you do something like that, knowingly or unknowingly you would have all the classes and you would do this object modeling right you have all the classes and you write the skeleton you write the private and the public members of function and then you later on implement them. So in functional programming conceptually you kind of do the same thing. And you can model asynchronous workflow also so like shipping order right I have the stock service so I get a request, I acknowledge that request and then I send an async request to shipping so it's more scalable. Here so you can even model async workflow very easily. And one of the hallmarks of from a microservice architecture is that you have this loose coupling. And typically each service will have its own database that's actually a pattern that you have to follow because if you're doing microservices you don't really want services to share database and the reason why the services don't share databases because then the schema gets tied to multiple services and the whole idea of microservices to have loose coupling. Why do you have loose couplings. You have loose couplings because then it reduces team interdependence and team interdependence means faster innovation that's that's the reason why you went to microservice in the first place. But the problem with loose coupling when you have one database per service is that you have distributed data and we'll talk about distributed data in a while also. Let's talk about contracts now right now services and tracking with each other we saw these contracts right think of these. Sorry, these as contracts, like input and output. How do you model these contracts turns out. And we talked about it that reading and writing F sharp provides something wonderful type providers. And where contracts are defined as snippets on x symbol json and you can just quickly read them and write them so you basically have live examples and then you can. Typically when you basically code you will have these in some kind of common repository or common shared location where all the services can actually reference but even if you're not using F sharp. You have other options like your Google proto buff in Apache thrift right you define your contracts and then it can generate all the classes that serialize and DC realize because when the services are interacting they often might want to send. Sometimes they just send Rogers and sometimes they want to send binary data so you have a way of serializing and these serializing these this data that's our contract management becomes very easy in functional programming if you use type providers but even if you use type providers you still have an option. And as I said proto buff would support Java that you can readily consume and scholar. Same is true for Apache thrift. And I'll digress a little bit and I'll come back to the problem of distributed data, but I want to at this point introduce domain driven design and domain driven design again is one of the topics which is pretty big. You can see scratching the service of it but essentially what it is is an approach of software development where you connect the implementation to the evolving model and you have various entities and there is excellent references both in functional and non functional world of how you would implement domain driven design I'm not going to go into details of a domain driven design by itself will just scratch the surface here, but one of the elements of domain driven design is aggregates. The aggregate is is it's a cluster of domain objects that can be treated as a single unit, usually you have a reference root and then a reference, all the references refer to this root aggregate root an example is your placing an order in Amazon you have an order, so you have an order ID and that order consists of okay I'm going to buy some shampoo toothpaste toothbrush whatever whatever the items are so you have a list of items and you have a quantity. Right, but you would reference that as an order that order consists of different objects but for you order is one entity that you refer as an order ID, right. And then you can think about your software as nothing but a collection of aggregates like the entire domain model of your software is nothing but a collection of aggregates now. Why is aggregate and important what's the relevance of DVD. We talked about implementing a system as set of services. What we haven't really talked about is how do you partition these services right how do how do I take this system and how do I divide into services I, I believe I want to go to micro service architecture. Great. But my question is that how, how do I divide that functionality into different services. And this is where domain driven design actually helps or more specifically aggregates because what happens is aggregates provide the boundaries for partition. So this is the way I can actually partition my functionality into different services now. So here I have an example of an order service I have a customer service I have a product service and the way I have partition date. Now mind you there is no unique way of partitioning right you can find it as much as you want, or you can course grenade and there are pros and cons on both side and that itself is a big topic but here for example, I have order service and product services one service and customer services second service, I could do that. Generally, you don't want to find gradient too much because you will end up having too many services but then you don't want to post gradient too much because if you have one big service then you're basically not taking advantages of micro service right the truth is somewhere and sometimes partitioning is more of an art than a science actually so there's no like because there's no unique way of doing it you have to rely on your intuition somewhat to do that. But moving on domain driven design usually has an architecture right so you have different layers like layered architecture you have user interface. And then you have application layer right which is where transactions would happen and then you have the domain layer your objects actually the domain objects like order would be one product would be customer these are all different domain objects and then you have the infrastructure layer, which is the layer where your persistence layer is where you have connection to database so this is where all the impure services would run. And DDD says that domain layer is where you should have the bulk of the code and DDD advocates that domain objects are basically immutable and they have these. They are basically data classes with attached member function so if you don't have attached member functions they're called anemic domain model which is an anti pattern in the micro service architecture and now here when we come back to function programming. And we kind of saw that as examples I'm actually now exclusively calling it out that you can model these domain objects in form of estimate f sharp discriminated unions or folks from Scala you could have Scala case classes. And what that becomes is that when you have all of these you basically have an executable specification that actually can be checked at runtime because your code. Actually, your design is basically an executable design right that I can actually compile because it's all F raw F sharp code or Scala code. And that is a big advantage in itself because you can then eliminate the model code gap now what is a model code gap. You will see it often that there is some wonderful software architect which would draw a nice little diagrams and they will have good documentation on how the software is. Implemented and that documentation is you know it's some word document one or whatever documentation system you have a wiki mostly, and then you have the source code, and then source code is implemented but it's not exactly matching because source code evolves evolves evolves and the document stays where it is so over a period of time your document would say one thing and the code would say something else. So that's the model code gap, but when you have your contracts in an executable specification, you know you compile them, you could check there's a compilation error. So there will not be like your documentation says something and reality something else, they'll always be aligned in in sync with each other so that's the advantage that you have. But now coming back, we, I flagged about this issue that we have a problem of distributed data, right what is that problem. Well, the problem that we have is that we have distributed data how do we keep the data consistent. Right. And also how do we queries data now why why consistency is a problem because usually you have multiple databases and what you can have is one database might imply something and other database might have something else for example. I, I have an inventory service and I order something let's say a product inventory service should keep account on how many products are there on the services. Great. And then I put in the customer but what happens is when I sell it I forgot because of a bug or whatever reason to actually reduce the count of the product that I'm checking out. If I, if I look at all, all the products that I've purchased all the products I have sold and as a practice difference, I should have what is in my inventory but because of this bug, the data is inconsistent. Now, when you have one database representing everything you will not have a problem because you will immediately catch this inconsistency problem when you have data scattered, you now have a problem. The second problem is how do you query scatter data, which is a problem and both of them are rather problematic situation so we'll look at the solution here. We can't use asset transactions because look at the simple simple query right in a monolithic you can use it but in a microservice you have a customer service so this database is private to customer and this is private to product service. In architecture do not give you access to database directly so every service has its own database, you can only interact with that data from the interface, so you really cannot actually just customer service cannot just go to the product service. Right. So if I want to run this query, I actually cannot run a SQL one I can't even do something like a two phase commit because it guarantees consistency which is great but it has its own problem coordinator is a point of failure. It's very chatty locks will decrease throughput in a fast moving service I can't have all of that. So two phase commits is usually not an option that I have so what do I do that. Well, my cap theorem says that I can't have all three of them consistency availability and partitioning right now in a high in a highly available system availability is something that I can't. I really cannot compromise because imagine a for services down for one minute, the amount of business that you're going to lose right availability translates to money so you can't sacrifice availability. Given that you're running a distributed system by default, you can't have partition problems right you need you need to have this partition network also network resiliency, but what can you sacrifice consistency to a little bit extent. And this is where we come back to eventual consistency now what is eventual consistency, eventual consistency says that my system will not be immediately consistent but if I give a little bit of time, it will eventually achieve consistency when I say eventually, eventually often means few milliseconds, basically that the human human I would not really be noticed so, even though your system is not immediately consistent, it actually will not make a difference because your consistency eventually, within a few milliseconds your system will become consistent. So for user it would not make a difference. And this is where event driven microservice architecture is so now I use these terms events and I, I kind of briefly described it so now I'm just going to pull all of them together what is event driven microservice architecture. This event driven market microservice architecture is basically an architecture where you have events events occur when there's a change in the system, right. And when there's a change in the system events happen and all the listeners gets notified and relevant people would take actions. And generally it's a very loosely coupled highly distributed system in the sense that when when a sender sends an event it actually does not know who are the people was going to listen. Right, it just sends an event it doesn't care it's an asynchronous way of communication basically asynchronous flow. And it might appear fancy event driven architecture and all those things when you think about it in your everyday life a lot of these distributed systems concepts. You've been actually using since always. For example, my favorite metaphor is that every time you go to an airport you're using an event driven architecture, why. Think of every human and the airport as a service and think of the person who's broadcasting as another service that is sending an event so it says flight ABC is about to depart in 510 minutes if you are on this flight please immediately go to gate three. Okay. Here's the synchronous information, the sender just emits event, some event is happening I'm just broadcasting that event. It does not know who are the listeners, or will they take any action who's whoever have listened or ignored that on on the ground you have thousands of these passengers and some of them who are on that flight would immediately listen hopefully and rush towards the gate. So they get this event, they take an action. People who are not in this flight they just keep ignoring I don't care what's happened so that's that's a very, you know, practical example of what an event driven architecture is you're using kind of the same thing and in distributed systems we have message interfaces like Kafka, basically does all that, sorry. There's all that stuff for you right you have these message bus where you're putting these messages and send these events so that's how it happens in the distributed system world and will look little bit briefly into communication patterns. But when you have events how do you build the state. So there's a, there's a pattern called event sourcing that builds the state of a system as a sequence of events or basically what it does is it actually stores the events and every time it has to build the state it actually combines these events and build the state. So, advantage of this is that you can roll back in the history and you can see how my state changed over a period of time. So, it gives you that auditing, and it enables creating future workflows why does it create energy flow first well, you have an event you have thought of some use cases, you know, you, you just implement them great. But later on you think about oh I this there's another use case for it and I want to have new service imagine you're using Kafka you can just plug. This service in the Kafka bus, and you know you have the topic and you messages are broadcasting to the topic anybody interested in the topic will just read that message. The center does not have to know who the listeners are that's the hallmark of event driven architecture. So I don't need to plan ahead, who are the people I need to cater to if an event I think is important I'll just broadcast it. But if it's people who think they need to know this will listen those don't ignore in future there are more services that might need this event. They would listen so that that's the reason why it enables creating future workflows and like everything else. You realize that you've been using event event sourcing in some form or another in your everyday life for example bank ledger is an event. In your bank account, you have zero balance you, you put some money you withdraw some money you put some money you withdraw some there's an event happening. What is a state, a state is basically the total amount that you have in your bank account right total balance and what is it, it's some total of all the events that is happening. That's event sourcing right every time I deposit, let's say plus $5 it's plus five every time I withdraw it's minus three. I add all of these numbers together, and I get the total balance. So all of these are events. I'm doing event sourcing and I'm building the state by just replaying these events, and I can go back in history and see how much bad balance was at some particular time. Another example is get version control right. Your state is your source code. Every time you make a commit every time there's a delta that's an event. What is your final source code. Nothing but a sum of all the data. If I sum every commit that I have made in my history. That's what my source code at any given point of time, and I can roll back. And another thing with event sources I can actually take these events and break them combine them recombine them like let's say in a bank, I detect there is a fraud that happened I want to take that transaction out. I have all of these transactions like as events I can just roll back in history remove that one event and then play back. So there's an advantage that even sourcing house. How do you implement event sourcing in functional language and this is another example of where realize that there's a very good mapping between distributed systems and functional programming. And that is for function. Another to model every event. Event sourcing is nothing but a list for it's a state aggregator function that you have you take an initial state, and you just fold it with caveats that sometimes what you want is sometimes you want to do some intermediate caching for performance. For example, even in bank account if you have a bank account for like 30 years you some all the transactions you have done it takes a lot of time sometimes to build so the bank would basically every end of the day every end of the week. I'll have like a closing weekly balance and then you know, if it's has to build that state it may not go all the way back 30 years it'll just go back to the last week, because it cash that state so basically implementing event sources is as simply simple as implementing a full function in functional programming languages, but you sometimes want to have snapshot performance. There are benefits you have a lot of it in you have temporal colleagues applications can have same events but create multiple views already talked about it but obviously there's no strict consistency. It adds complexity and longer boot times. So we're talking about sagas now what is a saga sometimes you have long running compensating actions for the failure so you have a transaction. Right. You move to a new transaction because remember in a services you have distributed functionality what if something fails, how do you handle that right you have distributed data. So let's say you were to move to the next transaction, but this failed you create a rollback. So, I am, I'm actually talking about sending money to let's say somebody else so there's $100 that gets detected from my account and will go to $100 to let's say, you know, somebody in the race account. But it can, it can be the case that I don't even have $100 in my account in which case the transaction fails right. The example is you're transferring money and let's say the account closes so you can't really transfer that money to a closed account so it failed and it came back there's a rollback transaction. So that's how you implement sagas. There are two communication patterns will cover very briefly because I'm actually running a little bit low on time. Let's keep chat. Okay, so we have communication patterns request response right this is like most common and most simple easier implementation better control, but increases the coupling and difficult to scale. Right because every time we talked about even driven this isn't exactly I mean it is even driven but you don't really have a message but it's not asynchronous. And then you have the standard Kafka message broker which has its own advantage but you're talking about a broker. And typically you break your services in three tiers of the customer facing ones almost always will be request response why they can't be asynchronous, because the customer wants a response I place an order I need an acknowledgement. I need to know I can't just wait and sit Oh my God I don't know what's happening to my order. So that's how the implementation pattern is that this is usually request response, and these would be even driven. So what I briefly talked about querying the states right we know how to build the state we talked about full function so typically, if you have to query a distributed states what you have is you, you build those using the full functions and then you have this one big state that you can query and sometimes in a larger systems you don't really don't have one state to have multiple such full functions, because not everybody is is interested in all the data right some people might have some aspects that might be interested. So you could have services with multiple fold function in fact there's a there's a pattern called CQRS command query responsibilities segregation in distributed systems that kind of deals with that. In the interest of time I can't unfortunately cover that although I'll add it to my slides when I submit it so for those who are interested they can go through it. Now we talk about testing microservices so we have talked about the development and we we now understand why functional programming is really good for development what are the advantages but we really haven't talked about testing so let's actually get to that subject. So we mentioned that most of the services that we have a pure functions and testing a pure function is actually pretty damn easy. And the reason why it's actually easy is because you know pure services are pure they are very predictable they can be tested exhaustively. So the set of inputs I know there are nothing. No side effects I can just you know, test it exhaustively. So that's the reason why a majority of these services generally tend to be pure services the ones that are impure the one that are connected to databases. This is where testing gets very tricky for example if you're testing your credit card payment service right every time you test you're actually making like a transaction on credit card, although I think you can still fake it. Unpredictable external state. It kind of gets a little bit tricky to test it now in the functional programming word particularly f sharp you actually have wonderful tools like I think there's a property based testing library for f sharp I think it's fs check property based testing in f sharp. If you Google you will get that library link I think it's called f stack that can be used Haskell world has also similar libraries, cubic is commercial libraries where you can beautifully describe your system and then generate exhaustively in the millions of test cases there's an excellent talk it's a little bit old but still very relevant by john huge I think he presented it in the functional conference but I think it was few years ago. But having having your services implemented as pure functions in a functional programming language point is makes it very easy to test. You have to do a little bit of trickiness in the sense that you have a message broker you have a test driver and a test interpreter because you don't really have a request response pattern. So you inject a test message and then you, you know, read the service bus. Now, what about static analysis and this is another beautiful way reason why you should use function programming is because pure functions in functional programming are very easy to analyze and reason about so static analysis generally tend to be very, very effective in. Yes, Scott heaven actually talks about this also Scott heaven and I actually work together at jet.com. He was, yeah, so I know him pretty well. So static analysis is a very effective way to detect issues in the code. An example is you can test when I was a jet.com which was using F sharp for the services. Actually, I implemented this that they had we had a set of empty patterns and then we could pass the F sharp port into a ST, and then test these patterns and in fact F sharp particularly has a parser but even if you're using other languages antler is a wonderful parser and grammars are available. For a lot of sorry. A lot of languages now running low on time so let's briefly talk about some of the advantages we have scalability right. It's infinitely scalable because you don't you have immutability you don't really have to worry about lock race conditions all those things. There are some major benefits that you could just scale them it allows you to literally scale them from 1000s to millions. Haskell has green threads I mean the scale of parallelism is like one of the start great things about Haskell but even otherwise using pure functional functional programming scalability is a big advantage. You also have productivity like F sharp code is much more concise that's actually to across the functional programming domain that your code is actually very concise so with few lines of code you have a lot of functionality and conciseness and clarity means lower maintenance simple code means reduced and we all know the benefits of having less code code is a liability not an asset FII everybody understands that. And then you have the code correctness right functional programming. Basically, the code is a, you know, you have static strict typing, you have immutability that makes the elimination of states eliminates a large class of birth strict typing will make it very easy. And then you can have exhausting pattern matching at compile time right if if you're missing a use case basically the compiler will catch it at the compile time. That's a big advantage that you have with functional programming code correctness, and then type system obviously makes it illegal states I'm representable right. A very famous problems is like null pointer, we all know how horrible null pointers are but in F sharp you have these option type scale also has or you can even create your own discriminated unions. I think one of my favorite construct actually is that you know response okay response or error something. Right. So either, either there's a response or there's an error and I have some information on the error. So I don't really have to worry about all the try catch headaches that you know exceptions might come exception might slip. I can just pattern match online so that gives me a lot of the silencing in my services and case study Twitter originally started as a Ruby in real but they moved to Scala. I have a link here. It's a rather old link but still very relevant or why Twitter uses Scala they had saw huge benefits they have Scala as one of the dominating languages not the only one they do have Java also. So I'm almost out of time functional programming is great we talked about it microservice enables faster instructor model events using ADT's pure functions are great for services and FPS several benefits we all talked about it this is my contact information. If you have any comments questions please feel to email me that's my webpage it has all my details. My Twitter handle with that. Thank you very much for attending. I will stop the video now. Thank you for your wonderful session, especially considering that it's a pretty late at your part of the world since we're very grateful that you could make time for us.