Build your own Excel 365 in an hour with F# - Tomas Petricek

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right time to get started thanks for staying until the very end this is my slide or sort of is it looks very much like a slide so what I want to do in this hour and I guess that's why they put me in the last slot because they're expecting higher I'll overrun by three hours is to write your own Excel 365 so what I want to do is to show you a couple of nice things in F sharp that will lead us to implement something like a very simple spreadsheet that runs in the web browser and I'll show you some nice I've sharp patterns and some nice F sharp tools so here I'm in Visual Studio code and I do have lots of to do here to start with and the first thing I need to do for my excel is to actually sort of represent some state of a spreadsheet so if you have a spreadsheet what what stage does it have so spreadsheet has some columns and I'll have my columns will be just ABC da da da so I'll remember what columns I have in my spreadsheet I'll have some rows these will be numbers and on so I'm using character and int as a position so I'll define type for this because it will be easier so my position is something like a 5 so that's a character and an int and then the other thing I will have in my state is what's the active cell so if you click somewhere in a spreadsheet that's the active cell the one you get to edit you might not have any so this will be optional so active cell is position option and then I'll have the content of my spreadsheet and this will be a map from positions to strings so yeah yeah I got typos here I'll fix this and so my cells will be for some positions in my spreadsheet I will have a string which is what you typed in there now when I start the spreadsheet so this is one of those two three snippets that I don't want to type because they're boring so initially I will start with rows from 1 to 15 and you could add more calls from a to K and you could add more nothing active and no no entry so this is the setup for my spreadsheet and what I want to do now is just actually start building it so here I'm using and I'll say more about this I'm using the Elm style functional reactive architecture and this comes with this function called app that starts the application you give it a def ID the initial state and then we need to give it these two functions and I'll tell you more about what they actually do so you can ignore this for now and in render will just say text hello and DC and then update that's the one I will explain later I'll just say given a state and an event return state so nothing this rendering bit this is you're using a little DSL to build HTML and if I save it I have a process running in the background that principles of stuff to the console and I have a browser running here where my application will show now I'm using really nice really nice setup in Fable where whenever I save things they will get automatically updated so that's what I that's what I want to do all right is this a spreadsheet yet no we can't sell it so we have to do more work so the first thing I need to do in the rendering is to actually render this the the the spreadsheet properly so I'm going to create a table now the first square brackets that's the CSS attributes or the sort of attributes on the tag the second is the contents so we will have to with first throw and in the first row we will generate one empty cell because that's the left upper corner and then for every column in my columns I will generate heading where the text inside is this column so I'm using two things here one is that I have this state argument and that represents my current state of a spreadsheet and so I can get stuff from it the other thing I'm using this yield keyword and absorb inside square brackets which is a really nice way to work with lists because you can just generate lists kind of like yield return in c-sharp and here it works quite nicely for generating HTML as well based on some data so we've got one row now we need even more rows so I'll iterate over all the rows and for every row we will generate a row what will be in the row the first thing will be the the text with the row number so this is my row and then I'll have and now I'm getting tired I'll do copy/paste for every column in the row we will need to render the cell now what do we need to pass through the cell I'll explain what rigorous in a short while we need to tell it where we are so the position is my column and my row and we'll also give it the state and I'll do more work here in render cell so we get position and state and right now just to test what what I've actually done we'll say text dot dot dot and render is done render cell will need more work and let's see what we've got looks like a spreadsheet yay now you can't edit it which is kind of kind of sad I also I think my spreadsheet is a bit missile I so what did I mess up I forgot the yield keyword it was actually giving me a red green squiggly to tell me I'm wrong but I was ignoring it so now we've got a nice grid what do we need to do now so now I want to show you my second slide - doo doo doo doo so my second slide is actually explaining this Elm style so this is a really sort of nice nice programming pattern where you compose user interfaces just by defining these things so you need to define type representing your state and that's the state of my spreadsheet so I've done that already then you need to define an event so this is basically what possible things can happen in your spreadsheet it can be click to select a cell and it can be entered to update the cell and then you define an initial state and a function that ignore this units event bit function that takes the state and produces HTML so you have a state you can render spreadsheet we've just wrote that part and you need to write an update function that given an state and an event produces a new state so if something happens you will calculate a new state and then it will automatically call render to re-render the page and the reason why this works and why it's not stupid is that the update of the page actually uses different algorithm to figure out what's the minimal changes that actually need to happen in the browser and that it only does those so it doesn't replace the whole page that's a really clever trick and we can now use it to add a bit of interactivity to my spreadsheet and I'm going to move my cheat sheet up here so that I don't get lost so the first thing I need to do is to define the event so I have my state what can be my event what can happen so I want two things I won't start at it so this is when you click on a cell and you want to edit that cell and this will carry a position so we know what we want to edit and when we click on it we change the state so that this is the selected cell and we want update value which happens whenever you do some typing in the in the selected cell so that we will have position and the new value and we want to update update our state to reflect this and now we need to go back to rendering and do something clever here so I'll have whenever I have cell I need to have two different cases one is when there is an editor then I'll create an input and the other when there is just the value and then I will evaluate the value and render it so I do have a basic template here because I'm too lazy to write this so render editor creates a TD element with an input with some stuff it's just an input element and render view just does this TD with a value and in render cell I need to make a decision so if the what did I call it active active if the active cell is the current position then what I'm going to do is call a render editor and what does render editor take it takes trigger function takes the position and takes the state now it takes a value and value I don't have yet so I'll need to do that otherwise we will call render view with all those things now we don't have a value so we need to get a value to get the value I will look at my state because my state has this map or dictionary of its cells and here I can do math dot try find give to look up key and and the map and it will try to find the cell now this can be optional so what I'm going to do is just say default value and if it doesn't exist we won't we will use an empty string it needs to be default art I got the name wrong so I'm calling a built-in function that will replace nuns with with empty string so if I render my page now well that's a bit less impressive all my dots are gone but I haven't done the clicking yet so how do we do the clicking when we render a view in the attributes we can say things like what I've done here above with the ID arrow cell add that just says assign this value to this attribute but I can also do on click and here I define this this nasty operator which says assign an event handler to this to this event and an event handler is a function that will takes the element that this happened on we can ignore that and now the clever thing is that we can say when the old click event happens trigger the start edit event and this tells my Elm style run time that something has happened it needs to call the update function response to this event and re-render the page so I just need to say trigger this and it will all audible all happen the only other thing I need to do is to go at to the end to my update function and say this is a function that does pattern matching and if the command is start at it at this position then we return a new state where we replace the active cell with some position now I get a green warning here because I'm not handling the update value that's one of the nice things in EPS our pattern matching I'll fix that later and let's see if I can click around and add it cells so I can click around type something in here it never gets stored because I haven't implemented that part yet but at least I can click around and type numbers so that's a good start and to do the other part so this is again one snippet that I'm just going to copy because it's a bit longer I need to go to my input in my editor and add this command which says own input trigger an update value event with this position and what I'm doing here is that I'm dynamically accessing the value of the input that the person is typing in so the D parameter of this function that's going to be the HTML input element and I can do not turn or it's some it's some sort of event event object from JavaScript so it's JavaScript that's why it's so ugly I just do dot target dot value to get the value and I have a value and I can trigger my nice update value event and now I need to go back to my update function and actually implement this so if I get update value for a position here's my new value then what do I need to do well I need to calculate new cells so state dot cells is my map with the with the value assignments and I can do map dot add to say at this position at this value and this is a new map with with representing the new updated cells and will return a new state with new cells now the nice thing here that this is this is all purely functional generating a new state so if I had any other reference to the state doing some other work in the background I wouldn't just override the state now so let's see what happens if I save this I saved it I can type 1 T 3 here 4 5 6 7 8 9 10 and then go back change it I can type equals 1 plus 4 and nothing happens so we've got a spreadsheet where you can edit a table now this took me 16 minutes exactly so that's a good start we have some user interface now we actually need to do spreadsheet that does something you can sell so let's let's improve my spreadsheet so the next thing we need to do in my spreadsheet is use is to do some parsing when you type a formula and we actually need to parse the formula and then evaluate it and to do this I'm going to use a very very minimal parser Combinator library all the code will be will be somewhere on github after the taco I'll tweet a link you can have a look at it so this is a site from the elvish style this is the only thing that I'm not going to implement from scratch during the talk that was maybe we should have done this with Scott blushing where he would write the parser Combinator in an hour and I would do this the nice thing here is that you just have a type called parser and then you can compose these parsers now a parser is something that takes a list of characters and it can fail and produce none or it can succeed and produce some containing a pair with the parsed value and the rest of the characters that it didn't need so if you run a parser it might tell you if you have a string 1 2 3 + 4 it can tell you I parse the number here's 1 2 3 it's an end and the rest is +4 parse that next and then there's a bunch of combinators for working with parsers the the or one says try the first part sir if it doesn't work try the second one and return whichever succeeded and the star says parts the first thing then parts the second thing and give me both so these are my parser combinators and now I need to define what the what the formulas look like and actually implement those so I'm going to put that put my hints here and I need to define what is an expression so this will go to my domain model and my expression so you can type a number which is just an int she say 42 or you can define a binary operation which has an expression and operator and another expression so this is really nice way of expressing what what what an equation is and what will add more stuff to this later and now I need to write some parsers so what is an operator an operator can be one of those well-known characters so I'll I'll do some nice copy and pasting here it can be x plus there's more - and divide so this just says recognize any of these special characters now number so my parser Combinator library has a has conveniently a parser for integers which says parser of int so it will recognize and end the other thing that my parser Combinator library has is that it comes with this map function where I can say given and power a parser so so let's see if I do string of n then what this means is it says given a parser that recognizes integers whatever they parse transform it using this function so here I just converted the string and I get a parser that will recognize strings now what I want is a parser that will recognize my expressions so I can say number and and now I've got a parser that will recognize an expression which happens to be an integer now I can use nice features of F sharp and just say this is an integer math number so I can parse numbers that's a good start now I need to parse binary things so a binary thing let's starts up with something simple it's going to be a number followed by an operator followed by another number this doesn't do nest it things that's alright we'll add that later and now we have a parser that recognizes a pair with a pair of expression and character and another expression so this is three things they're bracketed as pair of pairs because the operator just gets sort of associated to the left so but we have we have all the three things we need and we can turn them into a binary operation using map where I get the left thing and the operator and then the right thing and I'll say binary left op right all right so this is this is probably something forgotten that's what did I do binary no this is right let's see if I save it then it magically works all right the demo gods are with me so far that's nice so now I'll have an expression so an expression can be a binary thing or a number and let's see if this works so I've written too much code without running it so I'm feeling kind of nervous so what I want to do now is to go to my view and go to my render cell and whenever I'm rendering that the the view with the value I actually wanted to try evaluating it or try parsing it so what I'm going to do is say well if I don't have a value if there is none no value then I'm just going to say return render empty string if there is some value then let's try parsing it so let's say expert and the parser a library comes with this run function which will run so I'll say parsed run the parser so run takes a parser a sequence of characters and returns a option because the parser might fail so parse is my parse expression or none so what I'm going to do you just to see what happened it's just convert this whole thing to string and say string parsed which is not the real thing yet but a good start you see what's what's going on so now if I say 5 then I get number 5 so it actually sort of formats the FS or data type as something that looks like absorb if I say 5 plus 4 that's not 4 this is 4 then I get binary of number 5 plus number 4 so this is this is all I implemented so far and it seems to be working if I type I'd although ABC then it says null that's just because I like to prove the C sharp people wrong and Matz was saying in the morning that F sharp has all this null thing sorted you can get now if you try hard here I'm getting null because that's how fable actually at runtime represents non-event the none value so it's sort of hidden from the F sharp code but Italy still leaks through the JavaScript which actually is of nice because it means when you get an object from JavaScript you can just pattern match it and say none some and handle it so this means the parser has failed so now we've got a parser that sort of works and we want to do some more things so the nice thing that I think is sort of really really elegant here with this example is using the observed discriminated type discriminated union type to represent your expressions so an expression can be a number or a binary expression we will add reference as well when you say like a 1 plus 4 and this is a recursive type because the binary itself contains more expressions so you can say sort of if you say 1 plus 4 times 7 then that's going to be binary of number and another binary and they're not only sort of nice readable thing but they're also very easy to process because we can just write a function that will pattern match on this and handle all the cases and do whatever you need to do to evaluate so I want to write the evaluator now and for that I need to copy my next chunk of cheats so I want to add a recursive evaluator I'm going to put it somewhere here just after my parser so to write an evaluator I'm going to define a function called evaluate that takes an expression and pattern matches on it which I'm writing using this function function construct which is just like take an argument pattern match on it and when it's a number n then my result will be the number so this was really hard when it's binary we get operator and right and this is where we need to do a bit more work so the thing on the left and right they're both expressions themselves so we will need to evaluate those expressions and to make that possible I need to mark this function as recursive and then I can say left evaluated is evaluate L let right evaluate it is evaluate R so now I've evaluated left and right and now I need to do the operator now to do that I'm going to use a bit from the cheat sheet so what I'm doing here is just defining a mapping a dictionary where you can look up using the operator character and it will give you the actual F sharp function or the F sharp operator to do the plus minus times and so on so then I can say operators dot lookup index using the operator and this is a function that takes two integers and I think I'm missing a here oh I can't spell at all that's right so fortunately I'm in a type typed language so I don't have to learn how to spell so now the binary also evaluates and we need to actually call evaluate here when I parse things so once I parse things now this is this is still an option we'll fix error handling later on so now I'm going to be very nasty and just say dot value which will throw an exception if the value isn't there don't do this well do it do it but then remove it so now I can say evaluate this and this is my result and I still can't spell and my result is an int so converted to string and display it now if it reloads and if I don't make any any spelling mistakes while typing my equations I should be able to say 1 plus 2 or 4 times 728 all looking good or even just 42 that should still work as well so now I can evaluate really basic equations and there's two things I want to do next one thing I want to do is to actually fix my parser to do nested nested things too so to do that I'm not going to type all of it I'll just paste it in and give you a sketch of or explain what it what it means so the one tricky thing here is that now an expression can actually be inside an expression and I'll add some new lines so that you can see the whole thing so here I'm defining an expression but I'm not saying what it is yet so I'm saying well I'll have some expression but I'll I'll define what it means in a second then I say a bracketed thing is an expression with some spaces and some brackets around a term which is a sort of closed expression as a number or a bracketed expression a binary is a term followed by space followed by operator followed by some more space and followed by one more term and we wrap it in the binary so this is the same thing I was doing before but now with terms and spaces and then I say an expression is now a binary or a term and then I say this is actually expression and I also add a formula which is equals expression and an equation you can put in spreadsheet which is space formula our number and space so the whole business with expressions I'm doing that before because I'm defining an expression as binary or term term could be bracketed and bracketed contains an expression so I need expression to define what is an expression and for that you need to do some recursive recursive tricks so I've defined recursive expressions and now I'm going to change my evaluation my play parser here to actually use that I call it equation or did I call it formula equation is the one with which could be either formula with equals or just a number so this is an equation and if I save it and look at what I've got then now I can just put in numbers like I was doing before so I can have some numbers and then I can say equals five times seven plus two which is 45 does that sound right probably yeah mathematics is difficult yeah I think this is right so this seems to be working we can evaluate equations we're still missing the most important thing which is to be able to say something like a one plus four if I do it it just crashes I get some JavaScript error here so we need to fix this and to do this I need to add a new thing to my expression and that will be a reference so if I go back to my domain model then I can say an expression can be a number or binary or a reference of position and if my if my editor was a bit bigger you could see on the right panel it tells me where am I missing some case there's this little green dot that's telling me you added with reference to your expression but you haven't implemented the handling of references yet so we'll fix that in a second I also need to add references to my parser so if I say what is reference my reference is something like a five so that's a letter followed by an integer and I'm going to just say map reference because the thing on the Left produces a parser that recognizes a pair with a character and an int and this thing takes a position which is character and then and so now I have a parser that recognized one more kind of expression specifically dereference and I can add it as another case to my term which is the sort of basic syntactic constructs so now a term is a number or bracketed thing or reference and so now I can actually parse references and here's the missing bit where I haven't implemented the evaluator yet so here we have evaluator for numbers and for binary and we need to add handling for references so what's a reference it has a position ah no no no let me see yes you are right typing is so hard I don't know how you people managed to do it all day so we need to evaluate references now this is this is difficult because this is just some position but we don't really have the cells available here we just have the expression so we'll need to tweak our evaluate function to actually get all the cells from the spreadsheet because it might need to do cup into the spreadsheet now if I do this then I need to pass the cells through all the recursive calls so that's one thing the other thing is I will actually need to go to my evaluate function which is somewhere somewhere up here no I need to go to the place where I call the evaluate function in render cell and give it the cells from my from my spreadsheet state so now we have access to all those all those cells and if we want to evaluate a reference that we need to find the value for the cell so this is the the code that the person wrote and you can see I'm using map dot find which will just throw if the if the cell doesn't contain anything so this is one more place where I'm doing things in a dangerous way and that's something I'll have to fix later then we will run our equation parser on this code so this is parsed and again this is option and I'll have to do the parsing I'll have to have to do the error checking here eventually but if we just pretend it it will always work then I can say parse dot value this is dangerous we'll remove it later and save my code and let's see if it works so if I put say 3 in a cell c3 then I can go here and say c3 plus 1 that's 4 D 4 times 2 that's 8 so it seems to be working fine and if he did if he did spend a lot of time you could we we're now good enough that we can almost implement a Fibonacci numbers so this is f3 plus f4 I don't have the drag down feature yet so I'll just have to have to type all of those manually looks good doesn't it I'll do one more and then I'll stop all right that's just my Fibonacci number calculator implemented in my own spreadsheets now one interesting thing you can do here is you can say equals let's see I'll go here so I can do equals I don't know f1 now as you can see I got some JavaScript error which is why it stopped working it says key not found so that's not very good or I can just say 1 modulo 5 and I don't have that implemented so I have option has no value so my error handling is kind of poor so that's the next that's the next step for my spreadsheet I think I implemented everything I wanted here yep so now it's time to do some error handling and how do you do error handling in F sharp bay might be one answer but I've got the better one which is Rob so if you want to do error handling in F sharp you can I actually so a sort of word of warning you can use exceptions in F sharp and very often they're actually really nice way to handle exceptions because F sharp has has try-catch support and it also works in works inside asynchronous workflows and so if you're if you're doing sort of handling of unexpected exceptions then you can just use exceptions and it's going to be easier most very often but here we sort of want to explicitly say this may be missing so we're going to change our evaluator so that it returns option and option is the F sharp F sharp answer to this sort of null problem that Matz mentioned in the beginning so an option could be none meaning there is no value or sum and then we have the value and the F sharp library comes with two useful functions one of them is option dot map which says if I have an option of T and a function that can turn T's into hours then I can produce an option of R and the other one says if I've got an option of T and I have some more work to do that can also fail that might produce our option then I can sort of unwrap all those options and just give you an option of our so the first one basically says transform a value if it worked the second one says get something that might have failed do some more work that can fail as well and return just a simple value that is either there or not there so we'll need to use those along the way and to do that I'm going to go here in my recursive evaluator and change this so that rather than returning an int it returns an option of and so this case was easy if we have a number we just return some number and now we basically have to go and fix all the errors until the compiler is happy so here the compiler is complaining because these things are in options so rather than just using the value I can say option dot bind and if we actually got successfully evaluated the left thing that we can continue try evaluate the right thing and if this worked as well that we can do a map operation that will run the operator so now I've got I've got the transformation working here this returns an option I've also got a bunch of things that can fail in reference so this should really be try find to handle the case that you're referencing something that doesn't have a value if this works that we get code and then we can run the parser and if that worked as well then we get the parse expression and only then we can actually evaluate it and if the evaluation still fails well we return none and bind will take care of care of that so I've changed the evaluate function and if I go to the place where I'm actually calling it down here in my rendering now this is something that can fail and now I can also fix the thing where previously I said let's just parse it assume it worked so let's let's be a bit nicer and let's run the parser and then say if this worked then we will continue we get the parsed value and we try evaluating it and if this worked as well then whatever result we get we will just format it as string and this gives us a result which is a string option now I want to nicely format this as well so I will change my render view function and give us give it this whole option value and here I'll just say some empty and I'll go to render view now this value may be optional so what I'm going to do here is to say insert a style if it's none then give it a red background otherwise no special styling and I'll add a default value default arc where if it's if it failed then I will display hash error to make it look like excel all right because that's what my boss one's saying so now I can say this is this is this is 5 this is 11 this is C 3 plus C 4 this worked but if I do c8 then I get an error if I do something that doesn't parse I get an error if I change this value to 0 then I actually get an error over there so this is a nice thing that works sort of automatically for free because as its updating the the view it will recompute the the cells and so if I delete it it the error will get propagated if I make some changes here it all gets updated so I've now got I now have a have a nice error handling now there's still one case that I'm not really handling well so if I go to cell b2 and I say b2 plus 1 then what will happen the the famous nothing it seems broken happened in my JavaScript I get maxximum call stacks I succeeded so my evaluator tried really hard called itself a lot of time but haven't haven't really done that yet what do we do about that well this is this is actually one thing that is now really really easy to fix and by the way the the way the Excel engine does it is that the the render func the evaluate function just counts until it gets called 100 times and then it's as well probably no so we can already already do something that's better than Excel where as I'm doing the evaluation I will keep a set of the reference cells that I've already visited and if I get to the cell again then I'll say none so rather than just counting to 100 we will we will actually check that you either have a have a cycle so I will add a new parameter Refs which will be a set of the references I already visited and whenever I call myself recursively I will have to propagate this information so that's this part and when I'm in the reference case so here then what I want to do is to add this new cell that I've just sort of got to to my set so I'll say sets not add position to my references and now I'm saying I saw this I saw this I walk through this through here if I ever go here again it's an error and to handle that I can now do something like pattern matching on on the reference but with the when Clause where I can't a test whether the set contains this position and if that's the case there we have a reference to a cell that we already had to visit while we were evaluating so we say none this is an error does not support it and now if I go back it didn't it didn't refresh because I get this red error mark here on the side so I forgot one thing when I call evaluate initially I obviously need to give it empty set of things I haven't I haven't seen any references yet so that's what I have to do and now it reloads and I can say see three plus one and I get an error if I go back and change it and you see two plus one then now it works so that's my that's my spreadsheet that's my spreadsheet done and just to show you how sort of complicated this whole thing is from a bird's eye perspective if I delete all the comments then I have some bit here which is defining the domain model so this is just saying what is actually a spreadsheet it has positions it has expressions that you can put in the cells and have stay'd which is what I need to render and it has these two events which is the sort of operations that can happen so here is my domain model then I had second chunk of code here which was implementing all the different parsers so I can parse the things you can type in your in your spreadsheets most importantly equations that are composed of expressions then I had one more chunk of code which was this recursive evaluate function so this is a recursive one recursive function that walks over the expression resolves the references propagates errors correctly and checks for checks for recursive references and then I have all the rendering code here so render editor render view render sell and the main rendering function and the update function I'll move a bit up so in my rendering code that's that's a bit longer because we just had to render else of different elements and render cell does the sort of clever thing of figuring out is it the current one or is it is it just the view in which case we need to evaluate it and my main rendering function and then I have the update function which is handling the events and saying if this happens this is how we update the state and I've got my entry point code which just says this is the initial state and and start so if I figure out how to turn on line numbers I turned them off previously so that I'm not destructed by this then it actually fits in something like 130 lines of code and that's implementing that's implementing a spreadsheet that does not everything that Excel does but still quite a lot of quite a lot of clever things already so there's there's sort of one thing that I haven't done yet that I wasn't really expecting to have time for so I'll just show you tell you what it would be if I did have longer slot one thing that my my spreadsheet was doing is that every time you render it actually evaluates all those cells and that's fine for a small one but it wouldn't really work for something like Excel where people can create too abide Excel spreadsheets and run the entire economy of the state using an Excel spreadsheet or basically everything so the way to do this better would be to keep a dependency graph where if I have a1 and c1 which are just numbers and then I create a cell b3 that reference references these two cells then I would actually build a graph that says I'm a cell this is what I depend on now how would you do that a very simple sort of easy way to do this sort of thing in F sharp is to change my evaluator to construct not a number not an evaluated result but a representation of a cell which has two things it has a way of getting the current value and a way of notifying when it has changed and then you when you rerender you just update the update numbers in the cells and they will say have I changed not well then I'm not going to trigger this observable but if the number of changes then they can say trigger this observable and all the cells that depend on them will subscribe to this notification and do the recomputation so building a graph using these things is the sort of last thing that my spreadsheet is missing and that would that would take sort of 15 more minutes that I wasn't really expecting to have so that's just a just a sort of sketch of what you might need to do so the one thing that I think I often sort of get when people when people see me write some code life is that you say it's nice you can do all this in one hour but is this really what ifs are programming looks like in the real world aren't you like you trimmed this down to the very simple thing so that it fits in a talk and I did that I I did sort of simplify this this a lot but this is really what the FS are programming looks like in the real world because when I need to write some solve some problem most of my time is often spent figuring out how to actually best do this and obviously the way to figure out how to best do things is to use some crazy scaffolding engine to generate 100 classes for me in 100 files and then modify one spent the rest of the afternoon fixing my code base so that it actually builds and then running built and seeing that it didn't work no so in in F sharp I think that the sort of way of developing is that you really very often start with something simple and write a lot of code to explore what's the best way to of doing it and when that code as sort of 200 lines of code or or maybe 400 lines of code then you actually say well now it's a bit long for one file and you split it and I sort of sketched how this would look like here because I do have a bit for domain model that I would put in one file I have a bed for parser that I would put in another file I have an evaluator another file I'll have the rendering and maybe with update and initial I would put it in the main file and that's also a point where I would actually start worrying about adding some more tests because so far I just tested everything interactively and that's that's a way to get the quick feedback that people often want from TDD from sort of test runner a part of that part of that is give me a quick feedback here I get quick feedback in an in another way but when I move to something bigger that I would add some unit tests make sure that it actually does keep working so I start programming really looks like this in the real world and most of the time you're sort of exploring ideas separately and then you then you put it as part of your of your bigger bigger thing so to wrap up I wanted to do a talk that actually shows you how you approach solving one reasonably interesting problem like writing a spreadsheet and along the way I've used a couple of interesting things first of all it was all running in the browser using fable which is an amazing absorb to JavaScript compiler with a lot of lot of active people around in the community this is part of the safe stack which is sort of more more sort of a library a set of libraries that really do everything you need around web development nicely connected and documented together I use the Elm style of programming with the sort of update and render functions and I used it in a very simple way but safe spec comes with a elvish library which does it in a sort of more proper way and I use the nice features of sort of f-sharp compositionality by doing the parsers with with two custom operators to get them composed in two directions and all the way everywhere through my code I used pipes for domain modeling and the option type for error handling so before I let you go I still have 48 seconds so there is a functional track happening here for the next two days with more more talks on functional programming so if that's your if that's your area then do stay here or come or lots of other good talks in the next few days drag your friends in if they if they somehow had to go to something else they totally be here next time and we are also running fpsb lab lunch meeting or lunch hour it is in the program I don't no in which room is it room 10 so come come to room 10 tomorrow and the day after if you want to ask any questions I will I will also be there and lots of the other functional Trek speakers will be there so we can we can help you write some code and join the functional functional crowd thank you [Applause]
Info
Channel: NDC Conferences
Views: 20,580
Rating: 4.9492755 out of 5
Keywords: NDC, NDC Oslo, 2018, Tomas Petricek, Functional Programming, Spreadsheet, Excel 365, JavaScript, Elm Architecture
Id: Bnm71YEt_lI
Channel Id: undefined
Length: 60min 55sec (3655 seconds)
Published: Mon Jul 23 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.