 Hey, everyone. Thank you for joining today. I would like to talk about programming web applications with F sharp and basically retargeting them to kind of move away from JavaScript into web assembly I'm going to be using two technologies one web sharper and the other bull arrow to present some of these ideas And hopefully you can learn something from this We had certainly been working a lot quite heavily with web sharper to develop web applications and in recent years There had been this steady move a lot of cost customers have been asking about how could they better utilize web assembly? For example for some of them more computationally intensive Tasks that they have surfaced onto thin web clients So this probably affects a lot of people The technologies to enable that had been around for quite some time So I'm just gonna dip our toes into this whole ecosystem in this talk There's just so much just enormous amount of projects huge amounts of information about this topic other language communities Most notably rust had been extremely active in the area And I think they have a lot of inspiration to give to us Developers coming from other ecosystems so With that, let me jump into web sharper. We only have a limited time here. So I'm gonna be quite quick and trying to Basically Maximize our time. I think the easiest way to get started would be the CLI the dot net CLI You can install So here I'm showing the commands to actually install bowler o and also web sharper So you can do dot net new and then dash I and basically either bull arrow dot templates or web shopper dot templates This will put the project templates onto your system Clearly you will need the dot net SDK Just even to use the dotnet command and also to have all the build tools and everything available So once you have that you can of course create new projects In the bull arrow templates, there is a minimalist approach. So this bull arrow dash app Code name or pseudo name the name of the template Can be configured using different switches on the command line You can opt into just generating a client site code that will be run on web assembly or you can have a server client application So you can configure that you can read more in the documentation page that I'm gonna show you in a few minutes On the web shopper sites or side things are a bit different We have different project templates for different scenarios that you might actually run into for example, if you're needing a single page application Then you can do dot net new web shopper dash spa Still give some switches on the command line like the name of the project If you prefer you can actually use C sharp in addition to F sharp So these templates are bilingual so you can have support for C sharp as well Or if you want an HTML application or a full client server application, you can use web shopper dash web There are other templates. I'm not going to talk about these today. There is a nice documentation page that describes them We are about to release web shopper 6 Probably early next week and there will be a new documentation site with a lot of extra information We didn't have before so once you created a project you can edit your projects You can run them using just dot net run or you can use a dot net build to build to see for compilation errors You can toggle the verbosity of the compiler output It's it's all basic Dot net SDK stuff So the two websites to watch out for is a FS bowler or dot IO and web shopper dot com I Urged you to have a quick read just to see if you are into these Technologies, I think they're quite fun so To help you get convinced about web shopper There's this site try web shopper. You can go online The link is on the bottom and you can basically Try out snippets of web shopper code without actually installing anything or preparing anything on your system This is actually quite nice you can We will be looking at some of the examples so don't worry you can also create your own you can Reference dozens and dozens of different JavaScript libraries that we call bindings or extensions Into your snippets and then you can do charting like what we see here. You can do games You can do all kinds of other stuff By default most of the samples will be reactive So you are I web shopper dot UI as a reference will be given and I Think it's quite fun to actually get started looking at some of these snippets and seeing what people have invented. I think it's quite fun Alright, so let's just jump. This is without any coding. So I'm not gonna For this part at least not gonna demonstrate anything code, but if I was To actually put this into a project. I would probably create a Simple like a minimal web shopper application There's a template for that of course and just paste this very code that we see here And run it so in about a minute we could get this to run and it would say hello world Now the interesting thing to note here is that if you look at the main Function or binding here you can see that we are using application that single page So this actually will give us a single page HTML application and the content of that will be a simple H1 tag as we see hello world now You can imagine you could write all kinds of HTML combinators here To create markup We actually recommend that you use HTML templates external files so we can make changes to those We will be seeing that here in a second, but I wanted to just basically reinforce this fact that We had found through working on number Probably dozens and dozens of different web applications that the developer workflow goes very much like this You want to see kind of in an abstract way what the application will look like So you typically want to have some kind of an HTML mock up a wireframe or even maybe concrete HTML designs For the application at hand that you want to code Now of course all of that will be pretty much lifeless There won't be any kind of interactivity because the application hasn't been written yet But then you start taking that and treating that as a template and marking certain areas of the template Maybe you define inner templates within those templates you actually Define placeholders where things will be served and injected And then you start writing the application logic so this requires Millions or thousands or hundreds of Recompilation steps So we had realized this early on that It would be very beneficial to be able to load Changes to the markup without actually requiring recompilation of the application And this is what basically HTML templating via type providers Gets us in a couple slides down the road. I will have a couple examples So just keep in mind that instead of like what we do here in lining the h1 or writing in code HTML combinators we actually would recommend you to use outside external templates For this presentation layer A couple more advanced Examples, so this is exactly the same kind of application Skeleton here we defined an endpoint type with two discriminated unions And we had at with using attributes like the endpoint attribute here We could refine what happens with these endpoints So we basically here just refine that they should be accessible at slash Which is the root of the application or slash weather Which would be another endpoint and then as you can see whether in this case takes a string argument So down in the main we have application dot multi page now, which will be a standard Application client server application So here what we see is we basically can just pattern match On the discriminated union endpoint type To see what kind of request came in and all of the work involved in parsing the request Down to converting into this endpoint type and then matching on it to see what we should return All of that work is automated and we don't have to worry about it. Now. Obviously, there's a lot of details That should be mentioned here about refining these endpoints. What if I want to have a post a get or A delete HTTP verb What if I want to post like a JSON object from which I want to extract certain things? What if I have form data that I want to get the data from Post it to some of these endpoints you can do all of that And then once you have in the pattern match The actual f sharp representation of the endpoint like in this case one of the discriminated union shapes Then you can respond for example, if somebody requested the home page Then we return the home page, which would probably be some kind of a template based html response incase of a weather we get as an argument or parameter and then we as you Can see here just in case You can do on this version So that's a typo But in in case of form data, for example, we are expecting to pass the name and the h component as form data coming from our Form tags in html or in the third example, we are trying to get a json representation in one order Which in this case would follow the structure defined by the type or the data below So you would have an item and a quantity Now obviously this could be made into a list and more and composing it into larger data structures You can pretty much do that without limitation. Now, obviously at some point you're going to find that Coding everything into json and posting to the endpoint is is the fastest way to ship large amounts of data or varied data into service endpoints or or Yeah, service endpoints And to produce some kind of an output you can use the site template that was just given in the previous page like here depending on your endpoints returning json or files or Maybe error code if you if you want to have some kind of redirection or signal some kind of an error Or the actual html content like home page does I should also talk a little bit about reactivity Although in this talk, we're going to use mv u the model view of the pattern so here reactivity in webshopper is Is supplied by the functionality from webshopper ui the library so in Pretty much any one of my applications webshopper applications that I recently worked on Basically, I had webshopper of course as a core dependency And the second core dependency was webshopper that's ui So it's kind of like a ubiquitous Reference or dependency that I have in my occasions. Now, obviously some people are different, but I'm pretty much I could almost almost certainly say that webshopper that ui is the primary means of producing html and the reactive html applications with webshopper It's not the only one you can make your own html representation if you want it And we will actually see with Bola role how you can change the html representation within the within the framework So you could actually execute that pretty much the same way in webshopper. Just supply another html library using just a reference a library reference and keep using that but a lot of the Convenience code and helper functions like for cyclists, for example or geared Towards using webshopper ui Elements or docs as we have here So anyhow, I think it's time that I show some actual code running. So in the bottom I have some links some try to Open the first one. So this should be the first one to kind of demonstrate to you how you can do a reactive Computation so the idea here is very simple I want to type something here As I can see I'm going to echo something underneath and what I'm echoing is what's written in the actual text box And I map it to uppercase And I basically convert it back to a text view Which view in this case means the actual snapshot of a reactive variable like var Which here is bound to the input control. So actually I should get capitalized or uppercase Version of what I'm typing into the box, which is exactly what happens All right, so it looks pretty simple pretty painless Um, let me see this other one here. So this kind of goes against the idea of Not using inline html, but remember this is a website where we have Snippets although there is a markup tab and I could have actually used html templating and then just inject it Using the type provider that would have saved me all of this code But it's it's okay. It's a long it's a Small short example anyhow. So what this is doing is there's an input box. Hello And then we are basically mapping what's typed into that input box two different things Capitalized reversed we've counted words. So you can see that now you're changing So once I have a hello world, you can see that how things change And here the mouse coordinates is a view of course all of these views are assembled into a table And they are basically output here using this list of map basically we map each of those key value pairs into Just the docs html snippets and we concatenate them and put them into a t body And then in the main content, which is basically have the input field and then we have this output table Which is this guy here So within that, of course, we see this last one the mouse coordinates coming from this view mouse coordinates view Which here is basically instead of just mapping the input like all of these other ones do It's actually mapping a an external input which coming comes from the mouse So here if i'm on the application itself I can always access where my mouse sits and we basically just get the x and y coordinates And then we just output them as a Little string and then we just show that but you can see it's pretty pretty fast That there are a couple other snippets like drawing for example on a canvas that you can see here on try web sharper in fact Sorry I want to show that but then I realize it's there's so many examples and snippets here that it's difficult So Let's switch back to the slide here if you are more interested if you are if you want to Kind of understand what's happening underneath like these how these reactive variables and their views and how they are projected out into reactive html if you're interested in that there's a paper on the Awesome webshopper list, which is a community repo Uh, that we have linking some of the material on webshopper. So there's a documentation Oh, no, actually there's a publication section on that awesome webshopper list, which is also available by the way if you go to the main webshopper website so you can go into The main webshopper website. So we were on this try online Section we can also have blogs forums support documentation, etc. And what I'm talking about is this link here awesome webshopper This has an academic publication site and basically you can read this paper or Any one of the papers really talking about The actual reactive foundation underneath and some pragmatic applied topics on top for example piglets reactive forms These are pluggable view models very interesting things. As you can see they are kind of uh I wouldn't say outdated. They're definitely not outdated. They are still state of the art But they have been around for eight ten years. So a lot of this has been out Hasn't really been picked up that much I would hope that some of these ideas will come to more attention and people will learn about them All right So this is what we saw. Okay, now let's talk about templating So if you haven't seen webshopper or maybe just in the browser sense fsharp before You probably need some explanation on this type line. So type my template equals and then this Code here. This is actually an invocation of a type provider So what's happening here is that we take the webshop.html file We traverse it based on the type provider's logic and we are looking for certain placeholders And then we create types Which may or may not have other inner code entities Like members or properties, etc, etc Here my templates will become a whole space of types like a type space And in it there there must be We are not showing the html file source here, but within it I can see that there is a main Sort of inner template Which also has like title shopping cart items to buy as placeholders So those are the places where I can inject content the title here is a string placeholder Shopping cart is probably a dumnode placeholder where I can actually inject html And then the sent order is probably an event handler probably an unclick event on a button like a send order button Which on the UI makes it possible that I'm just basically whatever I have accumulated in my shopping cart I want to send it as my final order so it then Can be sent to the server for processing So this is pretty much how the application From an initial coding standpoint would look like and remember in the in the beginning of the talk We said that you you want to have some kind of a concrete or abstract or wireframe design So that's encapsulated in your webshop.html And then defining the proper placeholders event handlers You can actually put the code for them in a in a code very similar to this So this is how you would then externalize everything that has to do with the presentation layer At this point if I compile my application and I go and make changes in the webshop html file Then the application doesn't have to be recompiled it just automatically gets all those changes Now, obviously this is a behavior that you might want to alter So you can actually pass arguments to the templating type provider to say hey watch the source files for changes and only Load if there is a change Or you may actually say I don't want any changes to propagate I may actually change the file, but I don't want the application to reload Uh, so you can you can kind of gravitate in between those Uh, typically the the right choice is in maybe some production environments Disable the watch or the monitoring. Maybe you want to still have it on it's up to you Uh, so definitely, uh, there's some interesting Uh scenarios for you to try this of course applies to not only server side, but also client side templating So the same very cold could be applied in a html page Where you have a just basically a shopping cart Entirely running on the client side So if you make changes now, obviously when things are down on the client and executing in somebody's browser It's difficult to change the source template Because you no longer have access to it, but um If you refresh the page or whatever then the change could be applied All right, um So all of this templating can also facilitate reactivity So within your templates here what I have is a highlight of like these five lines I don't know if you can actually see them But here there there is the index template, which is the whole type space Coming from the type provider Inside is a list item template Which has you know basic things like some placeholders. There's an event handler for clearing and and so on But what what I can I can do here is I can I can connect things Into the model that I may have Serving This particular page so the data stored within the page Can also be reactive bound to the template and in this case task dot name for example is an example of that So we have a list model Tasks Which is defined above you can see that this model that's created in line 18 This is just basically a dictionary or a list of task values and You may have one or you may have zero or you may have a hundred of these tasks inside that model And what we're doing here is we're loading a template Which is just basically the design how things should be displayed. We are applying that to every one of these items So if my tasks changes programmatically or from the ui then things automatically Refresh now we could spend probably two hours explaining how the diffing works So similar flame frameworks Like for example react they have different ways to deal with this problem some of the ui foundations have representations for Basically virtual DOM and then they have Changes that are To be applied on top of what we can see on the screen And then these changes can be basically Unpicked and identified exactly where they happen And then the code that updates based on our change set is actually quite efficient. So we apply the diff Between two DOMs onto the existing one and then we arrive at the second Version of the tree. So this way we minimize The number of operations to sort of sync ui changes But everything else that didn't need to change remains the same Now, obviously this is a this can be a heavy computation An inexpensive computation if you're dumb, which is the thing that you represent For your document is large So most of the cases, you know web web application designers This guideline not to have too much scrolling within a page But you can also imagine situations where things are just basically not visible Like you may have an SPA which has a lot of functionality on two or three different pages But only one of the pages are shown at any given time But that doesn't mean that you're dumb doesn't have the rest of the pages So in reality it's very easy to run into situations where you're working with Thousands tens of thousands of DOM nodes within your tree. Now, obviously if you do dumb diffing That can actually slow things down quite a bit So webshopper doesn't do dumb diffing it uses Sort of like a data flow algorithm to propagate changes and then we have reactive Basically Things that allow you to expose the changes in reactive state into And reflect those changes into a html And this will be an example of those UI designs Coming from a template, but also having the ability to be connected into this reactive framework All right, that's uh, that's all I wanted to say about webshopper. So There are many talks huge amounts of documentation about webshopper on the on the internet Now let's switch to bolero, which is the other Topic of interest so bolero basically runs on blazor We'll talk about blazor in a second and it gives you the ability to program these blazor applications in fsharp Using the mv u pattern. So mv u is the model view update and bolero itself comes with a lot of webshopper inspired features for example endpoints, uh, so type representing, uh endpoints possible endpoints into your application then From this you can imply that uh, there's this whole topic of routing how you route Things between the different sections of your of your application The same kind of html template and more for example We saw inline html and we sort of advised against using too much of it and instead just Referring you to use html templates in bolero the same applies But in case you want the inline html there is now an alternative proposal for its syntax This is using computation expressions So it would look something like this the One of the biggest biggest benefits of of having an alternative Syntax for html and in this case the one using competition expressions is because of recent innovations in the stock compiler The ability to extend inlining in certain situations It turns out that you can reduce something like this into very efficient chain of function calls Which then if you execute would be a lot less work and also a lot less memory consumption Then having an actual data value representation of the html which you accumulate With your html combinators, which then you print into html at the end Somewhere in the pipeline. So this actually this alternate syntax involves a pretty heavy dose of optimization and performance benefits in most of the scenarios now, obviously This wouldn't deal with the scenario where you need to inspect or introspect the content of the html that you may have assembled Elsewhere and you need to change it in in certain places. So it doesn't have introspection abilities Because at this point everything is just a whole chain of function calls But you very typically don't need that kind of introspection And all you need is just being able to declaratively Write out what kind of html you want and here's the structure Etc etc So anyhow, you can track the progress of that. So that's pretty much ready To be released and it should probably be out soon. You can see on the bottom. There's a link for the github issue Okay, uh, i'm not going to talk about templates again because this is exactly the same Uh capability that we saw earlier with webshopper Uh, I just want to This was supposed to be a video Okay, here's a video. So this is uh, just shows you the power of the uh templating engine So here I have a running application and you can go out and basically change the underlying template And in this case we turn a button into a link just by uh Changing that uh inner template and saving it and as soon as we save that you see on the right hand side The buttons have switched to a hyperlink instead No recompilation to place in the server side It's just a simple file system watch And then sending a notification to the client to refresh all of that is uh uh Sort of included better is included in in uh in in the library when you use bolero Of course, obviously you can disable This hot load in hot reload functionality. I'll show you in some of the code snippets coming up where you can actually do that Okay, remoting of course is one of the fundamental pieces that you need to do in a Web framework or a web library obviously web shopper has and also bolero has Not a number but several or two or three different approaches to get remoting expressed Here's one way you can define sort of a record for your service type. So basically listing the rpc functions you want to have You can basically define this Record type and you can inject it using the remote member on the program component which represents an mbu Based application in bolero and then once you have that injected in this case as back end Then you can pass it down onto your update function And then the update function using that back end reference can make the appropriate calls on different messages as it receives them There are other ways you can do dependency injection etc etc You can basically read that in the documentation It's not that important which flavor you decide Now web shopper traditionally, for example, have used a third approach Where we just basically go through the f-shop code and we mark Using the rpc attribute certain functions that then suddenly become available for rpc calls And the compiler makes sure that if you're translating f-shop code to javascript Then calls a function that all of those functions are either placed on the javascript side Or they better be marked as rpc and sit on on a server somewhere So that's all checked and taken care of by the compiler itself Now routing Here's an example you typically So you have an endpoint type For your pages and then in your model in the state of your application You want to basically track which page you are on So here obviously in the model there's a page component and then also somewhere in your messages You need to define. Hey, here's a message that sets a new page Which basically means move to a different page of the application And then router.infer in the bottom takes care of all the work involved Okay, we have 10 minutes. So I'm going to just rush through this I mentioned how you can turn on Hot reloading for templates here the highlighted line the very last one basically adds a router Similarly, there will be program dot and then Use hot reload etc. So there's a whole bunch of capabilities in that module All right So just to briefly compare bolero versus webshopper You pretty much on the ui paradigm you stick with mbu and bolero on webshopper You have mbu, but you have a lot of different approaches based on the reactivity framework that we provide But the full stack aspect that when you have a bolero application Of course, we haven't talked about the different hosting models for blazer But on bolero, you typically have the client Running as a dotnet application On a web assembly runtime. So this is the blazor web assembly Approach but with webshopper we take the same dotnet called the translated to javascript and then that runs on the client Okay So why would you use blazor? So this is not a talk on that because this is just one of the fundamental pieces that we can rely on But basically it allows you to move away from javascript to dotnet for your client site code, which also brings a large part of the dotnet ecosystem to the client Because it actually can run in a web assembly interpreted Dotnet runtime You may actually have a pretty good performance compared to javascript, but you definitely have a better reliability and security guarantees because of the web assembly runtime and just running web assembly in a contained manner And also better code sharing. Of course, you have between your dotnet source server and client language parts So here are the three different blazor hosting models. You can have the web assembly, which I just explained The server model is a very interesting model where everything is running on the server and we just basically send Dom changes using signal R back to the client. This is computationally and resource Usage wise very heavy as you have more and more users accessing your website So this is not something that you should use on a large scale, but this would be very very perfect for Just small-scale testing of your application before you roll it out There's a new hybrid approach where you can build native applications And you have a web view that basically is running on top of blazor. You can read more about these hosting models on the link below Now here's an mbu model view update application We've already seen how you communicate using messages and change and update the model that you have using the update function and then here's the view typically in blazer or Sorry, bolero and webshop applications. You use html templating. You set up certain things and then from some of these dispatch events Like here decrement and increment will be buttons to increment the counter And value is the thing that you see as the current value. You can see that on a setter you also dispatch a message And this would be the source html template for for for that View function And this is what it would look like Really what I wanted to discuss is the to-do mbc app This is an application that basically almost 99% the same in webshopper and in bolero You have a couple things that you can change To go in between the two Of course, obviously you need to swap out the dependencies instead of relying on webshopper You need to change them to bolero and then you can take the very same f sharp code or most of mostly the same f sharp code And then suddenly instead of targeting javascript for your client Using webshopper. You now had switched your application to targeting or Running in a web assembly runtime so You can learn about this in the sample project Of course in the github repo the github link that I showed in the bottom There's one bit of information that I should highlight here that if you do use the webshopper mvu Approach so basically stick you stick with generating javascript You will find that from the traditional model view update the render function somewhat there Deviates because it takes not the model, but the view of the model This is a small and fine detail that I think is kind of under appreciated at this moment It basically just means that instead of having access to the raw model so that you can change it You can't so this makes it the model And and and and appreciates that the model is not changeable in the render function Obviously, it's not changeable in the mvu because you you're passing the model as a value But this is just a subtle distinction and just a small difference that you Need to be aware of Other than that, there's a website for mvu. I'll just show you that I think If I can switch over So in these So here's mvu itself you can learn about the architecture Some of the features like time travel debugging. This is not something this up to date So there's a security warning because the plugin used for the time travel debugging is actually Getting outdated and have some warnings you can Use local storage html templating. There's a paging mechanism coming with webshopper mvu So here's the routing and then the differences that I was talking about And then some of the applications some sample repositories that you can learn from All right And just finally Before we kind of close Here is a mvu Somewhat slightly larger example where we use components in other components. So this is like a scalability topic here This actually defines a counter like we have seen but also puts multiple of these counters on a single page And you can see how we compose messages into each other to sort of have this subsumption into A larger component All right I think There are a couple of things that I Just kind of rushed over And before I close I really should mention Blazor a aot which is the ahead of time compilation. So basically having the same ability that we have seen But compiling down not to Dot net d allows but to web assembly directly now Obviously the output size is going to be larger But it's definitely going to be faster than the interpreted Uh Approach with blazor web assembly. So this is something that we need to pay very close attention to I think it has a lot of potential Because this is now saying that you can take any dot net language F sharp c sharp whatnot and compile it down directly to web assembly Now this also means that you can interrupt with a huge and growing web assembly ecosystem coming from your dot net application code base Now obviously, uh, at this point we have to say and point out that web assembly still lacks access to certain features For example to the dom itself So we are falling back to using javascript for these But only for now. So a lot of people are anxiously waiting when uh, Web assembly is able to access the dom because at that point a lot of the javascript dependencies can go away Uh, and just closing down I really would like to mention and point out the rust community and all the work that they have been doing on web assembly They have this wonderful Ecosystem, uh, they can compile to web assembly very efficiently They also have tooling for example to take javascript libraries and javascript code in general and provide bindings To those javascript code Pieces by generating stubs that you can then use in your application that you compile to web assembly. So it's Really a cool approach. And I think it's a wonderful way to build applications Now, obviously, this is exactly the same kind of situation that dot net would arrive in once we have the aot compilation refined producing small that could eliminate it And optimized code and hopefully we'll get there or at least get somewhat closer in dot net seven Thank you very much for your attention I'm gonna be hanging out in the lounge To answer any questions you may have and otherwise have a good day. Thank you very much Thank you granite. Uh, thank you everyone for hanging around and listening to granite