 So first off just a quick intro. So I'm Andrew Collective on Twitter if people want to find me or chat at any point Fred is a project which I sort of kicked off with Ryan Riley last year at some point Obviously, it's open source f sharp friendly, etc. etc We kind of built this out of the bones of a few other bits and pieces So sort of Ryan had a few sort of projects which he built Things like fracture and differing and various other bits and pieces for working with sort of web stacks and web programming in F sharp I had a few as well sort of frost and other bits and pieces to try and explore some more interesting ways of building sort of web tech in in F sharp than just Than just working with sort of web API or anything like that We sort of eventually sort of had various sort of late night chats and various things I decided to sort of merge things together and try and actually sort of pull things into into one place Try and get so the F sharp community having not too many kind of fractured options to do So the web programming which wasn't sort of Microsoft centric in that kind of sense So Freya sits on top of a voting Which is sort of the faders of open standard for sort of working Sort of between sort of web servers and web frameworks I'll talk a little bit more about that in a minute It's something which things like web API kind of hide a lot But Freya doesn't really hide that very much. It's actually kind of useful to understand what that's doing and why So I'll come on to that in a moment. There's also a why about sort of why actually bothered writing Freya and it was very much one of those kind of Personal it scratching things. So I actually had a sort of corporate project sort of a company which I was starting which Had a very sort of heavy requirement for really accurate sort of HTTP API's I Still haven't actually got around to launching that company because I spent the whole time writing libraries to support launching that company I've tried to sort of stop yak shaving as much as possible, but this one's turned out to be enormous and hairy So it's it's it's still going I will eventually launch the company that this was actually meant to do But for now I'm sort of having more fun going and playing with this and talking about it We do get asked sort of you know Why actually bother to use this as opposed to sort of the things which already out there things like web API? It's just a different vibe. It's a different feeling So the web API you could probably do most of the things that you might want to do But you're going to do them in potentially quite a painful way Especially if you want to do things in a very F sharp way If you want to do things with a little bit more accuracy a little bit sort of closer to the metal in terms of actually understanding What HTTP is doing and you want a bit more control over what you're doing then Freya is probably kind of a good bet It's also a good bet if you want to actually start creating your own abstractions So API web API gives you a very NBC-ish type view of the world A very kind of you know sort of your your classes and objects are controllers and if you don't want to do this Then you're kind of out of luck If you want to build your own abstractions if you've got your own problems And you want to come up with an abstraction which suits you better Then something like web API is going to let you Freya hopefully will So what we're going to try and cover is just a quick sort of intro to Freya So a little bit of sort of background in terms of how it works how to think about it when using it Just sort of the very basics of the programming model. We can do them the first half Hopefully take about sort of 50 55 minutes something like that including me rambling now And then we're going to a quick break QA if anyone wants to ask any questions Go for it then as There's not that many of us I think it's probably one of those sorts of things where quite happily just sort of take questions If people want to ask questions shout out things as we're going I'd be more than happy if people want to do that I Think it's definitely one of those sorts of things where I'm I'm well aware that the documentation for Freya is kind of Missing to non-existent in a lot of places right now I was hoping to spend a lot of the flight over here actually writing some of that stuff But British Airways thought of that idea Given that sort of you know, it's very I think valid to sort of shout out questions We'll probably all learn from from things like that I think there's definitely the sort of case that if you're thinking if you're wondering what the hell is going on You almost certainly aren't the only one Apologies if I am too But we'll we'll see how we go the second half of this will work on a quick sort of actual let's implement something We're going to use the to do back-end project, which is a kind of sort of comparison site This to do MVC was one of those projects which people started doing to compare Front-end frameworks so people writing the sort of the same little app in backbone and reaction or that kind of thing So you can get a feel for for what those things look like to do back-end is exactly sort of the same But on the back-end on the server side People have written sort of implementations that in all kinds of languages across all kinds of platforms We're going to do a tiny little one in Freya So if you've got the code sort of down the way that this is going to work into working through the the exercises is basically just to Sort of set a startup project as we're going really so if we're doing some exercise zero or exercise one or anything else Feel free to just if you know set that as a startup project running everything should run Everything should be sort of accessible in the browser. Everything should be firing up on local host 8080 And you should be able to see things actually happening as we go But we'll we'll see how well that works a Quick apology as well the projector and the slides and visual studio and windows Don't play wonderfully nicely, so I'm going to be sort of Slightly sort of schizophrenically skipping around between things and that thing is going to go off and go flickering So I apologize when that's kind of annoying There'll be points in this where I forget to press detect displays and that's blank And I'm talking you're just staring at me sort of angrily Be nice to me when that happens because it's it's not going to be good for any of us Hopefully it won't happen too much. I'll actually remember what's going on so Freya is actually a whole bunch of libraries rather than one sort of single monolithic stack. It's Designed to be one of those sorts of bits of software where you can see right. I like this bit I don't like this bit. I want to replace this. I want to throw this away. I like this kind of level abstraction I don't like this one It's very stacked like in the sense that it starts with a very low level sort of minor abstraction Then tries to build on top of that The abstraction kind of levels which we're going to be going up to today and not the top level There are sort of new and more abstract things coming and you might want to build your own levels abstraction on there It's very much about creating a platform Which it's easy to build the right abstractions for you rather than you know the abstractions that Microsoft or somewhere else decided to give you Quite a lot of the sort of Freya stack was inspired by sort of other languages other communities Obviously sort of the DSP net sort of MVC kind of wealth and MVC movement got sort of inspired by various things Obviously, you could go small talk blah blah blah, but probably more rails ruby envy this kind of stuff happened quite a bit Freya looked around a bit more of the functional language space So we take a lot of ideas and think like closure or allowing Haskell other bits and pieces just a quickie on on Owen just so people actually sort of Get a feeling for for the underlying sort of tech underneath Freya Who's actually sort of used to Owen familiar with Owen as a standard how it works that kind of thing? Anyone, okay, that's good. I didn't waste my time actually writing anything else So one thing which is worth pulling up if you've got a browser handy is to head over to own org Oh In as a state is a community-driven standard. It's very much about writing very low-level kind of abstract interface for how sort of web servers that sort of implement the own standard can interface with web frameworks or So web apps on top of them It's really very simple. It's very lowest common denominator It's pretty ugly, but it does kind of work It's it's kind of similar to something like rack in Ruby or various other bits and pieces. It's a low-level interface between Sort of the unfortunate moving parts So if you're on the own to org site probably going over to sort of specification at the top and then finding the own 1.0 doc might be handy in a little bit So the actual sort of own interface is just this horrible looking funk So basically sort of Owen says okay the server is going to give you All going to expect from you a funk which takes nigh dictionary of string to obj which is glorious And returns a task not even a generic task. Just a task. So say when you're done kind of task It's it's not brilliant. That's really not the most elegant thing in the world But obviously it has to work from any kind of net CLR type language So we can't have anything pretty like sort of async stuff or nice kind of generic so even a nice type system and You know, not even really a nice kind of object system in terms of the data that comes in So this i dictionary string to obj is where all of the requests and response and context data is held And it's just a big mutable dictionary of state Which from the f sharp side of things doesn't make us feel particularly warm and fuzzy, but it is it is what it is really So it does work. You can plug all sorts things into this But it happens with a bit of ugliness, but it's worth understanding what's going on under the hood So exercise zero is going to be something which we have a quick play with this one If you've got exercise zero open in some sort of IDE, I'm going to assume visuals do you know for now, but something or other Fire it up and program FS is what you're going to want So you're going to see in there I'm just going to sort of flip between things over here so that I can actually see what you're seeing in a moment You're going to see in there a function which is kind of something like hello world And that's going to be that nasty raw kind of owing funk of i dictionary to stuff There's a parameter in there, which is which is nv It's going to quite accurately tell us that we're not even using nv at the moment because we've done nothing with it If you fire that program up right now and actually hit local host 8080 you will get a blank response It'll be 200. Okay. It just won't have anything in it. It'll be very very boring What we're going to want to do now is having a look at that own dog spec document Which I talked about just a moment Let's modify that nv to actually write some stuff. So we're going to be mutating that dictionary horribly Where everyone can see it. That's a shame But we got let's take sort of three minutes and see whether we can actually make that say hello world Maybe set something like a you know a response code or response status anything you like Somewhere down in there in the response data keys 3.2.2 in that doc should be enough information to get going And we don't need to be particularly clever about sort of actually just doing anything nice with our task It's just kind of fine to mutate that thing in place Hopefully that's making sense to people but do shout out if I'm making no sense whatsoever Just going to a quick glance at the code as well So those of you that have scrolled down might notice my deliberate mistake from last night when I was committing stuff Which was leaving my notes on the solution in place I have not done that in the other ones, but you have already got the solutions in the solutions folder in here So it depends how uh, sort of honest you want to be I can't exactly flunk people for this So it's kind of it is more about kind of getting a feel for what's actually happening under the hood So we don't sort of run into weirdness later Does everyone kind of made something work see something vaguely happening So if you haven't already feel free to have a look at solution zero Which is pretty much I would hope can look like what you wrote Or at least something like what you wrote If it didn't shout If if what you wrote sort of did look something like that and it compiled and ran and you got hello world back Then that's great. So does the sort of solution to that make sense to people Do shout if the answer's no to that one because otherwise this is going to get really awkward very quickly I didn't actually check as well Sort of whether everyone here actually had some f-sharp experience Which is probably something that I should have done earlier if you came in expecting sort of intro to f-sharp That might be slightly more awkward. I'm guessing everyone's actually written a read a reasonable amount of f-sharp here If not, give me a shout and I'll Yeah, okay, cool Oh, okay. Well, yeah, all right. If you got your camel experience is not going to come as a massive shock Yeah Yeah, I think it should be okay. I think when we start to see things like the computational expressions I'm not sure there's an obvious equivalent But it should be pretty obvious anyway, I think Hopefully there's there's enough kind of demo code and solutions and the rest of it in here that you're not going to get wildly lost Hopefully it'll make sense to you Okay, so let's uh We got that sort of x i zero working. Hopefully speaking and we got a hello world back, but it was Pretty nasty. I think Didn't really want to do that all the time. You could do of course, but probably don't want to so freya.co and the freya core library is Our sort of first level abstraction. It gives us a little bit over this What it mainly gives us in the f-sharp sense is a freya computation expression And it actually just wraps up that kind of state that environment dictionary and all the rest of it In something where you don't need to see it so we can keep all of our nasty mutation away where You know children can't find it and we don't upset the f-sharp community Unfortunately, we have to do under the hood, but we can at least make it slightly more palatable by making that sort of a slightly more functional approach So we have the freya.co library and the freya namespace which has a Freya module which has a bunch of useful functions of working with it So that's sort of freya computation expression is actually And I'm sorry t's the m word, but it's basically an async state kind of monad Sorry, I had it's just kind of You can't really avoid talking about them forever Don't worry too much if you hate monads any kind of discussion of types category theory or the rest of it You might have come to the wrong conference, but don't worry about it in this talk So let's change that over. So if you open up exercise one Rather than using that sort of raw kind of o-in kind of stuff we'll start to use the freya stuff So fire up exercise one And let's see what it looks like with the very basic level of freya It's not a great deal difference. So what we should see at least in exercise one I've created a little bit of scaffold We'll see that a couple of things have changed. So hello world is now an empty freya function And the the exercise function down below which is where we're wiring this up to To katana, which is the o-in server we're using Uh now actually has uh o-in at funk of freya Rather than just passing that hello world function directly All that's basically doing is taking our computation expression and turning into that nasty funk signature Sort of wrapping it in a little bit of sort of unpleasantness You'll see that kind of thing around so sort of converting computation expressions into other forms Sort of compiling or sort of reifying them if you like Um For this exercise all we really need to do is just grab the environment state out of Our freya expression because we're going to be doing basically the same thing again so It's still less pleasant than it should be but at least I begin to see right okay So this this freya computation expression is just basically wrapping that state Somewhere underneath it. We'll stop playing around with it directly in a minute But it's kind of useful to see so we've only got kind of a minute or so to to go with this one X minutes according to my slide not quite sure that happened, but still Pretty sure I only said about two minutes for this one. It's not wildly interesting Especially when you've just done the previous one So if you want to open up solution one whenever you feel like you kind of get where we're going with this feel free You will see something which is obvious and still quite horrific, but Is at least a little bit Less sort of funks and c-sharp types and casts of other things So you'll notice from that that the The environment isn't the only thing we actually hold in the state We actually use the state to hold a bunch of other sort of useful things as well Like sort of memorizations of data and various bits and pieces as a fray optimizations Things that we don't want to pollute sort of our own session with things that no one else cares about We can stick in other parts of our state You very rarely need to sort of fiddle with that directly, but if you do that's it's useful to know it's there So does that kind of make sense that new little bit? I'm going to assume that sort of the Lack of nose means yes, so So let's let's move on a little bit and see sort of exactly what we could do to make that a little bit nicer in this case so in the next kind of exercise We're going to look at sort of what was wrong with that in a very specific way So we have something that works We have something we're no longer sort of actually playing around with sort of funks and other bits and pieces But it's still unpleasant. It's still really ugly um, and The worst thing about this is that it's actually really unsafe So we're mucking about with a dictionary of string to obj And we're just kind of throwing data in there and I could write whatever I wanted to the stream Or I could set the header to be an image or I could do whatever the heck I wanted with it um So I've got no kind of guarantee that anything I'm doing with this is valid http in any sense whatsoever Anything I chuck into that dictionary I'm going to send back to and say hey do something with this and it may or may not it might blow myself up It might do anything, but it Certainly gives me no guarantees about what we actually want to do with it so What we'd actually quite like to have is a way of working with that big ugly dictionary of state In a way that we can only work with the stuff we care about at any particular time So we really want to just look at a specific sort of nested element within that data structure And it'd be great if we could do that in a way Which actually lets us use this as types rather than just strings or ints or random other Sort of potentially fail with worthy kind of stuff so The way that freya does this is with lenses The high school sort of team somewhere down the corridor will probably be Cheering at this point, but the f sharp means he doesn't sort of use lenses a great deal that I found Quick kind of show of hands show of nods, etc. Who's familiar with sort of lenses and sort of using lenses in fp Not okay. Cool. That's just as well. I suspected that that was probably going to be the case So Lenses are a sort of fairly useful functional technique for working with complex data structures um If we've got something like a big nested sort of tree of data or also, you know A big bunch of records containing dictionaries containing maps continuous kind of stuff A lot of time obviously because we've got this immutable data structures If we want to change something which is just a little piece of data Sort of way down in that data sort of structure That's really awkward We're going to have you know, even if it's just sort of records, you know Sort of with with with with kind of all these changes cascading through our data And the code to do something which is probably just you know, I just want to increment this int is Huge amount of code just to sort of go and grab that piece of data and put it back into this immutable data structure and it's ugly And it's ready for both and it's a pain um So what a lens does is let us actually work with just a small piece of that data structure So I've always wanted to do a whiteboard thing. This is going to take a very very small amount of time But it's kind of useful if we had, you know, some big kind of Data structure which had inside it a lot of other stuff Each of which had inside a lot of other stuff and some smaller things and actually the only thing that we care about is that one Uh, and at most immutable languages sort of actually dealing with just this, you know I want to apply a function to this value Is is a nuisance. I've got to go and grab that I've got to modify it. I've got to kind of recreate this whole outside data structure and get that back And so I've got a new instance of this whole outside thing And that's going to be a nuisance what lenses do is basically we can say right a lens is In f sharp at least, you know a function or a pair of functions Which lets us get this and let's us set this and then a library to let us work with that in a way Which this whole outside thing is invisible so I can just work at the level I care about The other cool thing about lenses is that they're composable So if I've got a lens which gets me to here And I've got a lens which gets me from here to here if I compose those I've got a lens which gets me all the way in So if I write sort of lots of small lenses, I can add them together and get deeper into my structure Or I can do other bits and pieces which are useful What you can also do with lenses is convert between the type of things you've got as you go between these representations So if I've got something in here, which is just a string If I write a lens which turns that into some type representation on the way in And writes it back as a string on the way out I can work with that as my type representation Transparenly while actually modifying the underlying string from the point of view of you know the compiled representation So that's kind of you know a lens plus a morphism can actually mean okay I can dive way down into my data structure see it as strongly typed modify just that thing While actually modifying a big ugly ball of strings in the middle So there is a little lens library which I wrote for f sharp called ether which uses sort of these techniques And we're going to see what that looks like now So we're going to start using lenses into that environment rather than Modifying that environment directly So there's some interesting functions, which Fred provides if you fire up exercise two at this point You're going to want some functions like freya dot set lens partial That's going to take a lens and you're also going to take the value that you want to set Whatever that lens is pointing to So there's a reason why we've got freya dot set lens and freya dot set lens partial So some lenses are called total lenses Essentially, that's where you know that the data you're getting is going to exist Um, so that sort of it'll always get you a piece of data. It'll always set a piece of data If you've got a data structure where the data you're looking for may not exist Uh, then what it's going to return is an option of that data. It's going to turn sort of maybe that data Um, you can always set that data, but you can't necessarily always get that data So we've got a partial lens There are quite a lot of things in http and in freya where that's the case because especially when we're dealing with Uh, things like, uh, sort of response values or headers or all the rest of it. Most of these things are optional So we often find that we're working with sort of partial Sort of lenses into some of these data structures But what we should be able to see if you sort of, uh Go with sort of do sort of freya dot set lens partial And then something like response dot status code or response dot reason phrase You should find that actually I'll see you for some data afterwards if that kind of makes sense Yeah, if feel free to go for that if you want to do it It's uh, it might be sort of a useful thing to to do Especially when we're looking at some of the things like the uh, so this it's a bit of a jump into this kind of Piece of code So feel free to look at the solution and see if you can sort of work out what that's doing see whether that makes sense They basically are yeah, so we're generally working sort of within this kind of freya computation expression Which is as you say it's it's a monadic kind of context So most of the methods that we're seeing here are actually working against that kind of monadic state They're working against the uh, so the async state that we have In this case, there's a you know, sort of actually working with that state with lenses. There are other things in there that we can do We'll see some some other worlds later on as well But this is actually a really common kind of pattern in the freya sort of approach So if we go and fire up solution two It's still moderately verbose But what it is is a lot more accurate and a lot more type safe So We've got that response to a status code and the response reason phrase and where we're actually working with sort of mapping things over the response body We've gone from having this kind of world where we're working with objects to a world where that's actually strongly typed So the only thing that I can set the status code to is an int or the only thing that I can set the status Or the reason phrase to is a string If we go and sort of type if you try something like changing response dot status code to response dot headers dot age, let's say If anyone wants to try that one you'll find that 200 is now not valid because it's actually expecting an age type And we have a very strong type system around http in freya So there's no way of actually sort of pumping each sort of invalid http Into a freya response if you use the typed lens system So we put quite a lot of effort into making sort of invalid states unrepresentable sort of non-compilable sort of Freya will if you use it sort of in a reasonably sane way And you sort of avoid diving down into sort of directly mutating the state sort of in the environment It will keep you pretty safe in terms of making sure that everything you actually send it Is is a valid piece of data and that the http your writing is actually going to be correct Yeah Yes If you have So i'll just pull this up on the screen and we'll we'll share this for a moment So Okay, so I'll just take that back to where we were. So if we had our response dot status code Can people see that roughly okay? Cool So that top line where we're looking at setting the response status code Response dot status code is a lens And it's a lens into that environment state which is actually sort of diving down into this nest of dictionaries And then mapping that string type to in this case an it it's quite simple The only thing I can put there is an it so if I want to change that something else if I were to change that to string It's going to say no that's that's not cool You know the only thing that you can set the status code to is an it Uh, if I wanted to change that to something like uh response dot headers and age It's now going to ask me to something else It's going to say that the string is still not valid, but it's expecting an age type So that actually would have to be something like Time span etc etc. So we have to be accurate about what we're doing And all of the representations of data that you can put in Freya are really strongly typed We actually have a complete type system over HTTP 1.1. Does that make some sort of sense to people it's sort of the uh Sort of take take us sort of on faith the the set lens and the set lens partials and this kind of stuff There are obviously equivalents for sort of getting that data out and for mapping that It is basically get set and map, which is what the usual sort of things you want to do with lenses But that will uh will let us actually work with pretty much everything in a web request in a strongly typed way This is the exciting bit. We're actually trying to go back to projecting things Does that make some kind of sense so far in terms of what we're actually sort of Starting to do in terms of working with sort of oh in data, but in a rather more strongly typed functional way Cool So The next kind of thing is obviously we we have a response coming in where we're handling our hello world quite nicely um It's strongly typed. It's it's working quite well. We can be pretty sure that this is actually safe Um, but we don't have any actual sort of routing or anything useful happening here So the next thing we're going to do is actually sort of wire this up so we can actually have more than one response That's really going to be useful in any kind of real world app. So Before we do that there's just a quick other sort of bits to go through which is we have this concept of a pipeline Um, so a lot of Freyre is designed to be really sort of heavily composable Um, if you write to lots of small functions, you can wire them together. You can sequence them You can you can call them from from each other um, one of the things which Sort of the high level sort of composition method is this concept for a Freyre pipeline So if you have a Freyre function, which returns either next or halt You can chain those together in such a way that you'll run through that chain until it reaches a halt And that's kind of useful. So a lot of the things that we that we have Are actually pipelines and we can compose pipelines together in a much more sensible way and we can express sort of, you know What's actually going to happen? So when we're writing things like routers, we can expect that the router is going to halt if you actually matched a route and that kind of thing So much like we had our sort of Freyre computation expression Freyre router provides a Freyre router computation expression Which has, you know, a few custom keywords and take some other strongly tight bits of data to define How are you actually going to wire up? You know these these functions we've been writing which can actually respond to an http request And how we're actually going to map those to different your eyes How we're going to actually start putting the data out and and doing that kind of thing so We have a root keyword in that kind of Freyre router If you want to fire up exercise three, this might sort of start to make a little bit more sense I've already wired one up So I've wired up our existing kind of hello world kind of function And I've wired it up to a root And you'll notice again, that's sort of pretty much everything in here is actually strongly tight We don't have any strings particularly in a way. The only string in there is we're actually parsing into uri template We actually use a strongly typed uri template for for routing and for various other things for generating your eyes and other parts of the framework So we can always guarantee that sort of the the routes that we have Are, you know, strongly typed the data that sort of comes out of those is is predictable And we can actually pass those around as values rather than just sort of relying on people getting the right strings in places So we have a sort of kind of world where we can match on particular methods In this case, we're just going to match on any http method or any http verb So we're just going to say we're going to match all methods with a slash hello And we're going to use our hello world function for that So the next really quick Very very simple exercise is just to create the equivalent for this as a you know We've got a hello world. Let's create a quick goodbye world function And wire that up in the same way I was I'm assuming a lot of that was probably sort of control c and control v. I'll kind of move on fairly quickly One of the things you'll notice if you fire up solution three, obviously we've got these two functions now We've got two routes in our router One little thing to notice at the end of our router. We're piping that to frairrouter.to pipeline This is kind of one of the things that I mean about we work with pipelines a lot Uh, we'll notice that the the hello world and the goodbye world functions. We've created as well also now return uh frair.next So those are pipeline functions as well And that router actually expects that each of the the functions you give it to actually map a uri to is going to be a pipeline When that router actually matches The the result next or halt that it returns will be the the result of the function that it that it matched So if it's it's going to run hello world, it's going to return the result of hello world And so the router is itself a pipeline That frairrouter to pipeline is actually essentially compiling that computation expression We use computation expressions quite a lot to essentially configure to the parts of our systems We have quite a declarative model in that kind of thing I could have a go what kind of thing Yeah, sure so If we were to have sort of you know, we write our sort of hello world function Let's call it hw somewhere over here And that returns Let's say that returns next If I were to sort of then create a router And say okay, so slash hello Uh We'll actually call my hello world function And goodbye, etc. We'll call my my goodbye world function When my router runs, uh, I'm going to map and I'm going to match the first root which actually You know matches the the path that came in on the request and I'm going to run this function And I'm going to get a value back which might be in the case of this one might be next might be halt here And then what I'm going to do is I'm going to return that function as a result of running the router So that actually sort of maps down to here And then what I can do with any of these functions So a router or any other type of function is I can chain them together And I can do that with there's a couple of operators, which we can see later on Um, but what I can do is I can say right you're going to carry on running this chain of functions until one doesn't return next So in the case of this router, I might say okay, right I want this function to only run This hello world and then I want it to halt So I just make sure that hello world returns halt and then the thing that comes after the router or anything else It uses hello world isn't going to happen. So I might want to say You know, there are some headers which on the else sets, but I don't want to set them all I might put something in front of hello world, which is you know, another function which does something like security Uh, so I might authenticate someone I might do some authorization at that point and I might say okay, so That function there is going to return next if you're authenticated It's going to return halt if you're not so we never even run this hello world function So we can start to chain things together in a way which actually sort of is is useful Does that make any sense or is that useful? Yeah Yeah, basically. Yeah, it's a way to sort of lift frayer pipeline expressions into a place that they can be composed Yeah, okay, so hopefully that sort of made some sense. You ended up with two roots and a router Um, but we've got some slightly unpleasant sort of things starting to happen. We've got two functions which are basically identical Um, that's not particularly good One of the things we really want to get as much as possible out of frayer is this concept of reuse and sort of breaking things down into small functions And reusing them so obviously sort of everything in frayer is just a function You know, all of these all of these frayer functions are just parameterized functions So we can call frayer functions from within other frayer functions We can give frayer functions arguments and then we can obviously sort of parameterize them in that way Um, so what we're going to try next is just saying right, okay Let's let's take this sort of common bit of functionality It should be fairly obvious to sort of refactorable bit from sort of hello world and goodbye world And create a new function Uh, call it. I don't mind too much, you know, sort of whatever you'd like to call that Pull the common stuff into there. Maybe give it a parameter for the message you want to send Uh, and then sort of actually make our hello world and goodbye world functions. Just call that one directly Because it's a computation expression It has the usual kind of do and let and uh, sort of return Sort of bang notation available. So you should be able to call that function as you would any other Kind of computation expression or sort of async type expression in in fsharp Feel free to uh, to look at the solution for if that's kind of useful to you Especially I can imagine if your main sort of world is a camel and you're not used to computation expressions that might, uh Definitely help Uh, we will get there in the second half Yeah so Just as a really quick sort of while other people are just doing that for a minute or two just the computation expression side of things in fsharp is essentially just some sort of syntactical sugar over Well, what is essentially a monad You can write your own as long as you write sort of a type which implements sort of you know, sort of bind return, etc Et cetera You know in a specific way The computation expression syntax kind of comes for free You can then sort of actually use this computation expression syntax with an instance of that type and say okay Sort of let bang is bind and and do is is return this kind of stuff Or return is return do is actually something else, but but it's It's only just sort of syntax sugar Um, and in fact actually sort of i'll show you just very briefly in a few minutes So that actually it's sort of you you don't need to use the computation expression syntax in fair If you don't want to if you like operators and monadic syntax, that's there too Um, but this is sort of usually a little bit easier to get started with it's a bit more verbose, but it's a bit more understandable So hopefully we should have ended up with something like solution four by now Let's go and take a look But then we luck people ended up with something roughly akin to that kind of thing so we Pulled all of that kind of common stuff out into uh into a function Which takes a message parameter and then just called that from our goodbye world and hello world functions All right, so we've at least managed to get some different routes in We're almost at the point where we could start building sane things with freya or admittedly at a very low level abstraction But we could actually start working with http in a relatively safe way and we'd actually start wiring things up to Actually sort of start building an api or to start building something that we might want We might not want to do it this way. It's going to be a lot of typing and a lot of work But we might at least be at a point where we could actually start to use this reasonably consistently The last kind of bit to perhaps look at is, you know, actually we're matching on routes and that kind of thing But routes tend to be a little bit more dynamic than this. We tend to have more than just some static uri's I said earlier that we used uri templates for our routing and the reason for that is we use uri templates for matching as well So if we have a uri template Which is you know slash users and then an id Sort of piece of data embedded in that uri We're going to want to be able to use that in our In our code in our data. We're going to be able to get the value about this kind of stuff that's coming out of the route Um, and we do that with lenses again So when we work with things like the request and the response we've got a lens into the data into that part of things The router will actually write the the data that it's matched the data that's pulled out of the route into the environment as well And we have some some lenses which can can get and set that too So in this case rather than it being request dot so-and-so or response dot whatever We've got root dot whatever and we actually sort of have a you know an rfc compliant version of the uri template system In this case if we've just got sort of id or something like that in the route Then actually that's just an atom. That's just an atom piece of data rather than a list or a map or anything else Which you can technically specify as part of the uri um So we'd use that lens. So sort of you know root dot atom id Uh, and we'd be able to pull that piece of data out of the route Uh, that's a partial lens again, um, because you know, we might not have that piece of data in the route Um In this case we kind of know that we are going to have that because we're not going to get to uh You know sort of matching on this if if if we didn't match Um But let's actually try and use that. So we're going to change our our two functions now Uh, so we're going to change the routing uh in exercise five So we don't just have this kind of static hello and goodbye kind of world We're actually going to say sort of hello name. Hello someone um And then we're going to use that piece of data on our functions So this is where we're going to want to uh, we've been setting data so far We're afraid of set lens partial Uh, we're going to want to use get lens partial here so we can actually pull that that route data out of the environment When we do that we're going to want to uh, sort of potentially change our functions Uh, so it might take an extra sort of parameter for for who to greet or for who to say hello to or other bits and pieces So root dot atom is going to return a string option um The thing with this and we find that this is sort of obviously quite a sort of common thing that happens with This kind of programming is this is definitely an option type, but we know that because we did actually match on this route It's definitely some So you can be kind of lazy and you can just take the value which is icky, but it actually works fine It's actually a safe thing to do If you really wanted to do something a little bit nice than that You can actually do some options sort of get or default or something else You can actually sort of get this so if you want to be really particularly safe and make sure that there was never any chance of uh, you know runtime exception you could Actually just sort of pattern match on that value if you wanted to and had supply a default name But the aware that that case is never going to get hit anyway, so and again, obviously sort of feel free to uh to take a look at solution five when you sort of feel like you uh Might get something from doing so Yeah, so Although obviously sort of the value that that brings back is an option because the the lens can't guarantee that that value is present in the in the root We know that it will be in this case because you know, we'll never call dysfunction unless we've matched that particular root Um, so it's it's actually sort of fairly safe to assume that we've got that But if we wanted to be a little bit safer we can pattern match over and make sure But feel free to just use the value of that option if you want to because it's going to be Effectively just as safe. It's just one of those things. So unfortunately without an extraordinary type system Maybe you just could get us there. Maybe not. We're never actually going to be able to verify at compile time Yeah, I mean that's one of the things that we'd probably do there is actually say, right So the the values that you might get out of a root Uh, just the values that are valid in the uri So they're either a string or a list of strings or a list of string pairs What you could do is write a function which takes that string and sort of you know option maps it to you know Int dot pass or whatever you wanted to do in that kind of sense if you want to cast that something cleverer Yeah, yeah Yeah, yeah atoms are always option of strings Uh, there are three things you can get out. You can either get a list or a sort of a list of pairs Because those are kind of the things that are valid within the uri template Um, as you say, I mean there are quite a lot of places where you're going to want to turn that into something a little bit more Uh structured And we'll we'll actually see that in the second half. We'll we'll use that in some of the the api that we build We're going to do exactly that All right, so hopefully people will have ended up with something Along the lines of If I actually go and find the solution to five Obviously in this case, we uh, we only really care about strings as it goes, but we could We could as you say be sort of passing those or sort of turning those into something a little bit more Uh, strongly typed or a little bit more specifically typed if we actually had a requirement to do so Uh, we'll see that later We could do something else here as well, of course. I mean this this is kind of There are always going to be different ways to sort of decompose this kind of problem So in this case actually name Is exactly the same in in both kind of places We're doing this freya.getlands partial in both our sort of hello and goodbye world sort of things We could move that into message name and have that have that over there um But then you know, it's it just depends sort of what we think we're going to use that for later Do we want that to be a parameter of this or is this always going to be the same thing? Um, you often find that it sort of works out more simply to make these things, you know So as parameterized as possible and then just pass things around You can always pull it out. It's pretty easy to refactor, but it's it's there if you need it One last thing for we have a quick break and any sort of other questions if you want to ask When I talked earlier on about uh, you know, we've got this computation expression syntax for this kind of thing Uh, and those are sort of really sort of quite sensible questions from there about you know Is this actually just a monadic kind of thing with the usual sort of bind and all the rest of it? Yes, it is If you like that kind of thing and sort of the f-shark communities a little bit split on sort of how much it loves custom operators or indeed doesn't Um, you can do that Quite happily if you do like those sorts of things so you could rewrite sort of solution five Uh, it's slightly differently if you open up this freya.core operators namespace You could write it like this If you're familiar with uh, sort of fairly common sort of monadic operators household, etc, etc This will look quite obvious and familiar if you're not this might look insane Um, but essentially all this is doing so if we take a look at this sort of top one this message name These operators basically just chain together monadic expressions And throw away the result of the last one as things like freya.setlands partial actually just return unit anyway We don't care about the results so we can just chain them together Um, read name here actually this this operator here Uh, actually just passes the result of a uh of a monadic function to a normal function Uh, and this one here just composes to monadic functions and takes the the result of one and passes it to the input of the next So it's a lot smaller, but it's also a little bit Less obvious to people that aren't really used to that kind of style of writing things It's there if you want it, uh in some of the systems I've written with this, uh, I used Sort of this style almost exclusively I'm not going to do it again in this talk. It's just kind of a useful sort of if you like this kind of thing If you have any hascal envy if you are a hascal if you are an on else you might want to Uh, sort of go this direction, but the computation expression syntax will let you do absolutely everything This does just in a slightly different way I could also be particularly unpleasant and say that there are Functions for doing things like fray dot set lens partial as well If I wanted to I could actually do something like I believe something like that Yeah, there we go so that Slightly weird operator here will actually do set lens partial in this kind of world Uh, and then I can actually just start mapping things and making this really quite small indeed and it starts to look like just imperative code um But again sort of you you might want to get a little bit more used to what this is actually doing before you start Filling your entire screen with operators as I say it's it's there if you want it Uh, there's there's going to be documentation sort of which will walk walk you through that and compare the two styles Uh, most people are probably going to want to start off and stick with the computation expression style It's a little bit more for both, but it's also a lot sort of easier to just sort of pick up and read quickly All right, cool. So we're about 55 ish minutes in so It's a sort of mid sort of session break So in the second half we're going to do an actual sort of example of building something slightly more sensible with this And for people that were interested in the web machine approach That's what we're going to hit in the second half. So we're going to go one more level of abstraction up and start to look at frame machine Uh, and start to look at sort of how that's similar to web machine how it goes a little bit further in some slightly insane But potentially useful ways Sorry Typed ways yes, it does go there in typed ways too. Yeah, so I mean I love Erlang, but it I wish you had a different type system, so But um Yeah, uh, all right, so we got let's take to the 10 minutes Grab the restrooms if anyone wants to come and ask anything talk about things that'd be cool Yeah Yeah Yeah, so oh in that funk of frayer actually doesn't care about the return type It assumes that by the time you're actually sort of turning this into something to give to a server You've done all the stuff you want So oh in that funk of frayer will take your return type and it will merrily throw it away and it will never look at it again Um, so that's sort of one place where yes, it doesn't matter too much. It's just going to discard it It assumes that by the time you get to there You've already done all the things you want to do with your pipelines and composition this kind of thing um so frayer Frayer pipeline is frayer of frayer pipeline choice So that's that next to a halt union um Frayer the frayer function itself is just frayer of t So whatever you return from that you've got a frayer t if you return a frayer pipeline choice You are sort of implicitly a frayer pipeline and then you can start using anything which expects a frayer pipeline Which is quite a lot of things But we'll see that a bit more as we go through um Yeah, so we've done some experiments with things like quotations With with type providers around generated aspects over this The kind of the underlying problem is that sort of the the data you've got is so woolly underneath Sort of that the dictionary and other bits and pieces are are awkward to work with You could probably add an extra layer of sugar on top of things like frayer dot set lens and this kind of thing You could probably also write a new computation expression which actually sort of gave you some of that stuff as keywords or custom expressions that kind of thing Um, it's it's out there if if you know as a potential way to do that At the moment it's sort of one of those which is Hard hard to make it add a lot of value um I'll obviously sort of it's finding that right balance between sort of being sort of verbose and explicit Uh, and also sort of reasonably concise The thing with this is that you actually see so if you don't end up spending that much time actually doing things like frayer dot set lens Etc etc when you start to look at the high levels abstraction Quite a lot of what we've done in the first half is essentially sort of the tools you use to build different abstractions Uh, so we're going to work through sort of our sort of most common abstraction in the second half But sort of from a day to day perspective if you're regularly doing things like actually setting headers manually and this kind of thing Um, then you're probably working at the two lower level You know, it's time to write another layer on top kind of thing Um, so it's one of the things that sort of fray is quite good for is sort of building up new abstractions out of smaller chunks Yeah Yeah No, that's cool. So Trying to see what what a good kind of way of doing this is um So a computation expression is basically sort of a syntax feature in f sharp um where You can write this kind of curly bracket kind of syntax. So the most common one that people will see is is async Uh, what that's doing behind the scenes is actually saying right whenever you write something like let bang equals so and so Or do bang etc. It's actually applying a function to that before it does that thing. So The async for example will take your expression that will wrap it in an async return or that kind of thing It's a way of sort of actually sort of modifying your functions or your expressions before you run them Um in this kind of world what we're actually doing is we're saying right each of your functions is going to have an implicit Sort of second argument, which is the state or something like that um So it's a way of wrapping up and sort of tidying away sort of threading some kind of context through this expression So in the async world, it's not actually sort of sending anything through but it's wrapping everything in asynx Or async dot run or async task or whatever Um in this world it's sort of saying okay everything gets an extra state Um, there are other ways of doing that kind of thing Um, we'll see one later on which is actually a jason computation expression What that's actually doing is saying right the sort of implicitly what you're working with is some jason object Which is the state which is the environment So any sort of function that you run in the jason expression Is going to be a sort of implicitly applied to this jason object And is this is why when you do like freight on set lines partial Yeah, you weren't ever actually specifying the thing Yeah, yeah, that's the thing. So that that freight expression implicitly has within it the state that we're working with Um, so whenever we actually do something in there, we've we've we've got access to that state Um, you know if we actually very briefly Let's see if I can Find some