 So earlier this year, I decided that I wanted to start working on the Clogars project. And the first thing I noticed whenever I looked at Clogars was there was no test suite whatsoever. So, and I'm a big fan of tests for my programs, particularly ones that are acceptance tests that say the user actually logs in and when they log in they can view, you know, their photo stream if it's something that direction. Since this end, I've built a couple of libraries for doing ring interaction and testing. The first one I want to talk about is called Paradot. It is basically a port of RackTest, if you're familiar with that from the Ruby community. It uses the thread-first macro to simulate an iterative or an imperative interaction. You start first by creating a session and then you can actually do a request. In this particular case, we're doing a request to a login and actually passing some key word parameters through. It uses ring mock underneath, so these actually are the exact key words that you see in the ring spec for your requests. You're also able to do things like follow redirections if you get a redirect at that point. It parses it out and figures out what the URL and creates the next request and such for you. This example does a request, follows a redirect, logs in as a user, follows a redirect and then actually looks at the task, has a dot, dot, dot there for creating a task and will then go and actually view the task. This is a little bit beyond what ring mock itself will do because it will actually parse out the cookies for you and keep those around in a cookie jar so that as you're moving along through the session, you actually stay logged in as that particular user. As part of the, what each one of these actions return is a little hash map, or hash state, state map, there we go, it contains the last response and the request that was used during that interaction, so you can actually pull those out and test against those particular values for that point in your interaction. There's the app and the cookie jar as I have already mentioned and there's a couple of extra things there down at the bottom for content type and headers because it's nice to be able to say for all future requests in this session, I want to use the JSON content type because I'm actually testing, say, a JSON API. This works decently well for, you know, hitting API endpoints, but it doesn't really represent what a user does whenever they interact with your application. There we have the, we've manually put in where the login URL, we have the parameters with the username and password where we've manually put those in ourselves and there's this whole HTML view, if you're doing an HTML site, where you also have to place those particular elements and if you get those out of sync, you've got to go fix all of your tests if they break and I prefer something a little bit more what it looks actually like what a user does. So to that end, I built a library called Keradin and this is inspired by a library called Capybara from the Ruby world. Here's an example of logging in with it, you start a session, you go visit the actual root page and then you can tell it to fill in these elements on the form with the particular login name and the password and you can tell it to go press this button and in this case follow the redirect around. This uses in live underneath to actually parse the HTML to figure out what the different nodes are and actually to update them as you do the form interaction. You don't always have fields, in this case, this looks at the labels for, say, the login looks at the label and then finds the text field associated with it to do the username. You don't always have labels, so it also allows you to do the in-live selector syntax to choose what HTML elements you're interacting with. In addition, there's a within form that I added up on that slide, that was not on the previous one, that allows you to scope all of the interactions in the body to that particular section of the HTML. In addition, I like to be able to go through a portion of the test to do some interaction with the website and then actually test some of the, that I'm actually getting what I expect and then continue on. So Keridan has a selection, a small selection at the moment of test helpers, you wrap them in the has function and in this case, we're actually checking whenever we go to the root page, did we get a 200 response status and does it have, does the page text actually have hello world in it? So it actually parses out, you know, goes, uses in live and checks through the HTML and gets out what's in the body and checks the text for that. And then once we've done those particular tests, we can, we'll actually continue running and we'll, as you see there, can do a following of a link in this case to whatever recent would be. This works by hooking into closure.test as, through some of the underlying mechanisms of it. I don't have anything for expectations or midge as I do not particularly use those ones yet. In the future, there's still some additions that need to be made. Paradot, for example, doesn't really support nested parameters. So it would be nice to actually have those go in where, if you have the wrap nested parameters, middleware, it can actually keep those in line as you would expect. That actually might end up being better off in ring box. So if I, when I get to that, it might end up being a patch in that direction. In addition, keratin doesn't yet support all of the different HTML elements. I need to make it understand things about check boxes and radio buttons and drop downs and then just figure out what else works good for test helpers. Not on here is, I'd like to eventually have it the ability to say, instead of using Paradot in in live, can you instead use CLJ WebDriver as part of this session so that you can actually do JavaScript testing so that whenever you actually start, you have your HTML page and you got a little bit of Ajax, you don't have to port, you know, whatever in your test suite it is that now has to do with the Ajax call. You can just flip a switch, hopefully. There are where they are on GitHub. That's my URL and Twitter handle, or if you want Twitter handle, if you want to follow me. And if you want to see some examples of keratin actually in use, if you go check out the Clogar's test suite, there are lots of examples of it. This is actually what the reason I ended up building these particular tools for. Thank you. Hi, I'm Dan Ligel Porter. I am frequently known on the Internet as a periodic. And I'm someone who until five or six years ago would have destroyed myself as primarily a visual artist. Now I like to call myself a programmer. And the big reason for that change is processing. So if you haven't heard of it, processing is a programming language environment that was designed with the aim of encouraging programming among the visual arts. So it's got a straightforward, dry API that's sort of similar to HTML canvas. But it has a lot of other capabilities besides it can do 3D, can do video rendering, audio input, audio synthesis. It can talk to our genuinos. It can get inputs from Kinects, a whole bunch of stuff. So the handy thing about processing is that under the hood, it's really just some Java libraries. So that means we can use it in Clogar. That's where Quill comes in. It was originally started as CLJ processing by Roland Sadoski. It was now primarily maintained by Sam Aaron who gave it the Quill moniker. And it's just a wrapper around processing that makes it a lot more pleasant to use in Closure than if we had to do a lot of Java interopt. So what I'm going to do is I'm going to walk you through creating a pretty simple Quill sketch in the next six and a half minutes or so. What the sketch is going to do is it's going to implement a common visual trope among Hollywood GUIs and games and other flashy interfaces that don't really do anything, where you have a lot of spinning circular arc segments nested inside one or the other. So let's get started. I've got my project here that I just recently created with line new. The only thing I've added to the project at CLJ is the Quill dependency down here at the bottom. I pre-warned my Swank server. It is. Oh, god. How do I do that? I don't know how to use my terminal. OK. That's still not big enough? Is that big enough? Color. OK. Color is bad? I don't know how to change the color. All right. I really hope you can see. If you can't, I'm very sorry you should find me afterward. So the first thing I'm going to do is to find the one true circle constant, tau. I just find it a lot easier to reason about than 2 pi. So the first question we probably want to ask ourselves as conscientious Clojureans is what sort of data we're going to need. We're going to need some way of describing the arcs that we want to draw. So like I said, this is not going to be idiomatic Clojure code because we're going to be processing underneath. So we're going to need a place to put this that the draw loop can find because the draw loop can't take any arguments. So I'm going to find an atom called arcs. And it just contains the empty vector for now. So now I need a way of making one of my arc objects. So I'm going to find a function to do that. It takes one argument, which is the index. And this is the way that it'll be able to set a different radius for each arc. So there are four properties to each arc. It has a position on the unit circle where it starts. It has an angular width that it spans. It has a radius and some angular velocity. So the new arc function just creates a map with all of those properties and fills them in with some nice looking random values that I won't explain. So there are two fundamental functions to every quill sketch. The first one is called setup. It's run once at the beginning of your sketch. And it's a good place to set up any initial state or configure things that will be constant throughout the entirety of your sketch. And the other one is called draw. And this is your main loop. This is what actually draws stuff to the screen. It's called by default 60 times a second. So let's fill in setup. There's not much happening here. The only configuration we do is call smooth to turn on anti-enlucine. Make everything nice and pretty. And then 15 times over, we're just going to make a new arc and swap it into the end of the arc setup. So now we're ready to go into the draw function. There's a few lines happening. There's a few lines here, but only really two basic things going on. This block here just sets up some visual properties of the sketch. We're gonna draw a black background every frame. We're gonna turn off filling in objects. So we just get the borders of the arcs rather than the full pie slice. We're gonna make them pure white stroke, make them 10 pixels wide and give them square caps. So after we finish doing that, we can move on to actually drawing them. So we first, by default, the origin is in the top left, as you probably expect if you're familiar with graphics programming. And we're just gonna move that down to the middle with a translate. The translation matrix is reset every frame, so we don't have to worry about scooting off to the bottom right of the frame. And then we just iterate over all of our arc maps for side effects. We pull out the position width in radius properties, and then we can just use Quill's arc function to actually do the drawing. It takes six arguments. The first two are the X and Y positions of the center of the arc ellipse. The next two are the semi-major and semi-minor axis lengths. And we want circular arcs, so we're just gonna give it the radius for both of those. And then the last two are the angular positions to start and stop drawing the arc. So we're gonna start at the position and stop at the sum of the position and the width. So now we have all the functions we need. The last thing we need to do is actually define a set and kick it off, and we do that with the depth sketch macro. So there are three important keyword arguments to this macro. The first is the size, which is just a two vector, defining the width and the height of the sketches window. And then it needs to know the names of our setup and draw functions, which in this case are just setup and draw. So let me open up a little crab. So here's a very cramped repo. Let's evaluate everything, and now we have some arcs. So you might be asking me that I told you the arcs would be spinning and they are clearly not, so let's fix that. I have a habit of where I like to separate out the part of my draw function that actually changes the state from the part that just does the drawing, and I like to put that in a function called tick pane. So this is not very much happening here. We're just gonna loop through all of our arcs and pull out the position and velocity keys, and then we just update the position to be the sum of the position and velocity. And then once we have the shifted arcs, we just reset the atom to contain the new ones. So we can define this and go down and call tick at the beginning of our draw function and redefine it. And we go back and you'll notice without us having to do anything, the sketch is picked up on our new draw function and now the arcs are all spinning. This is really cool because it means we can do a lot of experimentation basically instantaneously. So let's say we wanted to make the arcs thicker. Just happens. We can make them bright pink. And so this is really great because it allows you to do lots of experimentation really fast, which is what I found so seductive about programming in the first place. So that was a little taste of Quill. If you wanna talk to me more about creating art with code, check out some 3D printed sculptures I made with Quill. Find me around later. And thanks for listening. Good afternoon. My name is Hugh Goodman. I've worked with Lisp NOIC and my day job is at Brander Group. We're an Amazon web services company and shockingly we like to do our software development in Lisp. However, during the day, this is what I'd really like to do. A whole bunch of nothing. One day, my wife walked up to me and asked, are you happy? And yeah, sure. I'm on my own private island. I'm very happy. But she said, are you really happy? Are you like jump up and down happy? And like a typical guy, I said, well, yeah, I'm happy. Whatever. Then she said, really, how happy are you? And this is when the alarm bells went off in my head. Because my wife is a data junkie. She likes to collect data. She likes to manage data. She likes to graph it over time. She likes to do everything you can think of it. It's amazing. And what she's interested in now is quantifying happiness. Really, what she wants to do is track her happiness over time, as well as what she's doing at the time to see if there's any correlation and also long-term trends. So really? The things she's looking for is capturing context, have something easy to use that she can use anywhere. And myself, I have very simple needs. We are, however, a mixed couple. She has Android. I have Android and she has iPhone. So we're not gonna be writing any phone apps. Instead, I'm just gonna whip out a simple little web app. How hard can this be? And this is when I start thinking about it. Because at my day job, we have hundreds of hosts. However, they're all being used. And personally, I have dozens. And I don't really need another one. And there's a lot to owning a host. For an initial setup to maintenance, security updates. There's some non-trivial Amazon stuff. If you do it up there, monitoring. And if you have monitoring, then you get pages. And really, I just don't want that. And ultimately, the monetary cost is, it doesn't matter to me. I just don't want another host. All I want is a simple web app. And this is when I started looking at Heroku. It's really a simple cloud app platform. It's very easy to do. It's sold as a service. So basically, your closure app is up and running. And basically, what you don't do is manage a whole lot of stuff. They're gonna be taking care of host failures, data center problems, all things with security. As well as anything that has to happen with the update. As a matter of fact, you've probably seen in the news last week, I spent almost the entire week just watching New York City data centers go up and down. And then three days later, when the gasoline ran out, the same thing happened in New Jersey. And yeah, I had plenty of machines to worry about, but Heroku wasn't one of them. And right software for Heroku is actually really easy. You just hack out your closure. You update it with get, basically. You send it right up to Heroku. And they will launch it and manage it on their servers. You can then point to .com to it, and you're all set. Heroku conveniently runs on Amazon. You've probably heard of EC2 for their virtual machines. However, they also have dozens of other services, which are really nice. S3 has recently come out with a new version where they're charging a doll, I mean, a penny, a gigabyte. And that's really game changer. And they also offer databases, the queuing service has saved my bacon more than once, and stuff like this. So really for my simple happiness web app, what I wanna do is collect data, I want to store data, and then I also want to send out collection reminders throughout the day, with both text messages as well as email, so you can get randomized samples. This means a simple web app is suddenly becoming a little more sophisticated. Now you have to deal with the database, as well as either a mail server or some sort of service we're dealing with all that. And these are two more services that I do not want to manage, much less two more hosts. And with Amazon and Heroku, we can do that. So, from the time I bought the dot com, which is meometer, you can tell all the good ones are taken. Two when it was up and running was a total time of four hours. And really only about half of that was involved in the technology side. And it is indeed very simple. I'll ask for is your name, the context that you're doing, and then a big giant button of how happy are you? Clearly everybody here is a nine. Ding. Once you enter in some information, it'll give you some happiness back. We'll throw up a little quote. And actually I think I spent about half the time looking for quotes. Seriously, it's not that easy. And every other time you log in, it's even easier, it doesn't need to know who you are because it has a cookie. And as a matter of fact, you don't even have to tell it what you're doing. You can just give it a number, boom, it knows the date. And all of this is being stored in a database, actually. And it works great on phones as well as tablets, et cetera. This is the code base. It's shockingly 54 lines long. This includes the inline to HTML, the everything to deal with the database. The form processing is here too. I also put in something, so if you type in test, it doesn't actually store it. So I can test the infrastructure to see if things are working. And yeah, and it's basically a quick little jetty app. The moral of the story is that the use of simple services really allows you a lot of flexibility, especially when it comes to management. In total cost or ownership, it seriously matters for me. I'd much rather have just a few deal with a few servers than hundreds of servers. And especially when we have clients with small needs, then it might necessarily need a server. That's typically the problem. People walk in the doors and say, we need 50 servers. Usually they need one. We need a server. Sometimes they don't need any. This is where Heroku comes in. And yeah, it really does make me very happy. Thank you. All right, so. Yeah, thank you. Yeah, so I have a Raspberry Pi in my bag. They're really cool. The one I have in my bag is running closure. It's great, but I'm not gonna talk about it. So if you are interested in the Raspberry Pi, I wanna see one find me. I kind of switched topics at the last minute just because this is where my head is right now and I'm like fully loaded on FRP. And I have reached some crystal of understanding that I wish to convey. So functional reactive programming. It's a thing. I work at a place called LonoCloud where I've been doing a lot of closure script recently to write web-based visualization tools for various cloud tools that we operate. So I once again found myself in the world of web programming and callback hell. And I'd heard things about FRP and over the past few weeks with the help of my coworkers and a few friends, I think I've reached the light at the end of the tunnel. So I'm gonna try this explanation on you guys. If I'm not doing a good job, maybe I'll just switch back over to talking about Raspberry Pi. But here we go. So what is FRP? It is fundamentally a programming paradigm. What is a paradigm? Well, a paradigm is usually delivered to us in the form of an implementation, which is either some language or some library or some combination of language and library. If you look at all the FRP stuff that's out there to include the papers, some of which I've scanned in all the various implementations, whether they're languages, libraries or frameworks, two key ideas stick out. The first is the notion of a time-varying value. And I'm using terminology from my favorite paper which is the flapjack's paper. But they talk a lot about time-varying values, which one way to think about them in closure terms is as reference types. However, in closure, if you want to know the value of a reference type, you are the one responsible for asking the question. The value is not pushed to you. You dereference it with the little at symbol reader macro. These time-varying values are reference types, the value of which changes over time, but that value is conveyed to consumers as a stream of changes, so time-varying values. Once you have these time-varying values, these streams of changes, then you can work with them in a similar way to working with sequences in closure with the sequence library. You have these streams of events that you can compose or interleave or transpose in the same way we're used to working with sequences. What this does is allow you to program with events as if they were values. One of the other themes in a lot of the papers is this point that's made that whenever you're working with callbacks or watches, you don't have types. A callback is a void type. For those of us in closure, it means we don't have a value. It's usually the function that adds a callback is void. It doesn't return anything, and of course, callbacks are not values. What this allows one to do is work with events as streams of values and compose them the same way we would any stream of any value. So, there's tons of stuff again. I'm not gonna go over it. All of the stuff listed except for flapjacks is either on a platform I can't use for operational reasons, is too much, is too little, or just sucks. So of all of these, I like flapjacks and that's what I'm gonna talk about. What does flapjacks give us? So a lot of the FRP solutions claim to give you all kinds of stuff that help you solve all kinds of things in the domain. This is how you build web apps now. We give you a templating language and graphic stuff. Flapjacks just gives us one thing, which is this ability to turn events into streams of events so that we can work with them like values. And in a browser, there are a couple different flavors of events. There are user events. Bob, click the button. There are events that come from the DOM that you may or may not have initiated like success of an EJAX callback. And in a lot of systems with events, you have scheduled or periodic events like heartbeats or refresh the buddy list every minute. Flapjacks gives us tools for working with all those kinds of events. And then again, once they're streams, there's this general notion of consumption and generation and fusion and filtering and so on. What flapjacks gives you is a general set of tools for doing what a lot of people who work with events know as wiring. You know, we talk about wiring up the mock-up, wiring up our program. This is a genuine general purpose wiring library for wiring together behaviors in the browser. Demo time. So, does that look awesome? So, we're traveling back in time. Maybe the full screen is a little too awesome. All right, so what we're looking at here is the sort of the Fibonacci or the factorial of browser event things, which is we're gonna add some numbers together in a cool way. So I can do this thing where I can tab between these fields and change the values of the fields and they get summed up and printed at the bottom. Interesting thing to note, if I zero all these out or if some of them are empty, it does the right thing. So there's some ground value for these event sources, in this case, zero. If I type in something that you can't meaningfully sum, like, you know, some string, nothing blew up. So, you know, at least this experience is not unsophisticated. It does some amount of error handling. And things happen as I type. What is the code for this? Well, here it is. What we're looking at. So this is all of the closure code that drives all the behavior on the page we just saw. I'm gonna walk through each function. There are these five functions and explain the bits of flapjacks that are relevant to this closure script. The first function is kind of a helper function called parse float that takes a string and a default value to return in case that string can't be parsed as a number. So this is the sort of guard that percolates a number through the event streams if there isn't an input in the text field or if it's a string that parse float doesn't work with. So that's just a simple function. There's no event stuff happening. The next thing we do is define a function called extract number E. And you'll see this when you're working with flapjacks, this convention of the capital E at the end. That's the convention for a function that returns an event stream object where an event stream is an object that's part of the flapjacks API that represents a stream of events. So here we're creating a stream of events that's backed by an HTML element with the ID ID. We're using flapjacks' map which is specialized for mapping over events and we're mapping over each event with parse float. So every time the HTML element we specify generates an event like has a new value we run parse float on it and then that gets applied to whoever's consuming the stream. The next thing we do is define what in flapjacks is a behavior. So things that end in capital E are event streams. Things that end in capital B are called behaviors in flapjacks world. These are those time varying values that I was talking about. And the difference they have with event streams is they represent a value even if an event has not yet been fired. So for instance, when I opened the page I didn't get any errors or anything. That's because the inputs are behaviors and I had the ability to specify a default value. So what is the value of this thing before anybody has fired an event on it? That's what a behavior is. And then finally, now that we have expressed all of the inputs on our page in terms of behaviors we can start to compose behaviors. And this is the kind of composition that you just, there are no means of composition, no legitimate sane means of composition for callbacks or watches. So this is where we start to really reap the benefits of working with behaviors because here we're defining a thing called sumB which is a function of one or more or zero or more behaviors that allows us to apply a function to the snapshot values of those behaviors together and then return another behavior. So we're looking at a system where we have inputs. We lift them up to this flapjack's behavior level and now we can define new behaviors expressed in terms of existing behaviors that are totally general and not coupled to even the DOM. Lastly, we have a function calculate and this is what actually does all the wiring in and causes things to happen when we load the page up. But it's a function that takes a target ID, place to put the sum and some source IDs. And here we map our extract number B over the source IDs. Actually, I'm gonna flip open the HTML going on here. So I have an onload which calls my closure script function with the thing to put the results and the ID of the inputs and then here are the inputs down here. So this function takes the IDs, wires them together and then we're using one of the few IO functions that comes with flapjacks which is a function called insert value B which will continuously update an attribute at an HTML element of your choosing with a value given a behavior. And there's also an insert value E to do the same thing with event streams. So that's pretty much it. I've like been out of time for almost two hours now according to that thing. So I guess I'll just stop and just break you this time. Needless to say, there's a lot of fun stuff to do with events and I'm working on a closure script board if you want to talk about it. I think it's a general purpose evaluation model that could also work in closure in the JVM for doing interesting things. And thanks.