 My name is Will Freeman. I'm going to be talking about how to write a fairly functional web app to use in reaction to JavaScript. So, hello. My name is Will Freeman. You can find me on Twitter at tf3.org. You can get that as well. Just a little bit of a background about me. I originally started as a C-sharp and Java developer. I moved into Haskell slowly over a few years. The past few years, I've been writing TypeScript. That's a medical time company. Joey Tomlin based in the Lighting Club, Lasers. TypeScript was actually my motivation for writing JavaScript. TypeScript was a massive group of Java JavaScript that used enjoying static types. But I found that there was a small number of cases where I was... I wanted a little bit more with the type just not good, but it was a little bit more information about the programs I was writing. So, I started working on JavaScript. The bit of what libraries that I've developed in the JavaScript community has grown pretty quickly. And I think that's largely because due to its simple app advice, the foreign functions phase, which lets you talk to JavaScript libraries. So, today I'm going to be talking about a library called JavaScript Thermite, which uses the app advice to talk to the React JavaScript library, which is a UR library in JavaScript where we particularly go to JavaScript because they emphasize the idea of using pure functions. So, I was originally a lot of JavaScript Thermite. You might not forget how I'm on my GitHub repository list. And also, a library called PeerScript Halogen. It's another UR library to JavaScript. So, these two in a way demonstrate two very different approaches to writing applications. In PeerScript, even though they try to achieve the same goal, they believe writing UR is. So, PeerScript Halogen is more about seeing how you can push the password influences of PeerScript and really using the type system to really give us a lot of confidence in our programs. And, PeerScript Thermite is more about, you know, using the app, basically, we're almost just trying to sort of get, you know, just a minimal amount of benefit from the type system, just adding the type state onto an existing library like React. Okay, I just want to go through a quick checklist, make sure everybody has everything that's needed for the workshop, the five things. So, everybody wants to get PeerScript Compiler and the folder to do so. Great. Oh, did anyone know? It's out of the season, which is the idea. Okay. Did everybody mind to clone the Rochup repository from PeerScript? No? Okay. So, if you go to my GitHub repository, it's kf313m.1.0. It comes to 2015. Basically, just clone this, and if you already cloned it, I actually pushed some changes for the reason that you can try and basically get it as well. And there's instructions for attendees, mostly telling you how to install the tools that we need. But you'll need to run the compiler on three directories, sort of warm-up, client and server. And there's instructions in the previews, so you can start with that. Okay, so the third thing is, once you have done the repo, basically you need to make sure you can compile it. You can also actually close three code sections there in the shell. I do expect the talk, but I expect a certain amount of familiarity with Haskell or the other PeerScript, if you know it, if you go on Traskell, what's just fine. I'm not going to be using a lot of advanced concepts, but it would be, sort of, seen from Haskell as well. And if you haven't seen Haskell, I think, sort of, in that family like ML, it's also good. And then the final thing is, you're going to need to test it in a terminal to edit the files and compile them. Okay. So please stop me at any time if there's any questions. I'm just going to check that. If you need resources during the talk, or perhaps those are the things I just said. Oh, we can use them. Oh, okay. I'll just check. Oh, I'll take the call. So the Thermite library documentation is probably one of the best places for the talk. It's one of the best resources for the talk. So, again, that's in my GitHub repository. Today, everyone is going through a type of Thermite. There's a couple of other libraries that I'll introduce in a little bit. And module documentation is just referring to the link from the main to the error module documentation. And that will give you all the types of all the names of the needs. The needs find is the type and function. The exercises, you can just start from the names. Generally, for looking up types of standard library codes in GeoScript, there's a website called Pursuit. And you can go that and type in the name and function. It should be used in all kind of documentation for that function. And then later, if you're interested in learning more about GeoScript, the best places to look are... There's a good IFC channel. On Frito, Pursuit's IFC channel. It's always pretty lively. There's a book. We should be able to read. There's a Google group who can ask questions as well. Okay. So the agenda I've got is that I need to get through four sections. I've written a fifth, so we can actually choose the last one. So I just think about... There's a lot of great sound things when we get to it, but we've chosen the last section of doing SVG graphics or type-taperizing. And then the other ones I'm going to do are very quick warm-up exercises to go over the basics. This section on the AJAX web service, et cetera, and a flexible validation with warm-up validation. We'll have a comprehensive rule. So each one of those is going to consist of a bunch of slides, and then I'll do a quick code demo and then we should exercise these to go with it. Okay. So I'm just going to quickly show you the project that's put together, the way it's going to work. We're going to add features to this existing project. I'm just going to quickly show you the whole process as well. So this is to get our repository just going. This is the master branch. So I changed it into a client directory. And we have to run the PULT build tool. So to just build the modules, we can say PULT build. And so you should have this installed in MKM module already. You should hopefully see it's all successful. We have all the dependencies installed. And then you can say to bundle everything up to the browser, you can say PULT browserify. And with the two arguments, send it to JS and AJAX. So that should bundle everything up before you send it to the browser. And then if I last do all the PULT in a new tab, I'm going to change the server there and do one level up. And here I'm just going to say PULT run. And so that's going to build a pure script web service. That's going to do the API for our AJAX calls. So here's the front end with the app we're going to work on. So it's a very simple programming language database app. So there's no database involved. You're just going to run essentially a pure script in every database and that's done for a bit. And then you can navigate through this thing either by selecting languages. So let's say you're just in Haskell. You can do information like the type language, the language description, the URL and links to the website. And then you can edit the language as well. So we're going to be form validation on this section of the application. Another thing we're going to implement is browsing. Because if you try and press the app button right now, it's going to work. It's going to implement a single-page application. So to get back to the beginning, you have to click on the title bar. We're going to implement writing too. If we go into that section, we're going to implement writing to table hash trace writing. Every language has a selection of type resources as well. So let's say I'm just in 2D languages. So if we find just a 2D language, I can show all the 2D languages in the database. So I can show this. This would be important if we go into the AJAX section. This would be more important if we go into the AJAX section, but you go to both calls, 9000 slash API. This is the JSON API that the service would provide for us. So most of the endpoints are actually linked, so you can just follow things. So if you want to see a list of languages, you can go to the AJAX line. If you want to see a passcode, you can go to the AJAI line passcode. So a couple of these are actually going to... Most of these are going to be defined in the code that you have. When we go into the AJAX section, we're going to add and do the AJAX handle for one of these endpoints that we don't have yet. So a little bit of a reaction if you're not familiar with it. React is a library by Facebook for creating UI applications and JavaScript. And it emphasizes this idea that the description of the DOM that we want to render is a function of the application state. So if you enter John's talk, just before mine, it was often the way of the idea that JavaScript and languages like that passcode functions don't have side effects. Every time you call a function, functions have a domain. That's where the body starts. Functions have a domain. That's where the function maps to. If you take a volume of the domain and run it through the function, you'll always get the same answer because the language is pure language. So JavaScript builds on this. And we don't say that... Instead of just saying that we want the UI to function the application state, we want the UI to be a pure function of the application state. So we're really using this software after-mode abstraction to pure functions to build up all the way up to entire applications. Another key idea in React is that DOM updates are not been directed. They're made implicit. So we give a description of the way we want the DOM to work. And then React is responsible for keeping what's currently on in the DOM versus what we want in the DOM, and only applying the name of that chain to make that case. Another library that takes this approach is called Virtual DOM. It's a little smaller. It implements the different batching components in React, but not the channels. So that's basically what we want to call it in the DOM library. It's an alternative way of working about this model. So first with Clermite, I said already it's a library that uses the forward function in space to wrap the React library. And in fact, we don't wrap all of React functionality, but we identify one particular use base, and we describe it using four different things. So an application is going to have a state type, so we are going to define and type it. Completely encompasses the state of our application appointment time. We're going to define an action type. So actions go into a new array of all the different ways in which the user can interact with our form, so maybe clicking on a button or changing a text box, and how that's going to affect the state. So we have a state type and an action type. We have a rendering function, which takes the state and turns it into a description of the DOM, which we can then pass to React to see what the data is on. And we have an event handler, which takes the combination of an existing state and an action that needs the strength of the form. And in terms of new states, all of the possibilities involved makes an agent request to interact with the outside world. But the primary responsibility of the event handler is to speak to the data states. Any questions on that? So Thermite comes with quite a few modules, and the first section here is what you're typically going to want to use. So Thermite, at the top level, gives you general functionality. The things in the HTML, some modules define the DSL for templating the DOM. Look at these DOM descriptions. The actions of module defines what's called the action owner. We'll get onto that, but basically allow users to do things like set a state, get a state, make agent calls. Thermite events is another part of HTML. DSL, which allows us to attach event handles to things like buttons and inputs. Basically wrapping things like on-click from HTML, from the DOM figure. And then the types module find all the types of these modules we're going to use. And then if we get onto the SVG chapter, there's also two modules, SVG and SVG attributes. That defines the DSL, just like we had the HTML for templating SVG documents. So you'll notice all of these are important qualifiers, which means that we're going to use the namespaces on the right instead of using the modules directly. So that's because, in some cases, we're going to use the namespaces and the polygons, and generally, importing these modules basically is going to bring a lot of things into scope, as it's usually happened to, and put them in the qualified. So here's the HTML document DSL that was talking about. So we're going to define a type of state that represents the state of our application. And in the example I'm going to work through, first of all, the only state is going to be whether or not a button is toggled on or off. So we're going to build just as if it were toggled off. So I use types in and then of state. Actually, sorry, that's the type of the second state is going to be if it should be a synonym for this record, which has an on field which has type value. And then the render function has a bunch of arguments, but the one we're interested in is the state. And that's going to return this HTML document. So the DOM representation of this state is this document, which consists of a container div. So you notice I use the hname space for elements. Give the element name. And then two arguments. I give a attribute set. So the only attribute I care about is the class name, which has actually a container used in the string. And then the second argument is the list of shallowns. So the container is going to contain h1 elements, which contains a text document. And the prime here indicates that I'm not interested in using attributes for this element. I just want the default set of attributes. And then the second element is that they're just going to be paragraph. And again, I don't want any attributes, but I do want the text on the inside. And the contents of the text is going to be on or off, depending on the pool. And if you're wondering how the attributes get combined, let's say I have two attributes, they actually get combined using the monotype class. So you could use this operator with the angle brackets to combine multiple attributes. So when we get on to that handlers, you'll see that we have a class name and an output handler that will combine those two using the angle bracket operator, which I'm going to name it mapM. As I said, childL when it's specified in grade, just like that. Is that all for it? OK. So account handlers look just like attributes. Then you've got this type of context, which if you're familiar with React, basically wraps up the thing that we have available at this parameter, for this argument, to React. So it's going to basically allow it to dispatch events to React itself. So when we want to add an onClick handle, we provide a context. And it's parameterized by a few things, just to keep things type safe. So the state type and my action type that I decided on from application. And then I have to give it a function. So the second argument is a function here drawn in my event in case of onClick. So an action that we have a state in case of onClick. And then those two things that's on an attribute, which is an ATTR type, and I can attach that using just like I attached this part name on things. I did that. So just to compare that, I hope that there's all the great parts haven't changed from the previous example. The changes in order to have nonClick are then handled in a button. Or that's a defined action type. My action type just consists of one constructor, one of these constructs called toggle switch. This indicates that I want to change the representation of the change state to change the state of the button. Previously, I had to ignore this first argument. I had a wild card here. Now I'm going to find it to this name context. I'm going to use that in this onClick handle. So I create an element called button. I add this attribute called onClick and I pass the context to the first argument and the second argument was a function called ignoring and returns an action which is toggle switch. And instead I'm just going to put some text. I'm just going to say toggle. So we've defined our representation of the DOM given state and we've been able to attach it at handlers to the element of the DOM representation and now we need a way to have the state type interact with the action pattern. So in thermite that's implemented function. And again we have some type arguments to make these types in. But essentially what the form action is going to do is take the properties which I said for this demo we're not going to use but it's kind of in-react properties are not intended to state but for us we're just going to use the state to take the properties and then the action you want to invoke and sort of return a computation in the action model. As I said earlier the action model is going to do so let's get state set state and run casing in the actions. So here's an example if I want to hook up the total state action to button state my right list is form action function. We use that type as an intuitive type and note that the state and action type arguments became the type which is state action. And then I work by case analysis on the action I want to form in this case it's total state and I need to return an action in the action model. So we'll draw this when we get to the stage acts but there are some atomic actions defined in the library that work in the action model and one of them is modified state. So for the first exercise the only thing you would want to do is modify state and basically you give that a function from state to state and it's going to apply that function to the current state. So here I provide a function that takes with an HST to a new state in which the arm of the fly will be toggled to not arm. So now we have all the pieces that we need so we mentioned those four pieces the render function the form action function states and action types defined all those and we need to bundle them up into what we call a reactive component class so that we can actually render that model to your answer screen. So as I said component classes can be used to bundle our function house to reuse and in the spec is basically defined as a direct quality internally but we can construct one using the simple spec function and it takes those type arguments that we find states and action and it takes three arguments so we give it an initial state so the state we want our application to be in where we just loaded the application it takes the form action function so that was the thing that took our existing state and an action and so it took the action and it gave it the action to a bit of state and it takes a render function to take our state and produce something in the HTML templates in DSL and that returns the spec and then we pass our spec to this function called create class so this is the thing that's going to bundle all that functionality into a component so I create this component here we call it components in this left binding and then finally it may have to save render so we move that to node that essentially corresponds to the props argument that's already doing our examples we just want that empty props so this is the next record okay is that all clear are there any questions okay so I'm going to work through the code I just I just worked on the slides and why I've talked about and then there's going to be a quick break while you ask questions and walk with these exercises to be the command of the reading you should see a set of instructions based on some of the points there I'm going to go through the top an example that I'd like you to build an example where when you click the button you increment the counter so your stage your application is going to be to do value counter clicking the button is going to call it the increment seems like we're running the update so so I was told that the network was actually walking out so if you update the gate repository I actually checked the whole power dependency so if you update it should be a power component and then you just say whole threads reply to those so if I change the warmest directory so our source is in the source directory there's nothing to do the state and this application right now is nothing there's only one possible state and that's called state there are no actions that have been defined because there's no way for the user to interact with the application the initial stage is just the one saved the rendering function is just going to produce a static document which is going to be the list of instructions for the exercise the form action there's going to have no actions to be able to perform just basically ignore this argument and returns others that way I don't this should be ignore this and should say clearly to say we want to be absolutely nothing to do with that thing in this case and then I would say we need a simple spec to bundle up that functionality to take the initial state the action function the rendering function creates a spec and then in main we create a class from the spec and render it to the function so from the introductory talk to this and that God as far as explaining basically how to make a structure in a function so some of what is happening here is makes sense and some is a little confusing and I think the question I'd like to ask is could you briefly explain to the people who came here from the introductory class what does it do okay sure so the answer is probably more complicated than I can get into right now but I can give you a quick answer so it basically so the dookie word allows us to write what looks like imperative code and the particular line moves that you write some of that imperative code in depends on the particular monad that you're running this code in this case kscript defines and I think I don't know if you got into this in the introductory class but there's a special monad in kscript called f eff and it allows us to run native JavaScript code so it's primarily what we use for interacting with and good things like React in the end of time so for example here we're using it to just stack up at the by instructions one after another that we want to run it's a way of creating sort of sequences of instructions in general we can use it for more things here we're just going to use it for main and when we get on to the action monad we can use it to combine action computations too so quick quick question the monad that this do is going to be happening is that something that's specified here or is it something that your wrapper library is going to be feeding into main or something so the particular monad is implicit the particular monad we're using there is f and it's in the but do is overloaded so you can use it with different monad we'll use it here you won't have to change this code we'll use it here for the reactive integration and then moving on to the actions later on there'll be a way to use it to combine actions together as well quick question I'm sorry this is the way we think it will be who exactly specifies the ff I don't see it in the code here who specifies whether f or action oh okay I'm sorry the question was how exactly is the f specified and the person that's explained it's just off the top of the screen okay so it depends on which monad you're using so like I said we're going to use it to in the the form action case when we get on to it we're going to use the action monad here we use the f monad but in either case the one that we use is determined by type inference so I didn't give a I didn't give an annotation on the main function there but what the compiler is going to do is based on the bits and information it has to figure out that the main has type f or something and then it decides to use that meaning for it and the same thing will happen with action so you can do it if you have the NCI command running you can just use code on t or code on type and give it the expression that we type so really it's good practice to get type annotations on top of all the things I left it out there because it's implicit but usually I would I would actually start with so to build the one-point size I can just say fold build first fold it doesn't necessarily just make sure that things are building fold successfully so then I can say fold brazier five so then it says brazier by that means it's been compiled with brazier and I'm not going to index our HTML and this has taken up one state so it stays with the trivial here but it's taking the state and use that render function to turn that into a DOM template DOM description and then use React to render it on to the DOM so let's start making the changes so we can use a direct outside and use a label so the label I'll hold in with the label on actually if you follow me along with this you might like to use a different option brazier by just before the brazier by command just stick the dash on the that's going to run brazier by in watch mode so I'm going to change my file and just rebuild and just open the brazier so that way it's going to be that's about JS oh right sorry I haven't done anything that could really be reasonable so the action that we need is to build the table state so that's how I've constructed the initial state is now going to be a direct build it's going to have the DOM label and then my render action function which is why I'm also this but I'm going to change the action then to sort of the state that's a match a match upon I'm just going to use a variable binding just a binding state to the variable ST so I'm going to actually just remove all of this so inside my container I'm just going to create a button and now I don't need any attributes but I will accept them the only thing I care about is rendering the state so inside the variable child elements button I just want t.txt the text is going to be if the state is on let's come by and see if that's all working I'm going to write that and hopefully write the slides when it's kicking okay let's go that's it we go back here and refresh every half hour off button but it doesn't do anything so we need to do two things we need to press the button and we need to interpret the action inside the action handle is it all there at this time? yeah there's a question I'm just going to oh okay sorry I didn't realize who brought the phone along okay any questions? okay so I I want to add a backhand close to my button so I can do that by using the on-the-hand button so that's in the team module we've passed the concepts down here so that we can send events to react and that needs to provide an argument so sorry if function was taking my spend it could be an action and as I said before I don't care about the event body I only care about producing total state action so I'm interested in the mental balance just to make sure that compiles you've got a should that be changed up button rather than changed up button oh you're right thank you the prime means you don't care about you but now of course you do so we'll close again okay it does great and the last thing we need to do is implement this performance function so now I do care about a particular value that's been passed as an argument performance action there's only one case but let's just make it explicit so we match on that base constructed and then here I'm going to modify state function and I said that's going to take a function that takes a state and returns a new state so I said the old state ST and I can just return the rect of my new state to the on flag set to not ST. I recompile and then hopefully I click and toggle button so all of that so those four parts that we built we set it up to react and create class and then it's a job so you can those parts up on I think those actually that was a you were called back so it seems to yeah it's good okay okay so take a quick break anyway if anyone has questions I'll answer them otherwise you know feel free to just catch up with this although it's the other exercise if you want something else so I didn't see lots of the way the final difference so can you answer the question um so uh the question was um the record of the difference of the so um the does the most it was the difference you can uh record the uh um um um um um um um um um um um um um you can say elicited, nil or consul, okay, elicited. The difference is, let's say, in the way we talk to the rectals, you don't have to extract the function of the rectal notation directly to its construction. You can have a rectal type, and you can state the rectal type inside, so you can have an output. So I think that this gives, for example, I could also state the rectal type. Yes, but it would be an inside rectal type. So this is a type in its own right, in terms of what it has to come up with. Yeah, it's obvious. It's there. Barrel results are... Okay, so the network thing is preventing barrel bits. That's what we're talking about. But I added about a pen into the history book. Yeah. Yeah, so there's actually an issue. I guess if you get it slow... One way, then the way... Yeah, there is someone posted on Twitter if you give some command to change the URL so it's ever trying to access... Minus minus global... Yeah, I would try to do that. So I guess you can also make sure that it's in the... I think it's something about if you check out the whole thing... I think it depends on what URL you use to check out the thing from GitHub. And then you get both the global URL as either HTTPS or Git. And if it's one, then it doesn't work and if it's the other, then it doesn't. So I guess you can make the URL to use HTTPS and force that instead of using Git. And then it will... Off the back, can you check it and make it work? Yeah, make it work. Hey, I only have to do control this one. That's the list on that next row. Yeah, if there's anybody else to follow along at this point, there's no problem with that. I've got a compilation here that I'm not... Yeah, which is... It's a figure. It's fully in the same... Yeah, I got a figure. I got a figure. Yeah, I got a figure. So it's like the paradigm of the thermite but the state is local and it's component. So there's another... like another common pattern. It's like you have a single... Yeah, that's right. Yeah, like the only way I'm more familiar with it is that it's such a thing where the thermite is like... It definitely does. The way it works is you just have to come down and check out what's on it. When you react yourself... When you can't really react yourself to components or anything of that sort. So I'm not going to do that. Every time you're going to do one type of thing it's something that's... Definitely the problem you could run into is that it's a type of check-out. So if you want to wait for a couple of stations it depends if there are other ways of doing it. You don't have to do that. It's just to make it seem more than... There's nothing... I might put that down there. What I mean is like... I could... I guess you think there might be a long way to say it looks like we're doing something. I could show you. Or what I can do is... So... I'm sorry. Can we go over it? Yeah. Am I more all alone? Is there anything to talk to me about? Yeah. Are you testing an initial stage that you're going to put down in my... Fandaman? Yeah. Yeah. Are you standing there? Yeah. I'm in my third company... She makes the level of the... She says that... I'm in my sixth company... So I'm in the fifth company... That's good. You know, I see... I'm in the fifth company... That's good. So... We have, you know, over all of the things that we're doing. So, the more people we can relate to, the more decisions that we have to make. So, Josh, what he's talking about, he's talking about the importance of things that we're doing. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. So, there's a question about, in termite, we have this substantial model of how to describe the interface and at some point that has to get attention to, you know, to protect that interaction with the real world and it's not completely clear. I think that's happening. I thought that might be something other people wondering about as well, so I'll quickly go over that. So, the idea of termite and collagen and other models like this is that we want this, we want to take advantage of purity as much as we possibly can and to push the effects that, in this case, that involves modifying the dom, push the effects of the binary application in name. So, the goal of termite is to try and compressing the pure functions as much as we can. That's the idea of doing these four parts. Allogen takes a similar approach with some slightly different techniques. But you can think of the spec value here as a completely pure description of all the interactions that possibly happen in the application and then we push all of the effects into this render function. So, they happen throughout the edge of the application. Hope that makes sense. So, everything here, there's basically no unsafe operations happening in any of this. Apart from in render, render uses the F5 to go and take this pure specification into something that interacts with the real world. That's the long way we can go over this stuff again. So, can you just briefly explain, just I feel like I understand most of this except and just the one part about how, when you define the button name, you say up on the given context returns a random nothing and returns a toggle state something and then there's a perform action down there that kind of does the work of that and there's somehow glued together and I'm just missing a step there. So, all of the glue, so we have this good expression when I say all of the glue takes place in render. So, there's lots of wiring in render that so it takes that toggle state and pushes it three parts and then pushes that into the app. But it's explicitly, you know, that's supposed to, it's supposed to be everything in the work of that and we'll take a look at that. What are the underscores and the type signatures? All right, yeah, so let me explain that. So the question was what are the underscores and type signatures, so if you look in the middle of the screen, form action, that's the one that's pushing them. That's basically called the type one. It's called the type one file and it basically says to the compiler, I don't want to write this because I don't get the information I don't care about, but it's still made to it's right. So it's kind of like halfway between not putting the type signature at all and giving it form. Any other question? Is unit literally just a member of the unit kit? Yes, so I said we're not using rocks in any of these examples. Unit is a type, capital U, unit is a type with only one value so it has no information on content. Unit with a lot of issues is the only type at that time. So I'm just using unit here to say I don't care This is kind of an aside, but I went and explained what to look to see if I could add some information from the announcement to talk to the statement. I found that the announcement in their own events is just form and import. So when you have something like that, I'm going, how do I then find out what properties I can find by announcements and so forth? Yes, so right now events are treated completely opaquely. There's this kind of a difference between halogen, which is what I mentioned, and thermite. Halogen is kind of more I guess you've got industrial standard version of thermite. Thermite, something that would probably be used more for demonstration because it's a little small arts, but I never go around selling it. The F5 policy needs to actually go and get data out of events. So right now if I need, for example, value for the text change, I just use the F5 to go and get it. So right now they're completely opaquely but you can try to lie to me so people can say, the only reason it's not done right now is it's very difficult to be on type of cycle. Okay, let's carry on. So a bit constraint at times, I'm not going to work through the example. Hopefully it needs to be able to make some progress on that. Let's move on to the next bit. So the next part is going to start with the action model and an age action question. So you need to change back to the main directory and check out the like branch, so get check out the like and then just wipe out all the changes. And then we're going to go through those two steps. Now we're going to start using this application, pre-dot application. So let's go through those steps. We need to go into the server directory and do hold-run, run-server. And then we need to set up the browser reply again. I want to restart the watch on browser reply. And then go to localhost 9000 and hopefully you should see this. So let's take a quick pause. If anybody can't get that working, just I should say. What directory is this again? So the warm-up was just for the warm-up. So you can go out there. There's two directories you need. Is the server directory? In the server directory just maybe open two tabs and you turn them on or something. You can do hold-run and it's going to support my server on port 9000. So we'd rather take the other one. You need to do an npm install. I added that yesterday for the preview. So that's it then. If you do any npm install on the server, how do you fix the bloody person? Just run npm install in the server directory and it should hold n couple of modules. Basically it goes through a project running an express web server so you can express a couple of cool things. Let's get that running. Let's go back to the slides. Okay, let's operate the action model. So this was the piece we were missing really. This conceptual model. So we only used one comic action model. That was modified state but it actually requires a few more. In this section we're going to incorporate all the operations that the action model provides and then we're going to use a library called AppJax to make Ajax calls using another library called Kioskix app which allows you to structure these conversations. So you go into these, check out the live French like I just mentioned so I'll just check with my white boy. Okay, so very brief introduction to Kioskix app. If you came to the Kioskix on a yesterday John was talking about this library. This is a library that's been developed by Slamdata for using asynchronous conversations and structuring asynchronous conversations in Kioskix. So if you want to deal with asynchronous file item for example Kioskix or talk to a web server by Agax and Bresa we need to use, we need a vector we're talking about vector verbs, vector conversations that are asynchronous and that's what app does. The app type looks like this type on the right of this type of thing. So if you look right at the right says it returns f of e and a so there's two type arguments. The first type argument is the row of effects. So Kioskix has a notion of effects I think. So we can distinguish things like network effects from file effects and file effects from rising to the dawn. And then make sure that our main function we can put constraints on our main function by using the type thing to basically say things like this program never uses the dawn or this program never uses file item. So it gives us fine-grained control over all the effects that our program can have. So e can be thought of as representing a collection of effects that we want to form asynchronous. And in other words the details of how this is implemented because we don't need it for this talk. If you're interested you might like to look at the app library or the app library which is sort of the more basic synchronous version of the same thing. And the second type parameter a is the type of the return value of the thing we want to get in this conference. So in the case of file layout it holds a read and text from reader screen from text file and might have a computation of type a with the first type frame to be some set that contains the file layout effect and the second type would be a string meaning that I'm going to say synchronous to retrieve a string. So if you're familiar with things like promises from JavaScript then you know that we have similar things in JavaScript that allow us to generate synchronous computations and we need to have ways to compose them. So app provides a bunch of standard instances so it's a monad it's a bunch of quanta and it provides a bunch of combinators for building practical computations. So the basic one is what's that? So let's say we want to take a synchronous computation that's described by something type f ea that into a signal system to represent that as a signal system then we can use the left lift f function to take that computation into the app type. App also comes with built-in Arahant handling. So if you're familiar with promises again, John went over this in depth yesterday it's really interesting hopefully it'll slide to the bottom line but you talked about how Arahant linked with things like promises is difficult and so we wanted to build in Arahant and make that directly built into the app monad so there are various combinators that allow you to work with errors in the app monad so we could use this combinator at 10 for example. So that takes an asynchronous computation type r with these type arguments e and a so that's going to return an a eventually in 18 minutes. So this is an asynchronous computation an asynchronous computation but now the return type has changed into either Arah or a so that materializes the error so that our return value that actually gets back tells me whether my asynchronous computation failed with an error or succeeding in the beginning with an a back and there's a couple of other ways of dealing with errors. Another one is this throw error function so this is just explicitly the same application. Is that error type just a new type on the screen basically? It's actually a foreign type for the JavaScript error type so there's this group that's at the library which is just a lot of library defined as a error type so then there's a lot of other functions like the fetch function to give a bit of a taste of how errors look impact you can have functions like catch error that will allow you to recover from an error you can have ways of taking two computations and if the first one fails you carry out the second as an alternative so we've gone into this for the exercise that I was about to mention app defines an instance problem or another type of problem so I said before that Monad gives us a way to talk about sequential operations so I can have an Ajax service that loads the response using this from the web server and then when that is complete take that value and use it to determine another computation and then run that one and then the results of that might sequence these asynchronous computations using Monad's instance for app but in many cases you don't want to use you don't want sequential composition because you don't want to have good weight maybe I have two web services that completely depend on two results and you don't want to have each other in any way and there's no data dependencies that force me to retrieve one before the other so in that case we want to retrieve things in parallel and there's a new type graph that fall out of PAH which is not Monad because I said Monad is a sequential composition and PAH is a parallel composition so PAH provides an implicit one and it allows us to run the computation in parallel we can use the PAH constructor and the run PAH Eliminator function to go back and forward between parallel and sequential pieces of what's covered so here for example let's say I have a function of two arguments prepared page takes a list of languages and a list of tags now there's no reason why I have to wait for the languages to come back so I can send a lot in parallel so I can use PAH to wrap let's say Ajax.load languages and Ajax.load tags on type A to send a text in some return type I can use PAH to turn those into parallel computations then I can use the applicable instance to wonder those that run them in parallel and when they're both done I use this function to argument prepared page to determine the page state and then if I want to embed that whole combined parallel computation inside an app block again I just have to peel off the PAH constructor and I do that with run part so as I said parts, functions, takes us from sequential things into parallel things part and run part goes the other way take something that's parallel and embed it inside an app computation I don't want to go into detail with this but I think it's an important feature and it allows us to speed up some of the requests for the web services that we have and I've said some of them are self-executed exercises that people are interested in looking at it but the main exercise is you don't need it so so I mentioned this library app jacks this is another library by Spondata that allows us to build an Ajax API on top of the app library so after Ajax we find an Ajax effect and this is an argument about there's a row of effects so the effect we're interested in is Ajax or the network effects going into a web set and getting some information and it provides a low level wrapper for the XHR API but then it gives a very high level API as well so we can just say simple things like get so if the get function takes us straight into the URI which will return so this is all over using a type class but basically return some content from the web server the particular type the particular type is all loaded so here type reference returns that get wants a this tags object here's an example of combining the sequential app code with the parallel app code so let's say I want to have an endpoint API type that takes a list of all the types but it doesn't give them full information about all of them so I have a detail method of load type details so it's going to give me a full JSON object with all the information about the type let's say I want to combine those so that I get full information full JSON representation of every type that's listed in my details so the way I can do that is to combine sequential and parallel operations the first step the very first thing that I do and I can't do anything else before I've done it is to go and get all the types but then when I have the types each one of the requests to the type details called can be run in parallel so I use this parallel code combination to map the load type details action over the type of the stuff and then hopefully in part 4 it uses run part it brings us back into the app so it's just a quick example of the sort of thing you might write using a combination of app and part okay so those are very brief instructions to the app for the examples we're not going to be we're going to use the high-level API so we don't need to do a detail so let's talk about the action the operations to the action that we haven't seen yet so the first one that we saw was modified state so the type of that if we know the type argument says that we take the function from state to state so given the old state, give the new state that and that returns the computation of the action monad and you'll see that's the type safety we have to parameterize the action monad by the state type that we picked but the return type, the right-most type of argument in the regimen so that says that modified state doesn't give me some effect perhaps to go and modify the state and send it to react so that we can re-render the DOM the actual return value is uninteresting as you know so the two supplied variants of the state functions is get state so that just allows us to get the current state of the application so it doesn't take an argument but it returns an action an operation of the action monad and it returns and look at the last argument that returns a state so notice that the two type argument the state that we used to describe the action monad and return type are equal so this is an example of how we get type safety here and then set state is the opposite so given the new state it just wants to set the current application state to that value so modify state obviously could be implemented using the combination but state in fact is implemented that way in the library so the action monad also supports it's own variants of its English computations so the way we're going to use the Apple library is to actually use an adapter that takes an app computation because app computations have a nice composable model and to turn that into these qualities of these functions so any synchronous function described by type n can be set into an action an operation of the action monad so that states if I want to go out and maybe I want to trace something to the console for debugging purposes that's an action in the action monad and I can lift that up using sync to an action monad so that when I'm responding to an action to request a change of state using print line debugging you can do anything about the action monad supports more interesting version of it more interesting version is async so it's a little unfortunate that this has got up but we want to construct something in the action monad and to construct it we need to provide a function that asynchronous will determine the value of time and in JavaScript the idiomatic way to deal with these things is to use callbacks so if you look inside the parentheses on the first function argument you can think of that as a function which takes a callback and returns a synchronous a synchronous computation that kicks off asynchronous computations to get some results and when the data comes back asynchronously the computation can be responsible for passing the A house into the callback and that's all going to get packaged up inside the action monad so that might be too clear we don't the function that needs to be provided in the it's fine but I just wanted to give a brief overview of the API and then there's a combination of the async functions with the set state function so let's say we have a function that can take a callback and respond to state arguments then I can async and just take a state and just set that state instead of my computation any questions on anything? if they isn't clear that's okay because the code we need is actually much higher level so if these two concepts of async and we need to make them fit together we want to use that here are the two types of the two functions that we need to combine I just showed you the type of async which is the second one here so that's that thing that we need to provide a function that takes a callback and returns some initialization function and then we'll get an action and then there's a a combination of a function from the aft library called runaft and runaft says if you can give me an aft computation that is an asynchronous computation that will eventually take a callback or error async and you can give me two callbacks so I need an error handler so the error handler takes an error and returns an action and the success handler takes a value type A so on success the async is called the terms of value type A we'll pass that to the success handler and in that case I wouldn't need some code to run in that case in the F1 so if you can give me all those things then I can launch the aft computation and hook it up with the two callbacks and give you the initializer function in there so we need to glue these things together and ideally we want to construct something of type which takes an aft computation and returns an action computation and the code for that is actually just inside I'll go over the code in a second the code is inside the source UI HX not that as well so we've got these the code that I've been running the exercise that we're going to work through is going to take a copy so the exercise that we're going to work through is we're going to add an abstract call and you can do this just by copying pasting existing things so you hit this again so we want to implement a light button on for every language page so we want to make a post on this API and go over the code that we've modified you can basically do type we need to add an action called light it's a lighter language you're going to have to use the key that represents the language then we're going to have to attach the light button using the event handler for light action we should say that this is the action I want to invoke on the button then the final thing is we're going to use an interpret light inside the form action function so you can get a new case state let me just give a quick overview of the code okay so this is the first part it's very hard let's go over the UI module so the UI describes this is where we define our component class after the application let's go over the four pieces so the first piece is the state type and I said this was a single page application so basically what I've done is to represent each possible page and the application is a different state type so we have a home state the home page that you saw we have a list of tags and list of languages so the form is constructed by a line summary objects and a list of types then a list of types the next page is a language, we have this view line type and it takes a line object so a line object represents the full object that you get back from some of the websites you can view a tag as well so I don't need to type this line but now we don't need to edit the line driver but there's a edit line view page and then there's two other pages so we can view a state where we're still loading the service of a loading page and we can view a state where we're still loading this service so we can view an average page here's the action list so I need to be able to load each of these pages so when I click on a button I need to be able to say it goes to this particular page so for most of the pages I have a corresponding action I want to load a list I want to load a language the first one is to load the home page I want to load a language and it takes a key and a key is a private key for a language and it takes a piece of page it takes a tag for every key I want to load a new language page I want to load an edit language page and then there's another action which allows us to update the edit language page but we don't need that for this exercise that's going to be attached to the same language button so the initial space is going to be loading and when the application starts I'm going to run this load list action and that's going to go to the server it's going to use the same action it's going to load the data to the home page and call it a state function initially we're going to start loading then we have our render function and it's quite large because the application is quite large but for all the exercises you only need to make minor modifications to this individual piece and I'll show you where the pieces are so this is just the same ideas that we talked about before probably the simple examples but much more of it using things like the class name and on-click to set up some buttons and things so render delegates to a helpful function called render page so render's page has a particular page that we're interested in rendering and it constructs the bits of the download itself that renders that particular page in our single-page application so here's the code page for example you can see we've got header for the tags and then we render the tags we have a header for the languages we render the languages for some reason and then we render the edit languages here's the language detail page for the one similar things so in here this is important for the example we want to modify the rating button function to add the asynchronous click event to hold up that postman and then you tag the header one of the two other pages that we don't use for this and then again we just break these things down these five reasons are small ones, small functions small helpful functions there's something to render for language summaries and tags on the tags page the one we're interested in is the ratings button so you see there's a to-do here we said I've used a left binding to pull out this value light, which is the number of lights that I've already been number of times people have already clicked this button this particular language so ratings button states a language as it's argument when it turns that into a representation of the rating button to that language and the way it's represented is as a paragraph right now and the exercise is going to change that into a button and to hook that up to the postman let's get at the header one and here's the format so again everything's just like case analysis so it looks complicated but each case is actually very simple so let's go over the list so remember before action states an action that we want to perform it will be clicked the button and it has to represent something in the action format in the action format and eventually it has to set the state so we mentioned using do notations to sequence various actions and we used the left arrow to say first statement it says run the list lines command so that's going to go upwards of the API line endpoint and pull it out into this lines object then run when that returns run list tags to another agent pull it out into a type object then use that to construct the state type of the page then finally set state action to so set state has to take a state so we're going to construct the particular state based on the return value but based on this list data the type of the list data is going to be either an error or the page state and so we use the either function in the error case we return our error state page so that was the page that just showed the error and in the case of when we get successful page state we just use the identity function to just render that page state to the application and all of these just do very very similar things just involve using the helper function which I'll show you in a second it's helper module helper adepth module to get various bits of information in the same peninsula bring them back construct a new page state and just use that state to stick it into the application state basically the exercise is going to involve adding a new case of the format because we're going to start the action call of life and again we use simple spec just to turn all these four things into a specification and there's one more interesting thing here so I said that the initial state was going to be loaded React has this idea of a component lifecycle and we say that when the when the component is basically passed on the screen or if we get maybe when it's ready to be rendered on to the screen we get an event grace called component format and the way that's realized in Thermite is that we have this combination of the modified spec for attaching an action from our action list of actions to the component format of the event so we can say when the component makes we run the loadless action so we got from the loading state we got from the loading state the loadless action when I was in this conversation just to get that base in and finally put it on the page and then maybe it's exactly the same as before what is that hashtag sorry the hashtag oh right I'm sorry so if you're familiar with Haskell you've probably seen the dollup sign which is the exact location this is just the variance of that but in which the application is realized so you can think that I was taking the stat and applying this but because we applied the component format to the loadless action function to the loadless action is it perfect for you is it perfect for you I'm sorry which one are you component format oh that's in the thermal we don't need it for this example I'm just going to give you a larger application for example we'll take an extended break for a couple of things and if people are interested in working through this you can then after the break I'll work through this so you can see how it's done and I think at this point we're kind of behind in time so we can just take one of the remains we think that's done at the same time we can just go through it so here's the AJAX module so I said the AJAX module was responsible for taking this AJAX library and making it compatible with the action module so the low level API is this AJAX function so you don't have to understand the entire type of thing but it basically says if you give me an AJAX compensation this is a type sorry an AJAX request and this is something that's described in the AJAX module and I can give you an AJAX action that returns an A and AJAX action is defined as this type of name here which uses the action module and returns either a string which is an error message or the response that you wanted so basically AJAX is responsible for taking the AJAX request and turning it into an asynchronous compensation in the action module and when I went on that slide I said that the way we could make these things compatible was to use the function we had to make it compatible with Async from the action module from the app library and you can see that's done here so I said run path would require two callbacks and Async has to take something that would use a callback and pass the value to it so if you're interested this is the place where those two things can use together and if you're interested in constructing libraries for the real world action one of those conversations and you might like to have a look at this but we don't need it for the examples here are the websites I just called it's got the high level API exploited by this module so you see we built up this machinery but at the top level we have this very simple JSO for example it's just a rocket for this API line endpoint and the way we use it is to just pass it to the GET function which is this high level function of the AJAX library and that gives us an AJAX request and then we can pass that to our AJAX health function and that's going to give us something in the action moment which you remember the AJAX action I was sitting in for the action moment our return type is Langson Retype so to see what the Langson Retype has in it there's a rectangle to see what's in there you need to look into the UI types and then there's other things so we can list the types and we'll follow up with the same person you can call API type that gives you a list of all the types you can call getLang and that gives you the details of the language so Langson Retype is a primary key to that language and you can pass that as an argument to getLang it gives you a conversation which builds as you can get that language summary sorry it gets that language object you can pass it you can call plotLang so when we implement the edit form that takes a request on an API endpoint that takes a language as an argument which is going to be serializing stuff in the request one and it returns something called OK and OK is just basically a type I told you that says I don't have any response based on that I care about but I want to make sure that I got I want to make sure that I got a non error response from the server and that's constructed using a bit more of a low level part of the object library where we take this default request and we modify it by changing the method but change the URL and construct this API line slash the key URI we use content to take the serialized line that we want to put in the database and see that in the request one yeah, it's good and the final one is another get so if I have a tag then I can I call get type with that tag to get an age action if you want to run through the exercises for the section and then now or later the types are going to be in here of course we're going to do some types and then there's a couple of new types so we have the primary key for language that's just a string and we have the ok object which just said that I didn't pair with the response body but I need an ok from the server there are tag summaries so when you list all the tags you can get a list of tag summaries back tag summaries, a record or a new type around a record that just has a tag inside it the line summary a line summary has a key which is a key for language and the name of the language is called line and that has all of these things and it has the key, the name, the description the home page, the language the current language which is an incident so this is going to be something you want to use to exercise and that list of tags that go with that language and then there they would just define this for an instance so that we can actually serialize these things and deserialize them safely for whatever we want to use them as age action responses so the exercise is quite I'll work through the exercise after we get back from the couple of breaks but it's quite detailable that you can get through at least a couple of steps if not I'm going to ask you questions and we'll see, a couple of breaks let's just think five and break if people want the solutions for the exercises the four components that I was hoping to get through each have a branch for this a branch for solutions as well so you can just skip because it's becoming obvious that a lot of people don't have the pierce groups or something like that so I think it's going to turn into more of a demonstration and watch out for those comments but let's just go through the solutions some of the more solutions that I came up with and then I'm going to one of the last sections I had was SPG graphics, I think it's a little more fun using React support first SPG to do interactive graphics so I'm just going to go through that at least for the last time now ok so if you check out the light open solution branch in the inner repository that contains a lot of solutions for the ratings piece so on the left you should see that when you reload the application there's a light button there and what I've done for the example languages is just to look at the number of languages of that particular language so let's say I click on light on Haskell page so it doesn't update because I haven't mentioned the logic so you've got data immediately inside the model state then if you refresh the page go back to Haskell so the database is just keeping the number of lights inside this language table so I'm just going to quickly go over all the changes that we needed to actually implement that so I said all the changes were going to be in either AJAX or UI can you actually maybe show us this just to see what it looks like so all the pieces are relatively small maybe the UI is the biggest change let's just go through it so I had this action set one of the four parts that we needed to make the layout was attached to the buttons and you see the first green line in the data just says I added a new action type that I want to be able to attach to the light button called light line and it takes the primary key for a sorry the primary key for a language but it's only out so then I can attach that to the button I need to render the button so this ratings button function here started out as the one that I decided to do and I changed it from a paragraph to a button so it's like HL button constructed to create a button element and you remember that the DOM DSL has two arguments for each element unless you provide the prime two arguments are the attributes that I want to attach to the element and the array of child elements inside so the attributes there's two attributes I'm interested in there's the class name for the button using the blue strap theme that I'm using so the class name I provide is blue strap CSS class name, button and button default and then I use that monode operator the diamond operator just to combine that with the second attribute which is an event handler it's an object handler so there I take the object handler and we said for event handler we're going to pass a context so that's our CTX thing that's been rolled up into scope it's got a little function renderer and then we pass a function that states the mouse event which again I'm ignoring it gives us an action that I want to perform the action I want to perform is this new lifeline a data constructor and we said that we need to provide the key and we just can pull that out of the line project that I showed you inside the task module so we can select the key property from the directory and we've got key there and then the child elements maybe I should have formatted this a little the child elements is just a single text element that contains the text like followed by the number of likes in grants so we're going to update the record itself in place when we click on the bottom so you don't really see the response you don't really see the updates or the number of likes I know there have been nice exercises but we'll see if we can put that in so further down the other change that we need to make is to add an action to the form action function it gives us a conversation about how we can use the objects library to construct things to conversations in the action format so we have a new case the action that we need to it's every node is like one and we bring the key into the patch matching we do notations a sequence of these actions so the first thing we do is to use the live function with the key to form an age action class using objects I'm going to show the implementation of life that's the method that I added into the age action module we can pull out a response out of the string or okay because I don't care about the response there's a response body from the live call so then I can case on the patch match on the response that I got it was either it was outside either string or okay so it's either left in which case it's an error and if it's an error you set state to set state to see the error picture and if it's not an error then I have to use the right constructor I don't really care about the response body because I just use that okay it's a constructor so in that case I use a wild call to match that I just want to know if it's successful which is indicated by right and then in that case I don't have to do anything it should return here basically so just end the action conversation without doing anything else so if you're interested in doing the additional exercise and trying to see the button in place returning to the thing after the place see what to do and then modify state there to just dig into the data structure and find the correct language rating and just increment that one okay and the other change was just that live function that I added to the HACS module so the purpose change is just to change the module x-forces so you see the module x-forces just I've got this comma like so x-forces of like function and then the body of the chain was these last two lines where basically I just copied and pasted things in get request the change to URI and change to get from get to request actually there is one slight difference you'll notice the get request don't have this unit on the end and the reason is that get doesn't support in the HACS line we get doesn't support the get function doesn't support the request body but we do support the request body in post in this case I don't use the request body so I use units to indicate that there's nothing interesting to put in there you could have also implemented this by copying since you're probably not familiar with that post method the way that was supported people was implemented would be to copy pipeline where we take the default request and modify it to use putts and the URL of the method they would just modify methods to post and you don't have to set the content because there's no request body so you would just set the URL of the method overriding the default request is that all is that all for the question manager for the last piece I think I have less than half an hour so yeah I have 13 minutes so I'm going to give a very very speedy overview of SPG support in the reactant so SPG graphics are supported by reactants as a way of reactants as a way of creating interactive vector graphics so just like we have this DSL for creating HTML elements we have similar DSL looks almost identical to creating vector graphics using SPG elements so if you're interested in having a look at the code you can have a look at the SPG branch and the finished code is in the SPG ok so SPG if you're not familiar is a market language that looks very similar to HTML except instead of creating HTML elements we create some shapes and text for rendering as vector graphics there's an SPG element in HTML about the same as the roots of an SPG object so you'll see just like we created 12 cents in DS we can create SPG objects in the same way ok so let's go through a couple of things that are supported you'll notice that the types the way we use things like rect here to create a rectangle is very very similar to the way we used for example button to create a button we gave a bunch of attributes separated by this monoid operator the diamond operator and we gave a second argument which was a list of child elements so in a lot of cases in SPG we don't have child elements it might be the case that we have group developments like the children's property but things like rectangles there's nothing inside, it's just a rectangle with attributes but here's the low level like how you might create a rectangle which directly corresponds to the document model for SPG so you would use the rect constructor for this as module for the rect function which is in past which is nearest for the SPG and the attributes give us a way of specifying the top left corner which is at some y, so here is 0,50 and width and height so the width is 100 and the height is 150 so this results in the rect angle of 0,50 with 1,50 we can render circles and ellipses so it's almost exactly the same the arch reach is a little different so in the case of a circle and an ellipse you want to specify the center point instead of the top left point but with the rect angle and instead of a width and height specify radius in the SPG document model that's the arch attribute so there is a circle of radius 50, center 120, after the ellipse we break up the radius into the X radius so the radius along the X axis I guess and then our Y which is the radius on the Y axis so you create text in the SPG there's actually a limitation in React which means that you would think that you would want to use the text function that we use on buttons to stick the text inside the child element but even in React that's an issue so the way you have to create way of the text that you want to render to a text element in SPG in React in the HTML function which is a little unfortunate what we might expect to color if it doesn't then we can create a work-brain if that might but other properties that we attach to text are the coordinates of the text or the text anchor, text and font font size which is just like we would use in CSS or 16px and the font family so they have issues coming down you can attach colors using the fillers row values like CSS properties and as I said usually you don't end up using the child element property of each of these functions but in the case of grouping you do want to do that and the reason you might want to group a bunch of elements is that SPG provides an ability to apply a linear transformation to an element it might be the case that you have a group of the group of elements that you want to scale together or translate together or reflect together so the way you would do that is to take to use this G function which supplies a group grouping together a circle and a text element and they use MMT which basically just means they don't want any attributes I just want the default attributes just like we have the prime and HTML DSL and the SPG but then instead of using MMT I have to do a bunch of transforms to take the circle text and text and scale them together okay there's a whole bunch more that I haven't used really I added SPG support a couple of weeks ago I haven't really had the chance to look through all of this and you have to be technically in reacts do all of the things that SPG can do and create gradients by using much of gradient styles and colors you can do clipping use all the transparency and a whole bunch more stuff and the nice thing is because we have this model with our application state and actions we can do things like animate the SPGs so we can interact with graphics and SPG elements also support things like click events so we can do things like picking in visual elements while they're coming to enable interactivity so we can do all of these when we're doing HTML application so I've just said in Boston that if your SPG library is open for grabs if anybody wants to wrap up this stuff in a more productive way right now it's very low level of these attributes just as a direct mapping to the DOM the SPG model I think to be really nice to have a pure data structure representation of an SPG diagram that would then turn into then use this low level interpretation to react to actually turn into a diagram I'm always interested in working on that ok so we're going to be demoing exercises for this section but I think I'm almost out of time so I'm just going to go over the solutions the goal of this section was going to be to use a new endpoint that I did in this branch called API Popular I was going to query the database all the languages are written pick the top five and give you a list of the top five most popular languages in the database and then render that as a bar chart using SPG so it set up the steps that we were going to go through so add a get wrap it using after acts and then load use that function to call the languages and modify that load list I was going to use that to load the app on the page and add those into the application and then the last thing was going to be to use the record function to embed this bar graph inside and using the SPG element if anybody is interested in working through these later I had some additional exercises too so one nice feature that I won't do is to add non click and go see if you can actually click on the bar in the bar graph on the page ok so I'll just run through the solution except for that this is in SPG type in the solution check that out you will need to restart the server just start that and do a pull round it will recompile render server so if you refresh now this SPG graph just shows us the top five most popular languages in our database like I said just based on GitHub racing right now but then for example I could go in there actually I could click on for example like on PureScript and the next time I log this page it should show up so it's reloaded from the website ok so let's do it again so I'm just going to go through the changes I've already done parts of the exercise there's not going to show a positive solution but you'll get the idea so except that we needed to add states to the home page to track hopefully so I've done that you can see the difference between the red and green lines you'll see that I've just added popular language array the array of popular language objects that I want to track those I have to modify render page because that data construct has changed I have to change my pattern map to render page in the home case to just bring that popular languages data structure into scope so I've called it popular so I removed the to do take the popular languages data structure and pass it to tell function so I've done that see the green line render popular languages and here's the modified render popular languages function so render popular languages takes a data structure of an array a popular language and returns something so I called the array lines and what I need to do is take all of those languages and find the one that has the maximum the maximum rating because that's going to define the width of my SVG on the most popular to be the widest and the most widest part so I've used a health function called maxRaisings that's the line data structure and find that number the maximum rating to the max value of the maximum and then I used this SVGL and it actually used to set the width and then I just used some popular functions from the arrays library and the scripts so this concats math function if you're familiar with basically that's going to take each language and it's going to apply a function a function is going to return an array of html elements for each one of those languages and it's going to flatten a little bit it's a full array of columns if you're familiar with flatmap it's from Scala I think it's a very responsive extension then again this has been cut off it's a little unfortunate but for every language I want to create two SVGL I use another health function called Widthub which takes a language and that max bounding width and it determines the width of the bar wi1 for that language and I also need to know the wide position of the bar and on the position of the language in the array so it's the position of the rankings so the most popular will be position equals 0 and the fifth most popular will be position equals 4 so then you just create two SVGL elements rectangle and text element so you've seen the scope before on the other slide I just applied the rex constructor sorry the rex function and provide all the attributes so I provide the top line for the x and y the width and the height which depend on so I use the the y and w variables that I've completed for the width and the position of the wide coordinate based on the ranking and then I use the colouring information from the colouring slides to use the build and stroke attributes just to set the colours and the text element is just the same so I have to just bump the text element along with my 10 pixels so it doesn't fly to the rectangle but has a 7.4 that's essentially and then the original example basically just gave a fixed diagram just for Haskell so I had one of that to use and save in the HTML to render the language name and that's essentially it the only difference should be here is a change to the form action handler just handle that just to pull in that popular language data from the web server and add that to the application saved from which the last piece was just that get popular method in the AJAX module that's going to go into an AJAX guest on AJAX popular just roughly that this AJAX is going to be the popular language array and that's it so you might like to try trying to compile this all change some of the colours some of the arrangements of the shape and that sort of thing or I think the extended exercises that you might like to try if you're in a line graph instead of a bar graph or that sort of thing yeah so if you're interested there's a bunch of material that it's all on the GitHub repo to work through and that's it just sit here yeah that's it if you're interested in any of the functions come and talk to me I'll pure script ISE on free codes that's a good place to ask questions that's it