 Okay. Alright, so I want to thank everyone for attending our September meeting of the Houston Functional Programming Group. And today, we have Rashad Gover, who is speaking about developing web, web apps in Haskell, and I will just turn it right over to you. Alright, am I good to go now? And I think I can share my screen, if that's fine, just to show my slides. Let me just share. Okay, can everybody see my screen now? Hopefully. And yeah, I'm on a Chromebook right now, unfortunately, so I don't know, things might be slow. Let's see. And can everybody hear me still? Okay, let me start the slideshow here. Yeah, so is everybody still able to see my screen? Yes. Yes, you can say it. Okay, just making sure because I can. Okay. Yeah, so my talk is on hypermedia driven web apps in Haskell. So that's what I'm going to be talking about today. I'm going to be introducing a JavaScript library called htmx and I'm just going to kind of talk about how it can be used to build highly interactive web apps without JavaScript. And obviously I'm going to be talking about how it's used in conjunction with Haskell. And just so I can get a kind of idea of the audience, like how many people here are familiar with Haskell, or is there anybody here that's used Haskell before or? Tiny amount here. Well, that's not too important. We have a lot of F sharp people. Yeah, so yeah, we're familiar with the basic ideas if even if we haven't used. Yeah, sounds good. Just asking just so I can, you know, get an idea of how deep I need to go into each topic. But yeah, let's get it started. So I'm a Haskell developer. I work at Master Word Services in Houston. They're a translation company. And I'm helping them build their in house ERP system, which is written in Haskell. They use the solid web framework. I've been there for about a year now. I've been using Haskell for about four years now. So yeah, I first encountered it about four years ago, and I've been using it pretty much ever since. I'm interested in mathematics and how it can be applied to the creation of software. And so if anybody else is interested in similar topics, please feel free to shoot me an email. It's right there and also I'll give that out at the end of the talk if anybody's interested. So that's me in a nutshell. So yeah, you know, web development in Haskell is quite great, I would say. We have various libraries, you know, that you would expect that you would, you know, that you would expect to use in web development. Things like for decoding, you know, Jason stuff for encrypting data decrypting data. We have various tools for generating HTML. So on and so forth. Haskell is also very performant when compared to other languages, which is obviously great that ends in a better user experience. Which is nice. There's also obviously, you know, when most people think of Haskell, they think about the powerful type system. So Haskell has all of that and that's great for, you know, modeling our domain. So whatever domain we're working in, we can use Haskell's type system to model it. And it also leads to easier refactoring in the long run. So if business requirements change, thanks to the type system, we're able to adapt, you know, without too much worry that we're going to break too much of our code. Also, you know, there's a lot of great frameworks for Haskell. So like I mentioned earlier at the company that I work for, we use the Assault web framework. That's a full stack web framework for basically server side rendered websites. There's also tools like servant, which is very popular in the Haskell community. And we also have, you know, Django like frameworks like IHP, which are pretty much batteries included and very approachable to even beginners. So, and there's a lot more than just these. These are just the ones that are the most popular. And yeah, even though Haskell, you know, Haskell is great, mostly for server side web programming. The thing that's lacking in the Haskell ecosystem is, you know, front end libraries. So libraries for doing front end programming, there are some and I'll talk about them in a moment. But compared to the alternatives out there, they're not, they're a lot more difficult to use. And so the barrier of entry to using these Haskell front end frameworks is a lot higher. And so, yeah, that's the main reason why I'm doing this talk is to kind of show an alternative to using some of those more complicated front end Haskell web frameworks. And so I'll kind of talk about those in a minute, but I wanted to show this, this is by Gabriella Gonzalez. She wrote a state of the Haskell ecosystem article and it kind of goes in, it kind of breaks down, you know, the various domains that Haskell is good in or not so good in and so on so forth. And so you can kind of look at this here and kind of see for server side web programming, you know, Haskell is considered pretty mature, which I would definitely agree with. You know, just based off of the reasons that I gave earlier in the previous slide. But for on the front end, things aren't as good. And I'll kind of explore some of those options that, you know, what, so I kind of want to explore as a Haskell developer, what are the options that you have for implementing the client of your web app. And so we'll kind of go into that. And so, yeah, so as a Haskell developer, obviously, well, let's just start with the most basic type of website that you can make, you can just do a server side rendered website or web app, where that's basically where you just render all the HTML on your server. And as I mentioned earlier Haskell has a lot of useful libraries for that. So that's the most basic but usually, you know, for most modern websites and web applications you want more, you know, interactivity. So and for that, people usually go to JavaScript. And so that's the first step. You can use vanilla plain just plain vanilla JavaScript to add a little bit of interactivity to your web app. Another place that a lot of Haskellers like to look when it comes to web development on the front end is, you know, these front end functional programming languages like Elm, PureScript, ReasonML. I'm sure a lot of us here have heard about it. I know in F sharp land, I forget the name of it, but they have something that compiles down to JavaScript. And F sharp support for that is very good as well. So these are alternatives. The downside of going to these though is that you lose. Well, as a Haskell developer, you're not using Haskell anymore, which can be kind of a downer, I would say, but it's not the end of the world. Same thing with a lot of these other SPA frameworks like react, views, built, so obviously those are also options, right? You can basically make turn your Haskell server into just a JSON API, and then just kind of have these front end frameworks kind of query the API. And then the front end framework will kind of do their thing on the front end. And each of these are different, obviously. So I don't have it on this list right here, but I should have had it. There's something called ghcjs in the Haskell ecosystem. But the downsides of ghcjs are that the tool chain to get it set up is very difficult, I would say. I mean, to get your developer machine set up to use ghcjs isn't really easy. To be fair, I haven't used it in a while. You know, the last time I brought this up to another Haskell developer, they kind of mentioned that things have gotten better with ghcjs. But it is a lot more difficult than I would say some of these other options on the list. So usually have to use nix and involve a lot of other things that just bring in a lot of complexity. But the upside of ghcjs, obviously, is that you get to use Haskell. So you can use Haskell full stack. You get to share all of your data types and all of that good stuff, which is nice. And then there's also, I think in the works, there's a Haskell to WebAssembly compiler. So that might be something in the future. You know, the last time I checked on the status of that project, it's not 100% there yet. And so, yeah, currently that's not really an option, but it may be in the future. And I also want to mention, you know, for some of these other front end functional programming languages like Elm, CureScript, ReasonML, so on and so forth. Haskell does provide helpers that kind of help you generate functions so you can query your Haskell API without having to implement all of those functions yourself. So I know for Elm, there's something called Elm Servant. And so if you write your back end using the Servant framework, you know, also allow you to generate functions, generate Elm code to query that API, that server. And so that does remove a lot of boilerplate and overhead, but it's still not Haskell, you know, as I said earlier. So let's see, yeah. So those are basically all the options that Haskell Developer has when it comes to doing client side programming on the web. But I do, in this talk, I'm proposing another alternative called HTMX. Let's see what that looks like really quick. And I'm actually going to exit out of these slides real quick and kind of show an example of the HTMX website. But before that, let me just talk a little bit about what HTMX is. So HTMX is basically an extension of HTML. And so it makes HTML more powerful. And it gives HTML capabilities such as you're able to submit Ajax requests from any HTMX element. I mean any HTML element. So you're not only limited to get in post requests using forms. Or just using anchor tags to link to another page, but you can actually turn any HTML element into an interactive element that can make requests to the server. And then your server returns HTML and HTMX will place that HTML into the DOM. So it's kind of hard to explain. I'll have to show examples in order for it to make sense. But the great thing about HTMX is that it's language agnostic, meaning you can use HTMX with any server side programming language as long as you can generate HTML, which I'm pretty sure all server side programming languages can do. You can use anything. Pascal, F sharp, APL, elixir, so on and so forth. Another thing is that it's very simple. There's no build pipeline. So another thing that I forgot to mention with, you know, a lot of these other alternatives like react to view on pure script, whatever else, you have to bring in a whole new a whole another tool chain for your client. And that obviously, like I said, with jchcjs, it brings in a lot of complexity and overhead that most of the time we'd like to avoid. So with HTMX you just put a script tag into your HTML and bam, it's right there. You don't have to do anything else. There's no build, no bundling, no npm. None of that. So that's great. It's also small, very tiny, especially compared to a lot of these other front end frameworks. That's another issue with jchcjs that I forgot to mention is that the code that jchcjs produces is kind of bloated. You know, when you're going from Haskell code to JavaScript code. It's not really an efficient conversion. And so, but that is something that may be improved upon in the future. But yeah, HTMX is just a lot smaller when you're comparing it with a lot of these other SPA frameworks. And yeah, it's a friendly community. It's growing fast. So I have this graph here kind of shows like how it's been taking off. I'm not sure if anybody's heard about it before this talk, you might have heard about it. I'm not sure. But yeah, it is getting pretty popular, I would say. And it is a very interesting alternative to things like React and stuff like that. And so actually, I kind of just want to show some a few things. Let's go to the HTMX website so I can kind of show you what this does actually. So go to some of the examples here. But yeah, and before I even go into any of these examples, I want to say that none of these use JavaScript. Now, HTMX itself is implemented in JavaScript. But, you know, as a user of HTMX, you won't have to deal with any JavaScript. And so you can create these really rich UI interactions without any JavaScript. This is all HTML. And so we can do things like edit stuff. And I'll be kind of showing a little bit of this in my own example. But and so you would submit this to the server and then you get a response. And the response that the server returns is HTML. So this is different from other SPA frameworks. Usually you return JSON, right? And then your SPA framework would take that JSON and then manipulate that accordingly. But with HTMX, we're returning HTML. And so the state of the application is actually encoded in the HTML. I'm going to go into that a little bit later, but that is the important thing to know. And so, yeah, we can kind of see this tool right here kind of shows what's being returned when a response is sent. So let me see if I click to edit. So actually right there when I click on this edit button, there's a form being returned by the server. And then HTMX is putting that form into the DOM. And so now I have a form that I can edit. And then when I go ahead and edit this, I don't know, whatever. And then we submit that. And then once again, when we hit that submit button and sending the form contents to the server, and then the server is returning more HTML back to the client. And now we have the new contents of the form right here. And there's some other things right here, just to kind of show around. Yeah, so this is an example of like a table. We can delete things, obviously. And as you can see, there's animations. And basically anything that you would expect and you know from the SPA framework you can do in HTMX as well, which is nice. This is a nice example of like lazy loading. Let's see. There was another example that I really liked. Okay, yeah, infinite scroll. This is another example. So you can add like this is lazily loading the list of contents. So on and so forth. And so that's how HTMX kind of works in a nutshell. But we'll, we'll dive into it more as we go on. So you've been here and asked a question. So I'm definitely is HTMX like, yeah, an HTML like like HTML like language, or yes, yeah, so I completely skip that. I'm sorry, so let's like let's actually see how we use it. So HTMX is used so you basically add these attributes to your HTML elements. And so that's what I meant earlier by when I said, you know, we can basically turn any HTML element in the DOM into an interactive thing that can interact with the server. And so like as an example here, this is a table row. And we're turning this we're making this table row. Make a get request to this URL. And this URL is returning more HTML back to the client. So yeah, HTMX is basically all attributes. So we have attributes like hx get hx trigger hx swap so on and so forth and there's a whole reference of these attributes right here. So you have basically attributes for every HTTP method so get post put delete. So on and so forth. So you have various modifiers you can trigger request on different events so HTMX is very event oriented. So you can, for example trigger a post request when the user hits the H key, or when the user right clicks, or basically anything you can imagine. I mean, that's within the limitations of the browser obviously. I think that JavaScript exposes you can listen to that. And you can trigger your HTML elements can trigger request to the server. And so that's kind of the idea behind that. Did I answer your question. Yes, that's basically how it's yeah it's all HTML attributes. So that's what makes it very, you know, easy and simple to use. Yeah, if you're so this is why I really came to like love it is just because you know I'm more of a back end heavy developer. And so it was great I mean as long as you know HTML, you can use HTML with no issue. Yeah, and so let's kind of look at this. And so, yeah, HTML actually really simplifies the whole web development process, I would say, you know, in 2004 I can't really speak for 2004 because I wasn't doing web development back then. But apparently, you know when I talked to a lot a lot of older web developers they say it was a lot simpler than. And, you know, part of that is because server side rendering was the big thing users didn't really expect like super interactive websites like most users today expect. And so I guess you know part of that is that expectations were just different back then, but slowly as the web as users, you know, wanted more and more, you know interactivity on the client. And developers had to adapt by using JavaScript and from that JavaScript frameworks evolved, and that's how we have react and a lot of these other. A lot of these other SPA framework so that's kind of the birth of the single page application, you know people wanted more responsive, more rich interactions with the client. And so that's kind of this 2019 stage, where it seems like there's a lot of complexity involved. But now with HTML, we're kind of back to this more simpler model, where our servers just rendering HTML. So we're not managing state in two places. So with a traditional SPA you have to manage state on the client side and also on the server. And the kind of goal with that type architecture is just getting everything to synchronize correctly. And things like that. And when you think about it is kind of weird. We're getting Jason from the server, and then we're, we're going to we're processing that Jason into HTML at the end of the day. And a lot of these SPA frameworks they use things like a virtual DOM. And yeah it just introduces a lot of layers to to the stack that aren't really necessary when you have something like HTMLX, because with HTMLX we're making requests to the server, and then the server returns more HTML. And then whatever HTML was returned that determines the actions that the user can take next. And so there's this really big idea here where the state of your application is encoded in the HTML itself. And so it's basically just you can kind of think of it like a state machine where an HTML page is like a new state and then that determines depending on what HTMLX attributes are on the page that kind of determines what actions the user can take next. And so we'll kind of showcase that in a bit. But yeah, I think that's kind of interesting. And so yeah we're kind of going back to this more older architecture I guess with server side rendering instead of an SPA. So what does this mean for web developers using Haskell. Well, it means a few good things we no longer need a separate tool chain to implement interactive front end so we kind of get rid of the need so you know as I mentioned earlier with, you know, a lot of the SPA frameworks like Elm, ReasonML, React, AccessVel, so on and so forth. You have to introduce a separate tool chain to, you know, build that system. And so that's more maintenance, more complexity. And now as a Haskell, if you're a Haskell backend developer, you can now just use 100% Haskell to implement your client as well. There's various, you know, libraries as I mentioned a few times already for generating HTML. And so that's all you need to use HTMLX. All we need to do is generate HTML and return it to the client when it's requested. And yeah, we can use all of the amazing server side libraries and frameworks that we know and love, which is great. So this is compatible with any Haskell framework. Like at my company, Master Word Services, we've introduced HTMLX and to our Yasod backend. So, yeah, it works great. It really fits in smoothly. So we still have other parts of the application that are still the more traditional SPA architecture. But yeah, HTMLX works just fine with it side by side. There's no issues. You just have to implement endpoints that return HTML instead of JSON. And so that's the main thing. And another great thing that I like is we get to use all of our types and everything. And so I guess it's, you know, we get a lot of the benefits that you would get from like, from using something like ghc.js where, you know, I'm sure some of us have heard of the term isomorphic web apps where we can share code on the front and the back end. Well, HTMLX allows us to do this with Haskell, which is great. Yeah. Okay. Let's build something with Haskell and HTMLX. And so, yeah, let's go ahead and do that. We'll dive a little bit into this. Unfortunately, the demo project that I brought along is kind of out of whack, but we'll kind of do a live coding session and we'll kind of discover with each other, you know, how to use this in conjunction with Haskell. And even people that aren't using Haskell, you know, you'll be able to apply this to whatever language you use because it's all very similar at the end of the day. So that's great. Yeah, so in this live coding session, I'm going to be using Lucid for generating HTML and generating the HTMLX attributes. And so we'll kind of see how that works. Lucid is a monadic DSL for generating HTML. I was going to use Relate for data persistence, but Postgres isn't currently working on my development server right now. So we're going to use something else, but I would recommend Relate. If you can use Postgres, I would recommend Relate. Relate is also another monadic DSL. And then we're going to also be using a library called Okapy for routing HTTP requests. So Okapy is a new framework that I've been working on. It was inspired by Giraffe. So I know there are some F-sharp developers out there. F-sharp is a Giraffe. I mean, Giraffe is an F-sharp web framework. So I was kind of inspired by the simplicity of Giraffe, and I wanted to implement something similar to that, but in Haskell. And so that's what Okapy is. And so we'll be using these three tools. We won't be using Relate, but we'll use something else to fill that gap. Yeah, and let's go along. Yeah, kind of as we kind of go through this live coding session, I just, you know, want everybody to keep this in mind that... So there's actually a term for this, you know, encoding your application state in the HTMLs. It's hatoas. It's not the best acronym. But yeah, that is hypermedia... It just rolls off the tongue. I know. Yeah, hypermedia as the engine of application state. And so this means that the state of the application is encoded in the hypermedia itself. The hypermedia return to the client determines the next set of possible actions that the user can take against the server. And so I just kind of, you know, put in some generic image of a state machine diagram here. But basically that's what this is. You can imagine each of these nodes is sort of like an HTML page. And the arrows going from one node to another, these edges are basically the HTML attributes so we can do like a HX get. And then we would move on, we would transition to the next HTML page depending on what the server returns to us. So the server is basically in controls determining based on what the user does. Okay, I'm going to present this next set of actions. And from the next node, we can go to another node, so on so forth. And so that's really the core idea behind all of this. Can I ask something? Yes, definitely. I don't know if this is the same thing because you're talking about hypermedia here. So I was looking at the htmx webpage and early on on the homepage, they say something about htmx completes HTML as a hypertext. But then they just link to the Wikipedia page and hypertext. And so I'm wondering they're obviously trying to say something about HTML is not fully hypertext. And does that matter? And what do they mean? Yeah, no, that's a great question. And this is something I'm still, you know, doing a research in the creator of htmx is very knowledgeable in this area, his name is Carson Gross. And, you know, he mentioned so the father of the sort of rest architecture and, you know, hypertext is Dr. Roy Fielding. And he was a big proponent of this idea of of Hadeloss. But yeah, as you said, and as Carson Gross has noted, HTML doesn't fully implement, you know, what hypermedia was meant to be. You know, that's because of the fact that, you know, in plain HTML five, the only way we can interact with the server through the hypermedia is by like submitting a form, or clicking an anchor tag, those are pretty much the only two things that allow you to interact with the server and just plain HTML, you have anchor tags, which you click on the link, which makes a call to the server. And that takes you to, and the downside of those interactions is that it reloads the page. And so I kind of forgot to mention that earlier is that, you know, that's another reason why, as, you know, web development became more and more modern and people expected richer and richer interactions that sort of became like something that we didn't want. We didn't want to reload the entire page each time. We got some data from the server. And so HTML solves that problem. And yeah, as it states on the HTML website, it is truly an extension of HTML and it makes HTML, it brings HTML to its fullest potential. And so it kind of gets rid of the need for, I mean, the reason for JavaScript coming into the picture was because HTML was lacking in those areas. And so, yeah, and we kind of left HTML in the dust, and we kind of went all in into JavaScript. And like HTML, we're kind of revisiting that fork in the road and we're kind of saying, hey, okay, what if we didn't put all of our eggs into JavaScript and we kind of improved HTML. Let's improve HTML and let's make, you know, HTML what it was really meant to be. And so that's kind of the whole idea behind it. Yeah, that's helpful. So my follow up question is, yeah, is HTML plus JavaScript considered fully hypertext or fully hypermedia. No, I would say no, because so the core thing in order for in order for in order for this to work to its fullest potential hypermedia has to be the engine of application state. So HTML is hypermedia, but it doesn't allow for this hey to us concept that we're trying to that we're trying to bring out. And that's because HTML is just limited in power, as I kind of expressed earlier. Now HTML plus JavaScript that gave you the interactivity but there's a disconnect there because you know, as I mentioned earlier, there's just a lot of we have now, when we introduce JavaScript is the picture we have to manage state on both the server and the client, if that makes sense. And so the core concept of hey to us is that we can just use hypermedia to encode our state, and we need nothing else. And so that's kind of the idea behind it. But funnily, it's funny because HTML, HTML itself is implemented in JavaScript. And so, yeah, I guess so I guess you could say yeah, HTML, I mean HTML plus JavaScript does create this true hypermedia the way we would like it. Or the way Dr Roy Fielding would have liked it the way he kind of described it in his PhD work. And this goes into a whole nother conversation and I'd like to, you know, talk about it after if you'd like but the whole history of the rest. So apparently what we consider to be a rest architecture, rest architecture isn't really rest. I've recently learned this myself, but there's some quotes by Roy Fielding and I'm not quoting him exactly, but he did have a blog post, and maybe I can bring it up right now just so we can see the title. Fielding. Yeah, and so the I recommend everybody read this blog post if you get a chance. Basically saying rest APIs must be hypertext driven. And so, yeah, it really just all comes back to this idea that the hyper media is supposed to be driving the state of the application. It shouldn't be. And there's a lot of benefits to this that I won't really dive into much now, and I haven't really experienced them all myself either. This is something I'm new to, and I'm still discovering. But yeah, it is, it is interesting. It is definitely interesting. So yeah, I recommend everybody read that we get a chance, but kind of moving along. Let's see. Okay, so yeah. Now I guess we can get into our live coding session. So everybody's fine with that, we can kind of. And so, yeah, I have a to do app here. And that's what I kind of wanted to use to showcase this. And so I'll kind of walk through it, and we might run into a bug or something later on like I said earlier, my development machine is kind of, it's not agreeing with me today. But yeah, so this is our to do app. And I'm not going to dive too much into like implementation details like how all of this works. This is what OKP looks like. So this is the web framework I was talking about earlier that I've been working on. And so this is the top level API and so we have a homepage and so let's see what is the homepage do. So it accepts a get request, it selects all the to do is if we have any, and then it returns all of those to do is HTML. And so this is the entry point into our application. So if we were to envision our application is like a state machine, this would be the first node. This is when the user is going to the homepage. And so this loads in everything. Like so as you can see here, we have a script. So this is all you need to use HTML to just put this in the top of your va your HTML document and then bam, you have access to all of those HTML X attributes and you're ready to go. And maybe I guess I should explain like so this right here is lucid. And so it's a it's a monadic DSL. And so, you know, monads in Haskell they allow you to use the do syntax. So we have all of these do blocks right here. And yeah, you basically just nest HTML tags within each other. So I have a head and a body inside of my top level HTML tag. And then within the head I have a script. And within my body I have a h1 and a div within the div I have. These are functions. I'll show the implementation of these later. But yeah, that's how that works. Yeah, so let's get started. And like I said, this is buggy so there may be some issues but that's fine. We're doing a live coding session. So we'll we'll run into some issues and then we'll fix them accordingly. And so that'll, we'll kind of get up to speed on how to use all of these things. So hold on, I have to get my IP address here. Yeah, so this is the to do app. And so let's just kind of look at so I can go ahead I'll delete this and I'll kind of show. So bam, that was htmx right there I click delete it sent a delete request to the server. And let me show what the that endpoint is on on the server side right here. Okay, so I have here the forget to do button. So this is the button that I just clicked and that's what made the to do become deleted so it sent a I'm using the hx delete attribute. So that's sending a delete HTTP delete to this URL to this endpoint. And we've deleted that to do. And to show the actual endpoint that receives that request. So this is the forget to do endpoint. It takes the delete method. And you have to see that the first path parameter is to do's. And then we get the second path parameter, the to do ID. And then we go to our database and we go ahead and delete the to do, based on the ID. And then I'm selecting all the to do's from the database and then I'm returning a to do's table. Because I deleted that to do we have no more but let me make another one. And that was also just now another htmx interaction. So, when I click on this create to do button. My server response to that and it puts a form into the DOM, and then I can go and make a to do here. I'm going to create that so now I have a make T to do. Let's try another one. I don't even have dogs. I have cats, but just whatever. And yeah, that's that. And so each time we're creating it to do. I'm getting so. Every DOM change you're seeing here is an interaction with the server it's an interaction between the client and the server. If that makes sense. And so. Yeah, whatever create to do and then we can delete these. Do we do it before you all of them can I ask a question. What happens, what happens if you refresh right now. Okay, yeah, so my current. Yeah, so if I refresh this will just go to the folder. I'm sorry. No, it's there that's great. I was, I was curious if it happened to the to do this. Yeah, so, but I'm glad you brought that up because there are cases and so my current implementation of this server it doesn't account for these edge cases but if like I were to. Let's say for example, I go to create to do and then I refresh this page. It's going to take me back to the original page, but HTML provides some helpers that make it so. If I were to go here and click refresh you would bring back the same page, but you'll notice in this in the. My search bar up here. The URL doesn't change. And so but HTML does provide facilities that allow you to update. I forget the name of the property but basically it'll allow you to update whatever's in the user's search bar up here. Just to jump in, in AngularJS, there's well, sorry, Angular and probably react as well. There's something like called a UI router right where basically, I think the way htmx is set up. It seems like you can update frames inside of the HTML set. Is that correct? Like just just the individual. That's exactly correct. Yeah. And then but but sometimes you can have it so it'll update the state of the URL. So that like if you go back to a like basically so you don't break the back. So like you can you can return to a previous state that you were at before preview. Yes, exactly. So as you can see, like I hit back right there and it took me back. So yeah, I haven't implemented, you know, the code to handle those edge cases ideally you would. But yeah, so sorry. Yeah, I got confused here. When you had the to-do list and you hit refresh, it just returns itself. But when you hit back and got to the to-do app form page and hit refresh, it goes to the list. Why is that happening? So are you so you're asking like why? Here it looked like when you hit refresh, it went to the to-do list. But when you were on the to-do list refresh, it just it was fine. So why did it break on one part and not the other? Yeah, I think this was Chris's question as well, but I got lost somewhere along the way. Yeah, so basically I mean what I have in this in the bar is when I hit refresh, it's going to make requests to whatever URL I have in my search bar right here. So this is the URL for the home page. And so every time I hit refresh, it's just loading the HTML for the home page, if that makes sense. I got confused as to what the home page was. Okay, okay. Yeah, I think I get it. Yeah, sorry, you can keep going. Yeah, no problem. Yeah, it is kind of because it's kind of a new way to think about, you know, how state is kind of transferred between the client. And so then the cool thing about this is that, yeah, I mean, as I kind of talked about earlier, it's the server managing all of the state. And so I think, you know, once you get used to it, it actually does simplify a lot of things. And so we don't have like a separate router for the front end and a separate router for it's kind of all of the same. But yeah, when we do make these HTMLX interactions, it doesn't load the URL into the bar unless we specify it to do so. And I haven't done that in this case. But yeah, ideally you would. And yeah, so that's another interaction right there. So I just made this make tea to do. I basically turned it into complete. If I were to hit this again, it would make it incomplete. And so all this is doing is swapping a button. So another cool thing about this is that the Dom swaps can be very fine grained. So in this case, I'm making a request to the server to make this to do incomplete. And then it just returns a new button. So now that the to do is incomplete, I'm going to return a button so that the user can turn it into complete. So if I were to click this again, so let's say I made my tea. So now I'm going to click complete. And now my to do has been updated to a state of complete and I got the incomplete button back. If that makes sense. So yeah, I basically put that here just to show that these DOM updates can be very fine grained. And I'll kind of show the endpoint for that as well, just so we can see, like what am I returning. So I have an endpoint called edit to do status. And so this is taking a put request to the endpoint to do is it's making sure that there's a path parameter to do is. So it would be that that matches on that. And then this is matching on the second path parameter, which is the to do ID. And that's binding it to do ID. And then this right here is just to check that there's no more path parameters after that. If I would remove this, this path end right here, then I could just have anything after that. Second path parameter and it wouldn't matter, it would still accept it, it would still route the request to this handler. But because I have path end right here it's making sure okay we have to do is, and then we have a to do ID, and then it's nothing after that. And then here we're getting a query parameter to get the current status of the to do. And so this is what I kind of mean about encoding the state of the application in the HTML because we'll see. So this is the key right here I'm returning a to do status button. And so that's what that incomplete complete button was. And I'm kind of going through it it's kind of like weird to kind of, it's like, is it really updating the to do on the back end and yes it is. So I'll kind of show. Like this is the. This is the, the function that updates the status to the new status depending on which type of button the user clicked, and then I'm returning. So in that replaces the button that the user just clicked on. And so let's look at the flip to do status button because this is the HTML that I'm returning. So if we go check that out. So we have the flip to do status button. It's just a button. But it has this hx put attribute. And it's making a put request to the to do's with the correct to do ID. And with the status of that to do. And yeah, depending on the to do status, if it's incomplete, well, we're returning the complete button because it's incomplete. We want the user to click on complete if they completed it. And if it's a to do that was already complete and for whatever reason the user wants to bring it back to incomplete. They can click on the incomplete button. And so, yeah, this kind of goes back to this idea of like the state of the application is encoded in the HTML because depending on the to do that determines what action the user is going to get. So if it's a to do that's complete, they're going to get an incomplete button. If the to do is incomplete, they're going to get a complete button. And so that's kind of how that works. And my apologies, that's kind of weird to understand but is there any questions about that or any, any ideas or, or is that pretty much makes sense. I do have a question but it's not really related to that. I was curious. Yeah. Do you know if hdmx has like polling so like can you if. Yes, hdmx does have polling yep. Oh that's nice. Is it. So, yeah, I think you were going to bring up like a scenario like what kind of scenario were you thinking of using that. So I actually, well, I really liked this architecture. I was actually thinking of replacing some of our front end with. Well, basically we use giraffe in the back end and but I think this is like a good fixing some of the front end. But the example that I have in mind is basically. Well, it's not really rest it's sort of like a remote procedure call where the procedure takes a long time to run so like, we run a lot of things that take, you know, simulation or something like that that takes a really long time to run. So basically we just want something where, you know, you make a post, and then it keeps pulling the server until it's complete and then it renders the page. Yeah. Yeah, I think that's a great use case and yeah hdmx does have support for polling. So like I'm just bringing this up from the documentation maybe we can like do like a quick demo of something like I was just thinking like a counter that updates like every two seconds and the hdmx will pull the server like I would like to implement that a little bit after this. Sure, just to kind of play around with it. But yeah, hdmx does support polling and it's very useful. There's low delays, as you can see low polling I've never even used that before but that's possible. There's really a lot you can do. Honestly, it's really impressive and yeah I recommend if you go on Twitter and follow hdmx.org you'll see he posts a lot of examples of people making really cool things with hdmx. Like this to do it doesn't really do it justice at all. I just kind of chose something really basic just to get the idea out there, but you can really like there's not really anything I can come up with. It's me and you know I'm, I'm compared to a lot of web developers I'm very junior so it's not really saying much but I rarely can come up with something that's like, Hmm, I really I need to use an SPA framework for this, because it's like I feel like anything I would need to do I can do it in hdmx. So I have a lot of handles, even animations and things like that. It just has a lot of cool stuff. There's also support for web sockets and server side events and things like that. So yeah, that is very much well supported a lot of stuff. So I have a question. This might be a little too off topic but and I'm not an expert in this stuff either but how like a lot of this stuff that you're talking about in the sort of the mission of hate loss. Yeah, kind of sounds very broadly like the Elm architecture. Yeah, what do you, what's your take on overlap or just just what do you think of the similarities there. I think there are a lot of similarities yeah, I'm glad you brought that up because I did think about that before. I was like wow this is kind of like the Elm architecture except it's just full stack. And it really fits nicely with, and this kind of goes into like the original I mean we're talking about Dr Roy Fielding he's like the father of the rest architecture and he's written a lot of the RFCs for, you know, the RFC and a lot of these other protocols that web developers use and HTMLX pretty much completes his vision because you know the rest architecture source to be stateless. And, you know, this really fits nicely because we're performing an action that sent to the server. And then the servers returning more HTML to perform more actions. And so it's kind of like we kind of it's it's not obviously there's state on the server. I mean there has to be state somewhere but it's all in one place so I guess an Elm you can, you know, looking at it from the Elm architecture perspective, where you have a model, and you're making calls against that model, and then you get a new model. Yeah, this is kind of the same idea where your servers kind of like, for the HTML that your server generates is the model. And then based on that model, you get access to other endpoints in the server. And yeah it's really nice and another cool thing is that you know the client doesn't have to have any knowledge of the server, really at all. What it needs to be able to do is, you know, understand these URLs, make requests of the URLs, and then just put the HTML gets back into the DOM. And so the client really has no knowledge of the server at all. I mean it just knows that it's getting HTML. So it's really a really really dumb client. And then so your servers like, you know, it's a really thick server. And so it's like I said earlier it's kind of going back to the, you know how things were done back in the day where we're just really doing server side rendering. That's pretty much it in HTML just handling all the DOM swapping and all of that good stuff so we don't have to worry about it. I think that's very nice. But yeah, I do really like that analogy. Yeah, I really do. So it seems like a, like, to me, like, almost like a Elm light, you know, like, it's a little easier to understand than the whole conceptual apparatus of Elm. And it seems to achieve similar goals. It's very much so. Yeah. And yeah, you know, I kind of brought up Elm earlier, you know, a lot of when I got into Haskell web development, that was kind of like the main role was like, okay, I want to implement, I need a front end for my web application. What am I going to write it in? And, you know, there was GACJS, but the tool chain for that is just overly complicated in my opinion. And, you know, Elm was just kind of like, it's easy to get started with, you know, the Elm architecture is pretty intuitive. And so yeah, that was my go to for implementing, you know, the clients from our web applications for a long time. But yeah, I like HTMLX as an alternative just because I can do everything in Haskell. And yeah, I get to keep a lot of those, the things I like about Haskell, without introducing a new tool chain or anything. So yeah, really nice. I think Claude was going to say something. Yeah, so, okay, so I guess I should preface this. I haven't done real web development in decades. Like, I did it professionally like for the original act of server pages, right? So server side everything. This sounds like, well, yeah, so I kind of like this. This sounds like it's AJAX. Yep. Yeah, under the hood I, it is actually using AJAX. Yeah, except the only difference is, you know, you're using it through the attributes in your HTML, which completely changes everything because no longer do I have to explicitly make AJAX calls using JavaScript. Yeah, the HTMLX handles all of that. And yeah, so it is AJAX pretty much except now it's a part of HTML. And so that's, you know, that kind of goes back to like how this is an extension of the hypertext. It's kind of making it what it was originally supposed to be. Because, you know, as we discussed earlier, plain HTML5 is just limited. I mean, you only have two options with interacting with the server. And so this just opens up everything all within HTML. And so it's very nice. And I would say, yeah, if you've been doing, if you're only familiar with like server side rendering or anything like that, this is perfect for you. Because now you don't have to go and learn React or Sevelle or any of these other, you know, SPA frameworks. All you need to know is HTML. No back end programming, obviously for your server. And then you just learn these attributes and you can just really get going. So I think that's really cool. And yeah, I think the, yeah, it's very nice and convenient, I would say it was really for me convenient because I and not not that I have not that I'm like completely against SPA frameworks like obviously SPA SPA frameworks have their place for sure. And if you were there, if you were to you know try and build something like Google Docs for example that might not be too. I don't think you can do this in HTML probably this is an example like some something where you need offline first functionality might not be the best use case although I am working on a tool that might remedy that by like using caching and stuff like that so like if you were to go offline, you could still use an HTML, a web app that was built using HTML, but yeah, that's just one idea. But so yeah, yeah, I think I think it's great. So, is there any other questions or questions that anybody has or what about I guess security does it does it manage like authorization authentication. Um, so you have to handle it. HTML self doesn't handle it. The recommended way. I guess bear tokens would come in and the request of the server so it's probably Yes, exactly. So it's like, yeah, based on so you can use headers and things like that obvious for like JWT's whether the recommended ways to use cookies. Do it, I guess since, you know, the prominence of SPA is JWT's have kind of become the standard. But yeah, you can use either one for authentication and things like that and you can send headers with your htmx request so like this hx post. I could send a header with this maybe including a session token or whatever. I actually try and look for that. It's called hx headers. So yeah, you can add headers that will be submitted with the request. And so this is what it would look like. And so yeah you can put any whatever information you'd like in there. So yeah. I'm kind of curious if there's applications to this like to like an enhanced jam stack site and not even getting rid of JavaScript just pulling in JavaScript is sort of a separate library and letting htmx interact with the server. And so the main use case of this is like the front end developers I've worked with. I'm kind of complaining that there's very little, it's hard to get any kind of like isomorphism between the front end and the back end with JSON. So basically you have to like pass it, you have to serialize it JSON, and then deserialize it on the front end and if it changes on one side has to change on the other side. It's really annoying. So I mean it seems like it might make sense if, you know, it's kind of thing where the host for interaction with the server but then potentially have like for any kind of high performance, or browser performance tasks run, you know, run an SBA. Because I'm kind of thinking like you know, you know one thing Elm does very well is 3D graphics. And I feel like this probably would not do that as well. Yeah. Maybe I don't know maybe maybe there's a opportunity for implementing some sort of, you know, 3js in there. Yeah. Yeah, possibly, you know, this is still like pretty much in its infancy, you know, and so we're, you know, people are still discovering a lot of cool new things you know I really recommend checking out the this core. It's very, I should have it somewhere and I kind of also want to show this just so I can show everybody like the community is quite large and there's, you know, people from various languages. Well now it's asking me to log in. I don't know why. Anyway, basically there's a channel for like every language you could think there's a one for Haskell developers one for elixir, list users f sharp users. Like there's a lot of people coming from there, because as I mentioned earlier htmx is language agnostic you know as long as you can generate html, you're good to go. And so a lot of people are really taking a liking to that and really come come and really embrace the htmx which I think is great. And that's actually what led to the development of okopee so I didn't know about so I that's how I learned about giraffe, you know, there was a guy in the f sharp, the htmx f sharp channel. He was posting a lot of cool stuff and I was like wow you know a lot of the web frameworks in Haskell are kind of bloated you know I'd like something like giraffe, and because giraffe and Haskell are like, I mean f sharp and Haskell really related to each other you know I thought, why not have something like giraffe in Haskell. And so that's how okopee came to be. Yeah, I thought I wanted to comment that your okopee looked really nice and Chris and I use f sharp at work, but and so we're familiar with giraffe. And I really like what you did. Really simplifies a lot of things I think it doesn't provide you know it's not like a full I'm not sure maybe some people are familiar with the assault or that's like one of the more popular Haskell frameworks but it's like a basically a Ruby on rails. And it's it's there's just a lot of magic involved and there's a lot of metaprogramming and it's good for getting you up and started quickly. Once you understand everything but it's just a lot bloated for my taste you know I wanted something more lightweight. So that's the inspiration for okopee you know the inspiration was like giraffe flask from Python. So it's just really, it's just a monadic DSL for implementing. And this is very interesting too, as well. I'll probably do a separate talk on that sometime in the future. But yeah, I'd like to do that. It's pretty cool. But yeah shout out to giraffe for doing it first yeah. Yeah, I've only somewhat played around with Haskell web development and it's. Yeah everything I came across was very big. Which is surprising given how devoted Haskell is to minimalism. Yeah that's the you know. I think a lot of the Haskell community they have a tendency to get caught up in to caught up in these complicated abstractions and you know they're nice and beautiful I think in a lot of ways but they have to be used correctly like for instance okopee. This is all completely based on monads and so this is essentially yeah it's a monadic DSL and so but this is like way more approachable than you know a lot of these other features a lot of these other Haskell web frameworks they use like type level programming and template Haskell which is like meta programming. It's very like I wanted something where like I could just, you know, maybe go to somebody who's used to using express like no JS express and I could like show them this and it wouldn't be that intimidating I think because it's like ok ok it has to have the get method and we have to check that the first path parameter is greet and we can get a path parameter or query parameter that has a name. And you know it's going so forth I feel like it's just a lot easier to explain. Yeah I mean the way you've got that set up there I mean you're you're just a couple of curly braces away from a computation expression and F sharp. Yeah. And I think those are a lot easier to read. Yeah. Yep, the do syntax. So, I guess did anybody want to see that polling example really quickly. I just kind of want to implement implement a counter. I'm just going to slap this on to my to do app. Let's just do it really quickly I know it's going to be nine in a bit but let's just do this for fun because why not right. So I'm going to define a counter endpoint right here counter. So, monad okapien so this is just basically saying you know we're operating with a monad that has access to the the state of the request so whatever HTTP request and we're basically performing a series of checks on request so like is an example. This right here checks that the method is a get request, if it's not this will fail, and it will try the next thing in line. So that's how this works basically that and this is what this operator does is basically saying, okay if that doesn't work, then try this one if that doesn't work, then try the next one. So this is performing the series of checks against the request and verifying that, okay, this is the right request for for this handler. And so I'm checking okay, is it a get request is the first path parameter to do's. And then is it an end. And then does it have a query parameter representing the status. And so yeah it's just basically a set of small combinators and stuff, but let's go ahead and implement our counter. So it's going to be a get request. And so let's see, we're going to do. Yeah, I was going to make it where okay so like one thing we could do we could like have a variable on the server. So like you could use like an IO ref in Haskell. That's basically like a mutable variable that we can store the state. So the number. So our state for this counter is just going to be a number. But I think when I'm going to try. So we can actually make this stateless so we can do this in a stateless way, because like, well, let's see, let's see. So I'm going to just, we're going to say, okay. So I want to check that. So our entry point is going to be counter. So basically match against the you talk URL like this counter. And then for the second. For the second argument, it's going to be an integer representing the current state of the counter. So let's do that count. And we might have to make that optional because to start off it's not going to have any count. So let's see. We're going to start off at zero right. Yeah. So, and then we're going to return. So this isn't something that's usually done in how I actually introduced this operator just to make things I don't know maybe easier for others that are familiar with it but that's like the pipe operator. So that would pipe into. And yeah, we're just going to return the count. So, and actually. So yeah, I was going to. So let's see. Set lucid. I'm going to have to render that. So I'm going to have to say, let me do. Well first, well first let me let's add the actual state of the counter to the page. So let me see. So, okay, let's add a counter button to this. Or we can just add the counter HTML like that. So I'm going to define the counter HTML first let's do that, just so we can get something on the screen. So that's just going to be some HTML. And we're going to use that polling attribute that we were looking at earlier. And so I'm just going to make this a div. I'm thinking, and it's just going to start at zero. And then let's go back to the documentation here, because I don't really use this polling attribute, but so this will be fun. What was the name of it? Well, it's it's the HX trigger. And so yeah, like let's copy that. So like let's get let's trigger this URL the counter URL, like every. So let's see. So yeah, and lose it. This is just going to be HX get. And we're going to make requests to counter slash. And I'm going to concatenate zero to that because we're going to start off with zero. So like the entry points are application the counter starting off at zero. So when they come to the home page. And then we're going to trigger this every two seconds or let's just do every one second. So we don't grow old doing this. And so, yeah, the initial state so I can actually. I could just I could have abstracted this out into variable, but we'll just do zero zero for now. And then okay, let's see what that looks like first. So, and why I guess we just go ahead and implement that. So we're making a trigger to this record we're making a get request to the counter every one second. And then we're, well, let's also specify the target HX target. And we're going to set it to outer HTML. And I'll kind of show what that means later but basically, we're saying we want to replace this div this entire div each time. The counter is triggered. So whatever whatever response we get from the server, it's going to replace this div right here. And so actually, because I'm going to use this in two places I actually should abstract this out so it's just count. And count and I'm going to have to do to show count to HTML, just so that works right. And then let's see if this compiles really quick. Well, let me. And then, and actually, let me just bring this down here so I'm not scrolling back and forth counter. So yeah, path ram is counter. Okay, and this is no longer there. This is going to be guaranteed to be there. The second path ram is going to be an hint. And yeah, we're just going to and then what we're going to return is the new counter HTML. But it's going to be the new count. And we're going to return that. So we're, so this okay is just, it's just a generic 200 okay response. We're modifying the body of that response so that it returns this counter HTML with the new count. And it's returning it. So because this returns a response. Yeah, let's see what happens now. This might this might not compile yet, but we'll fix it. Okay. Okay, yeah, of course, so put a dollar sign right there. It says, okay it's applied to two few arguments right so. Right here so our counter is going to start off at zero. So that's what we want. And okay, let's try it. Let's see if this works because it looks like it compiled but let's see if it works though. And then we can even open up the dev tools and then see making requests every. So cabal exec to do. Oh no it's due to do exe. And so let's see what happens here. So if I reloaded we should go back to the homepage. And okay, so I noticed nothing's updating let's see. Okay. So you see it's being triggered every one second but there's a target error. So we have to figure that out. I'm not sure what's going on there. Let's see. Because, well, let me add because it might not be obvious here. So I'm just going to add an ID to this call it counter. Okay, so yeah I messed up here. So the HX target that this attribute determines what object in the DOM is being swapped out. I should have just used HX swap. So the swap determines what type of swap you're doing. Are you replacing the outer HTML the inner HTML. So there's a lot of you know variations with that you can really you can replace the sibling of the element. And so we're we can really manipulate the DOM like a surgeon just from our server. It's pretty cool. So let me see let me build that so hopefully let's see if this works because by default the target is itself. So it should just replace itself every one second. But we'll see if my assumption is correct. I believe that's how it works. Yeah. Let's see what happens here. Okay. Let's see. Okay, there we go. Nice. Yeah, so that's an example of polling. Very basic example, and notice, like, I could have did it where you know I use an IO ref and I store the state. I'm going to store the server explicitly right like inside of a variable and then I read from the variable and then send that. But here the state is completely within coded in the HTML. Because I have a count it starts off at zero. I'm going to bring that state inside of this URL so it's going to make a get request with its current count. And then the server is going to take that and say okay where your new count is whatever count you pass as a path parameter plus one. And then I'm going to send you back the new HTML. And it's just so it's kind of like a recursive type of thing going on. And if you if you refresh the count will go back to zero. But if you store it count as a, yeah, yeah, I read this it should yeah, it goes back to zero yeah. Cool. Thank you so much I know it's tricky to do live coding like that but it made it look easy. Yeah. Yeah, just. This was a good talk I had fun for sure. And even practice the errors, because it did seem a little too seamless. And planted the questions right like planted the people in the audience. Afterwards, don't worry, guys are going to get. But yeah, like I said, I mean, we just scratched the very surface of this today. And you know if you guys are thinking about using this you know it's really easy to integrate into whatever existing system you have I mean like I said at my job we introduced it to like our pretty complicated big nasty, you sold application, and it fits in pretty smoothly. So. Yeah, I like it. That's really cool. All right, this, this was really fun. So thank you so much. And I think I'm going to stop the recording and then if there are any additional questions we can chat for a little bit longer. So, yeah, figure out how to stop the recording. All right. Thank you.