Devreal

Functional Domain Modeling: Beyond Buzzw...

Event: Scala by the Bay

SBTB 2015: Luke Smith, Functional Domain Modeling: Beyond Buzzword-Compliance

Recording: SBTB 2015: Luke Smith, Functional Domain Modeling: Beyond Buzzword-Compliance

thank you David like he said I work as in jeopardy right here in Oakland and what I've been working on is API design and Scala interacting with sungevity systems and building solar platform and the title of this talk is functional domain modeling beyond buzzword compliance and I chose that tagline because a prominent member of the Scala community who shall remain nameless once once asked me so it's functional just the word we put in front of all the book titles we've sold already so we can sell a new version I think know the answer is no that actually there's a deep connection between functionalism and domain modeling and it's something I was pleased to discover in the process of actually working on a practical project for sungevity so okay what are we talking about functional domain modeling is making functional code correspond to real meaning in a language that programmers share with other people and what I mean by real meaning before you ask is something something that obtains in the minds of people with domain knowledge and one legitimate question you might have about this is why why bother it is it is more difficult than not doing it right and the answer is really about complexity and accuracy at sungevity we needed to tell a simple but accurate and true story to each customer about their interaction with a very complicated problem and my particular situation then developing an API was taking a stateful and not type checked situation and turning it into a type checked API based on immutable build up hmm I'm bringing down the house already so customers don't need or want to know about the complexity of their situation various jurisdictions taxes utilities we operate in multiple countries we use multiple funding partners etc we need to do all that stuff and account for all those important differences rigorously but without having to tell us a story that's too complicated on its surface and to explain our business I swear this isn't just an advertisement for sungevity but is its explaining the project this is the simple value proposition we provide it's called the story of spun or solar for universal need sungevity looks at your home it designs a system estimates how much that system is going to cost and how much electricity it'll produce and then shows you your savings over 20 years and then we put it on your roof and provide you with access to your installations performance and design information this is our core value proposition no matter who we're working with and telling this story simply and rigorously and reliably for each customer at scale means accounting for a lot of complexity that nobody wants to think about in the sales process through domain modeling so that's why we chose to do it domain modeling and software is the practice of making code correspond to a ubiquitous language that's shared between domain experts and programmers you may be familiar with this from the Evans book and ideas about members of that ubiquitous language come from both the domain experts a subset of their knowledge and also from the implementation process and it's been well explored and fateful object oriented situations but what I'm talking about today is how it's compatible with functional approaches I don't know if anyone saw Chris Richardson's talked yesterday about event sourcing yes okay few people and also Michael slin talked a little bit about using caching to build up mu doable models in play and both of those are very interesting directions and I'll talk a little bit more about them at the end so how is it that they're compatible well for one thing as a historical note functional domain modeling may actually be the original kind of domain modeling the word domain comes from symantec domain and in linguistics a semantic domain is a set of concepts that are grouped by having something in common in some kind of natural category like types of snow chess moves musical notes etc but in computer science the idea is associated with creating a mathematical object used for rigorously assigning meaning to programs and denotational semantics which is a semantics of programs that's compositional assigning means of programs by assigning meaning to their parts someone of a man named Dana Scott was working on denotational semantics expressed in lambda calculus when he formalized one influential concept of domain and computer science which is now called the Scott domain and this was all the way back in the 1970s and at the time on typed lambda calculus didn't have a math model mathematical model relating it to function so he came up with one and Scott domains are the result or one hour one formalization and they provide a general semantics model for recursive programs that accounts for you know recursive functions functions that take functions as arguments and they model it in the ordered set as a series of successive approximations building toward a result and but for our purposes I'm not going to get it too deeply into the mathematical side which I'm still learning about as well it's enough to think of these sets the domains at sets and then products built up from sets approximating an end state and so the reason I think I can back up this idea is that functional languages like Scala or list to deliberate we were inspired organizer associated with approaches like lambda calculus which is also being used for denotational semantics so my assertion is that functional domain modeling is actually the og domain modeling that there's every reason to believe that domain modeling is useful because of this sort of compositional approach and it allows you to communicate about the real world and that also help help help you meaningfully explain your code base in relation to your specific problem and not only is it compatible with functionalism it actually has functional origins it's not a coincidence that as we're trying to make code more comprehensible we take functional approaches so okay that out of the way I'm going to be talking about a toy solar domain that mirrors the API that I worked on and it's the domain of utility consumption sites and why utility consumption sites instead of just houses the reason is the thing on the left is the utility consumption site and the thing on the right is not and at sungevity we're only just dipping our toe into battery solutions so we were concerned with utility consumption sites people who have grid so going back to our core value proposition this is the domain that we need to interact with customers in i'm just going to camelcase some nouns and use these as the primitives of building up our domain and some of the products so sungevity looks at your utility consumption site creates a system design calculates a system price and your production estimate and gives you a quote that shows your savings then we provide you access to installation showing a system design and performance information about your utility consumption site which is now also a solar production site so we can just imagine these as the domain core models in our system and what these are are a set of overlapping categories and I hope you can you can actually see that a little bit everything is utility consumption site some of those have system designs some of those have system prices some of those have production estimates and they're priced and estimated and when they have the savings calculation completed their quotes and so the API can mirror this structure and when we interact with certain endpoints we are taking a journey through this buildup of values so the first route on the bottom there is from point A to point B adding a system designed to a utility consumption site and then calculating the quote result which can happen in one of two orders it could we have an opportunity for parallelism and then another one is a post up a solid production site to a quote to actually turn it into an installation I've emitted the part where people pay us money because it's complicated so this is this is a simple version of what's really going on and so if we consider these sorts of primitives and and buildups is a grammar we can see that there's going to be some intermediate results that there that we're interested in representing and we could almost parse our story of fun with something like this like we really are trying to build a language of sorts that makes sense to people in the who are domain users and then we can see that quote and installation are separate they they don't contain everything that the other contains but if we wanted to imagine what is the what is the element that contains all the information in this system it would be this unit the story of quote becoming an installation united solar for universal need unit sorry I love acronyms but not everyone does okay so if we were to label all of the intersection serial the buildups we would see you know imagining these as just products some of the intermediate representation so we might need to be interested in as we're approaching the quote or as we're constructing installations and then the the unit at the top would be ultimately the product of of everything so this is a pretty simple algebraic situation so not a lot of complicated understanding is necessary so we can then translate this sort of grammatical approach into a state machine that clearly reflects the workflow we start with a utility consumption site then we design something and we arrive at the second state then in either order we can price an estimate and arrive at the price and estimated state through composition then we calculate savings and then we have a quote and then eventually we install the system and we drop some information moving into that state and so these are the routes i'll be talking about post getting utility consumption site just accessing them posting a system design and getting back a quote posting a solar production site and generating and installation and so we can imagine these as functions between domain and codomain that are defined in terms of either basic semantic domains or their products so again here is a state machine representing what happens when you would post a system design and get back in installation or sorry to get back at a quote and if you can't read my handwriting out I'm sorry and here's what would happen when we post a installation and post a solar production site and get back an installation we forget some things we add in the solar production site and get back the installation something in the installation domain so like so far we've been talking entirely about the conceptual structure and that's intentional on my part that I want to emphasize it I'm starting from an idea of what is the the conceptual structure that we want to model but now of course we have to actually put some Scala code on the screen so here we are so when we want to realize these models in code there's more than one way we can do it I did it in this example in my real API project through a system of trade build up but I want to emphasize that that's not the only way you could represent the product of these domains another way to do it would be through more ADT style case classes and and type and that's something I want to explore as well but here we can see what we've got is a case class utility consumption site it has an ID address usage and the key information is their price so from here we can make the basis of our calculation for how much the customer is spending and here we have a system design case class which is really simple it just has a number of panels and a number of kilowatts that that kilowatt hours that that panel is going to produce over its lifetime here's the system price again the real domain is a lot more complicated but we can see this is basically all we would need to calculate assistant price based on the system design here's a production estimate here's a savings trait and this would be like the net savings and the electricity savings is how much you would save immediately off of your bill and the net savings is taking into account the cost to the system over time and so a way of imagining their intersection is this price to end estimated utility consumption site trade right and this is one of these intermediate representations and so it sounds pretty complicated but really it's just this it's just this note here that exists right before savings can be applied and here's another intermediate result we might be interested in we might want to be able to look at utility consumption site sent without knowledge of or rather we might want to be able to design systems without knowledge of the utility consumption site and so the least upper bound of the justice system design the system price and the production estimate can give us a system that's very interesting even without might be a separate aggregate at some point right even without knowledge completely of the consumption site itself and once we get to a quote what we can see is the product expressed as a trait that has all of the information built up into it and this is can be this is the kind of data we can use to power the API here's an installation reflecting all the thing all the products that it is part of so those are how the models are structured and services that I created provide transitions between the trades so new traits to take work and then those trades can be composed on to the models to provide you to actually do the work of building up the data so here's a production estimation service it shows a method taking a system design trait and producing a future production estimate so we're mapping into a future of you were mapping into a future of the domain the trait that we want to compose into the model and crucially this only depends on satisfaction of the system design trade it doesn't depend on anything extraneous it's based entirely on its requirements are based entirely on things that actually requires in its output is only things that knows about similarly here's a pricing service sorry for the lack of syntax highlighting here but what you can see is there's two methods system design assistant price which just looks up the price per panel and calculate surprised and calculating a savings is also here and so these can be expressed and and given functional denotations or you know sort of loose denotations as to what they provide in terms of the domain so what's nice is that when we get to actually writing the model method or action for applying a system design and getting back a quote we can do it in one for comprehension like this so all we have to do is find our utility consumption site get the price get the estimate those two things can happen in any order then we at once we have our priced and estimated site composed we can add on savings and return the quote and so what's nice about this is that the structure of our for comprehension directly mirrors the kind of state machine that we constructed just by thinking about the domain concepts so here it is as our people's eyes glazing over I basically um what's nice is just that it's totally parallel and that we have a real explanation and in terms of functions over domains as to what we're doing so what does this actually look like the thing that we use to or the format we use to represent these entities in the API is called siren it's an extension of JSON that provides a set of classes describing a bunch of properties and it has some other interesting things about it too but for our purposes now what's interesting is that it can provide intersecting classes analogous to create mix-ins to describe what set of properties is present in a resource so here's a utility consumption site this is what you would post or this is what you would get back or see as a resource when there is no system design present and here is after adding a system design Lloyd what we would achieve something that describes itself as a quota system design a utility consumption cited assistant price a savings a production estimate and all the fields therein are contained and so just as some context for the real project I was working on here this allowed type checking both invalidation at the time of receiving the entity and instantiating types of what had previously been a totally mutable state process Ben values that we're all optional and got filled in over time as we acquired more information and so adding into a functional immutable build-up model allowed us to have a lot better checking of what was going on during the build-up of the result and we can write tests that say you know any entity that contains a certain siren class ought to have these properties and so on and we can base contracts on that so similarly here we are applying the solar production site to a quote in order to get an installation this is just a matter of a function from a solar production site to installation in this service or in the model rather so we're finding a quote and then composing the solar production site on to it and achieving the installation like so and that's all the de soller production site looks like just a performance ID and here's what we end up with as a entity for installation describing itself with classes and showing all of the fields that it's mixed together so had I would argue that you know we've done some of what we set out to do or I did what some of what I set out to you lose semantics and a denotational understanding of the code not not a perfect one but real meaningful anchor points between the operation of the API and semantic domains and now the program and its programmers can communicate more effectively about how representations are composed and we can contribute back some of those intermediate representations as meaningful categories and we also have built up some positive reason to believe that it's correct for the whole domain not just tests but there's a lot of other things we can talk about so persistence is one and managing events modeling events you know this is also just talking about a restful interaction what about other types of more reactive designs how is that serialization achieved and no it's not really mathematical proof of anything because we have not done any kind of complete denotation some of the next steps I want to try are some more ADT style classes and using type classes for service signatures instead of traits I think that might be an interesting approach event sourcing is also very interesting in that it models the entire persistence solution as a successive application of events so not only are would we be building up stuff over time like the entire model would be built out of successive application and be approximating some immutable final result so like even in the example of a bank account like you can view this excessive application of events as an approximation of the final mutable state of that account that complete story of why your balance is what it is I think it's very interesting and certainly I'm very interested in learning more about semantic domains and techniques associated with them and if you have an interest in this topic I would love to hear from you so here's some of the references and I don't know do we have time for a short demo maybe okay so just to prove to you that this actually works where am I so I'm just running my ass BTW project and let's see if i can it's sorry got stuck in fullscreen well well I'm while i'm fiddling around does anyone have any questions or comments feedback yes in the back so he asked do I specified domain models domain laws right and do I model functional States yes okay so let me let me just show some code the composition these basic traits represent models of the domain immutable ones and the composition functions which are pretty unsophisticated just represent what transitions that that element is capable of oh not on the screen yeah so so a very simple kind of application of an event to this quote is a transition as installation like so and that represents the possibility of doing this now there could be much more sophisticated ways of doing this we could imagine the aggregate as something that we can do some kind of magnetic application to or each event such as a pricing event or an installation event as being something we can apply to the model as we go forward like that even as we're recovering it from an event store but in a primitive sort of way here I've got my immutable model of a certain category and I've got the function that composes it onto it and I've got services providing functions that are futures of things that take work to arrive at some trait that I need to compose on to the model yeah good question thank you so let me see if I can show you oh I think maybe I'm coming up against the end of time here so trust me when I say yes if i if i post a system design i get back a quote just in those formats that i showed you any last questions no all right thank you