so earlier this year i decided that i
wanted to start working on the clojures
project
and the first thing i noticed whenever i
looked at clojars 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
um
towards 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
peridot
it is basically a port of rack test if
you're familiar with that from the ruby
community
uh 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 parameters
keyword parameters through
uses ring mock underneath so these
actually are the exact keywords that you
see in the ring spec for your requests
uh 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 next
requests and such for you
uh
this example
does a request
follows redirect and then actually logs
in as a user follows the redirect and
then actually looks at the task has an
example has a dot dot there for creating
a task
and
will then go and actually view the test
the task
and this is
uh 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
uh as part of the what it what each one
of these actions return is a little
hashmap uh hash state state map there we
go
uh 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 the
uh
in your in your interaction
uh
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
um
and so this works this looks decently
well for
you know hitting user or use hitting uh
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 went with the username
and password where we've manually put
those in ourselves and there's this
whole html view if you're doing 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
caradin
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
the form the form interaction
since you don't always have fields
particular in this case this looks at
the labels for say the the login looks
at the label and then finds the the text
field associated with it to do the
username
you don't always have
labels so it also allows you to do css
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
uh in addition i like to 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 uh
that i'm actually getting what i expect
and then continue on so carried in has a
selection a small selection at the
moment of test helpers
uh
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 uh 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 it will actually
continue running and we'll as you see
that i can do a following of a link in
this case to whatever reason 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 uh let's see
in the future uh there's still some
additions that need to be made uh
peridot for example doesn't really
support uh nested parameters
uh so it'd be nice to actually have
those go in where
if you have the wrap nested parameters
uh
middleware
you 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
even have it the ability to say instead
of using peridot and in live
can you instead use clj webdriver
as part of this session so that you can
actually do javascript you know 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
uh there are where they are on github
uh that's my url and twitter handler if
you want twitter handle if you want to
find me
and if you want to see some examples of
keratin actually in use if you go check
out the clojars test suite there are
lots of examples of it this is actually
what the reason i ended up building uh
these particular tools for
thank you
here
hi
i'm dan ledrill porter i am frequently
known on the internet as a periodic
and i'm someone who until five or six
years ago would have described myself as
primarily a visual artist uh 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's uh was designed with
the aim of encouraging programming among
the visual arts
um so it's got a straightforward drawing
api that's sort of similar to html
canvas
but it has a lot of other capabilities
besides it can do 3d you can do video
rendering audio input audio synthesis it
can talk to arduinos it can get inputs
from k'nex um
a whole bunch of stuff so the neat handy
thing about processing is that under the
hood it's really just some java
libraries uh so that means we can use it
in closure and that's where quilt comes
in it was originally started
as clj processing by roland stadowski it
was now primarily maintained by sam erin
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 interop
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 uh it's going to
implement a common visual trope among
hollywood guise 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've pre-warmed my swank server
it is
oh god
uh how do i do that i don't know how to
use my terminal
okay
that's still not big enough
is that big enough
okay
color is bad
i don't know how to change the color
all right um i really hope you can see
if you can't i'm very sorry you should
find me afterward uh so
the first thing i'm going to do is
define 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 is conscientious
clojurians 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 and this is so like i said this
is not going to be idiomatic closure
code because we're initiating 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 define an
atom called arcs and it just contains
the empty vector for now
and so now i need a way of making one of
my arc objects
so i'm going to define a function to do
that it takes one argument which is the
index this is the way that it'll be able
to set a different radius for each arc
that's not
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 uh so the new arc
function just creates a map with all of
those properties um and fills them in
with some
nice looking random values that i won't
explain
so there are two fundamental functions
to every coil 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 um 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-aliasing make
everything nice and pretty
uh and then
15 times over we're just going to
make a new art arc and swap it into the
end of the arcs atom
so now we're ready to get going to the
draw function
there's a few lines happening 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 going to draw a black
background every frame
we're going to turn off filling in
objects so we just get the borders of
the arcs rather than the full pie slice
we're going to make them pure white
stroke make them 10 pixels wide and give
them square caps
and 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 going to move
that down to the middle with a translate
the translation matrix is reset every
frame so we're not 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
arcmaps for side effects
we pull out the position within 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 arcs
ellipse
the next two are the semi-major and
semi-minor axis lengths and we want
circular arcs so we're just going to
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 going to start at the
position and stop at the sum of the
position and the width
so now we have all the functions we need
uh the last thing we need to do is
actually define a sketch and kick it off
and we do that with the
death 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 set up and draw
so
let me open up
oh crap
so here's a very cramped repo
let's evaluate everything and now we
have some marks
so you might be uh 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 uh 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 bang
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 of 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 has 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
oh that's redefined
uh 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 want to 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 lisbenwyc 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
so yeah
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 you know do everything
you can think of it it's amazing
and what she's interested 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 thing she's looking for
you know is capturing contacts have
something easy to use that she can use
anywhere and myself i have very simple
needs
are however a mixed couple uh she has
android i mean i have android and she
has iphone
so we're not going to be writing any
phone apps instead
i'm just going to whip out a simple
little web app how hard can this
be this when i 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 uh 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 you uh 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 going to 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 uh yeah i had apparently plenty of
machines to worry about but heroku
wasn't one of them
and to write software for heroku is
actually really easy um you just hack
out your closure you update it
with git basically you send it right up
to heroku
and they will launch it and manage it on
their servers you can then point to dot
com to it and you're all set
roku conveniently runs on amazon
you probably heard of ec2 for their
virtual machines everything else i have
dozens of other services which are
really nice
um s3 has recently recently come out
with a new version where they're
charging a dollar i mean a penny a
gigabyte
and that's 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 want to do is collect data i
want to store data and then i also want
to send out collection reminders
throughout the day
with both 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 mail server or some sort
of service for 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 meow meter
um you can tell all the good ones are
taken
uh to the
to 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 contacts that you're doing and then
a big giant button of how happy are you
clearly everybody here is a nine
ding
once you uh enter in some information
it'll give you some happiness back it'll
throw up a little um
little quote and actually i think i
spent about half the time looking for
quotes
seriously it's not that easy
and then every other time you log in
it's even easier it doesn't need to know
who you are because it has a cookie uh
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 this is being stored in
a database actually
and works great on
phones as well as tablets etc
this is the codebase it's shockingly 54
lines long this includes the inline html
the uh everything to deal with the
database
uh 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 just 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 and total cost of
ownership you know 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 you know that
might necessarily need us need a server
um
that that's typically the the problem
people walk in the door 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 uh
yeah thank you
um
yeah so i i have a raspberry pi in my
bag they're really cool uh the one i
have in my bag is running closure it's
it's great but i'm not gonna talk about
it uh
so if you are interested in the
raspberry pi i want to 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 um
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
uh
various cloud tools that we operate so i
once again found myself in the world of
of web programming
and uh callback uh
hell
and um i'd heard things about frp and uh
over the past few weeks um with the help
of my co-workers and a few friends i
think i've reached light at the end of
the tunnel so i'm going to try this
explanation on you guys
um
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 a
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 you know
some of which i've skimmed 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 flapjacks
paper but they talk a lot about time
varying values which one way to think
about them in closure terms as
is as reference types
however in
closure if you want to know the value of
a reference type you you are the one
responsible for asking the question the
value is not pushed to you you
dereference it with a little you know 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
uh
to working with sequences enclosure with
the sequence library you have these
streams of events that you can you know
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 you know a callback
is a void type
for those of us enclosure
it means we don't have a value
it's you know usually the function that
adds a callback is void it doesn't
return anything and of course callbacks
are not values so what this allows one
to do is work with
events
as streams of values and compose in the
same way we would any stream of any
value
so
there's tons of stuff again i'm not
going to 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 going to talk about
what does slapjacks give us
um so a lot of the frp solutions claim
to give you all kinds of stuff
to you know that help you solve all
kinds of things in in the domain you
know this is this is how you build web
apps now we give you uh templating
language language and
graphics 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 event there are
user events you know bob click the
button there are events that come from
the dom that you may or may not have
initiated like success of an ajax
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 your streams there's
this general notion of consumption and
generation and fusion and filtering and
so on
um
what flat jacks gives you is a general
set of tools for for doing what a lot of
people who work with events
noaa's 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 how's that look it look awesome yeah
so we're traveling back in time
oh
maybe the full screen is a little too
awesome
how's that yeah
all right so uh what we're looking at
here is the
sort of the fibonacci or the factorial
of browser event things which is you
know we're going to add some numbers
together
in a cool way
um so you'll you know 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
um if i type in something that you can't
meaningfully sum like you know some
string
nothing blew up
so um
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
here
um so this is all of the closure code
that drives all the behavior on the page
we just saw
i'm going to 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 parsefloat 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
parsefloat doesn't doesn't work with so
that's just a 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's
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 is
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 same 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 sum b 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
flapjacks 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 and 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 going to flip open the
html going on here
so i have an onload which calls my
closure script function with the id of
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 uh
one of the few
i o functions that comes with flapjacks
which is a function called insert value
b which will continue 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
um
so i guess i'll just stop and respect
people's time um 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
enclosure in the jvm for doing
interesting things
and
thanks
you