Bummer! This is just a preview. You need to be signed in with a Pro account to view the entire video.
Start a free Basic trial
to watch this video
Your Language is My Compilation Target: A Whirlwind Tour of ClojureScript
43:22 with Ben OrensteinThis session will be an introduction to ClojureScript, a powerful lisp that compiles into JavaScript. Come be tempted by ClojureScript's functional nature, immutable data structures, superior asynchronous strategies, and sane floating point operations.
-
0:00
When are we gonna pair our program?
-
0:00
Well, this right here.
-
0:02
So one way to show people a language is to like put up a 100 slides and, you know,
-
0:07
be like oh, here are the interesting features of ClojureScript, and
-
0:09
why you might wanna use it.
-
0:10
Or you could write a real program, and show people how it works, and do it live,
-
0:14
which is my preferred way of doing things.
-
0:15
So, we are going to be coding part of flappy bird today.
-
0:18
Everybody know flappy bird?
-
0:19
You're familiar with this, right?
-
0:21
If you don't, it's a very simple game.
-
0:22
You'll get the gist of it.
-
0:24
So unfortunately it's only, I only have 45 minutes so,
-
0:27
I'm not gonna be able to code, we're not gonna be able to code,
-
0:29
we're not gonna be able to pair a program, all of flappy bird.
-
0:32
But, we can write the interesting parts.
-
0:35
So, what I've done, is I wrote the boring parts already.
-
0:37
Those parts are hidden away and cool.
-
0:40
And we're just gonna write the interesting parts.
-
0:42
So, I'll show what this is.
-
0:43
So, very quick overview.
-
0:44
What is ClojureScript?
-
0:45
ClojureScript is a language that compiles into JavaScript.
-
0:48
What is the best part about ClojureScript?
-
0:49
You don't have to write JavaScript anymore.
-
0:52
You can use a programming language, that writes JavaScript.
-
0:54
I know this is like I've come into the lion's den, and
-
0:56
told the lion like, you lion, don't worry you don't have to be a lion anymore.
-
0:59
You can stop being a cat.
-
1:01
But I think it's an awesome language.
-
1:04
I think you should, I'm, I'm glad to see there are people here.
-
1:06
I hope you have an open mind.
-
1:08
There are some really interesting things in ClojureScript.
-
1:09
And we're gonna try to bump into them organically.
-
1:11
Now let me show you one cool thing that's gonna happen right away.
-
1:15
Take a look at the label over here, the Start, underneath Flappy.
-
1:18
I'm going to change this to Art, which is appropriate.
-
1:21
And all I did was save that file.
-
1:23
And notice the browser, this is the browser over here, it's a Chrome, updates.
-
1:26
We can change it to tart, and we get that, or just start.
-
1:30
So, I had this really interesting thing going, which is called live reloading.
-
1:33
So, I have a plugin for
-
1:34
ClojureScript called Figwheel, which is kind of an awesome library name.
-
1:38
And figwheel is basically, setup a web socket connection from the browser,
-
1:42
to our code, and every time I save one of these CloJureScript files.
-
1:46
They get recompiled, cuz it is compiled into JavaScript,
-
1:48
on the fly, and then the browser goes oh, hey I noticed, or I guess [INAUDIBLE] hey
-
1:51
I noticed you changed that file, hey browser, here's some new code.
-
1:54
Reload that live.
-
1:55
And because of some of the properties of ClojureScript,
-
1:57
it's actually quite easy to write code that is reloadable on the fly.
-
2:00
And so you'll see me do some more things like that are reloading like this.
-
2:04
So, let's actually start our game.
-
2:06
And just see how how much we've got so far.
-
2:09
So, there have been better games.
-
2:12
So far collision detection, not 100% quite yet.
-
2:17
So basically Flappy moves to the right.
-
2:20
And the parts we're gonna write are jumping.
-
2:21
Like I can't jump right now, if I click, Flappy does nothing,
-
2:24
I think it's an interesting thing oh, okay, just like scrolled off.
-
2:26
So, if I can't jump I don't, there's no gravity,
-
2:30
I'm not doing any collision detection with the, the pipes, the pillars.
-
2:34
But we're gonna write those things, but one thing I wanna show, while I'm here,
-
2:37
just to show that this is pretty actually really live,
-
2:40
I am gonna change the horizontal velocity, and save this file, ready?
-
2:43
Save. [SOUND] The game just got a lot harder,
-
2:46
so, let all those var, I have a bunch of of sort of constants here that
-
2:49
determine where Flappy starts, and how tall Flappy is, and
-
2:52
how far apart the pillars should be, and blah, blah blah and all of those
-
2:56
things are in fact, I can update any of these live, and you might see me do this.
-
3:00
For instance, to make the game a little bit easier.
-
3:01
When I add collision detection, I'm pretty bad at Flappy Bird, actually.
-
3:04
And so, I'll like take the pillars and sort of stretch them apart.
-
3:07
I know you can do that without reloading, which I think is really, really cool.
-
3:10
But let's start writing our very first function.
-
3:12
And that'll start bumping into real ClojureScript functionality.
-
3:15
So, let's make Flappy jump.
-
3:18
So, in real Flappy Bird, every time you click, or I guess,
-
3:21
tap on your screen, it's a mobile thing Flappy's supposed to, you know,
-
3:24
sort of have a vertical velocity, and then sort of sink back down to the ground.
-
3:27
Kinda [UNKNOWN] by gravity.
-
3:29
So, let's right now, the rough model of this program is a very typical functional
-
3:36
set up, which is there's a bunch of data, at almost sort of a global level.
-
3:41
So, it's a big map.
-
3:42
It's like a hash.
-
3:43
There's a big map that has all of the variables of the program.
-
3:47
And this map is constantly being updated, basically every eight milliseconds.
-
3:50
And then we take all the data in that map, and we pass into a render function, and
-
3:53
the render function paints the game, using just that data, that, all that,
-
3:57
all that, everything that we need is in that map.
-
3:59
So this map, works its way through a series of functions, that update it.
-
4:04
And each function has a small responsibility for updating things.
-
4:07
So the very first thing we wanna write, is the map function.
-
4:10
So, basically all the functions that we're gonna write today,
-
4:14
take the entire state of the world, and then return a new copy,
-
4:16
of the state of the world, having affected it in some way, or not.
-
4:20
[BLANK_AUDIO]
-
4:22
So, let's write jump.
-
4:23
So, jump is really easy.
-
4:25
Now, one weird thing.
-
4:26
Fir, first thing to look at here.
-
4:28
I've defined, this is a partly how you define a function.
-
4:30
So, I define jump right here.
-
4:32
And I've said, right now, jump is just the identity function.
-
4:35
Identity is a function that takes whatever you give it, and returns it to you.
-
4:39
And I want this because,
-
4:40
there are other functions in this code calling jump already, and
-
4:43
they give jump a state, and they want back a state that's been effected potentially,
-
4:46
and so, identity just takes that state, and returns it wholesale.
-
4:49
That's a get, here's the state, nothing's happened.
-
4:51
So, this basically just keeps my code from blowing up, every time I click,
-
4:54
cuz when I click, it's actually calling jump, but
-
4:56
nothing happens because we just have the identity function.
-
4:59
So, let's rewrite jump.
-
5:01
Here is how you write a functioning in Clojure.
-
5:03
It looks basically like this.
-
5:04
And I'll write it in pieces and explain what I'm doing.
-
5:07
So, defn, defn says, I'm going to define a function now.
-
5:10
The function's name is jump.
-
5:11
Notice something weird is happening, we have prefixed notation, so
-
5:14
in ClojureScripts, the very first thing you type in a set of parens,
-
5:18
is the function name, and then the remainder things are an argument.
-
5:21
So, we have defn, which is a call to say create a function.
-
5:23
The function's name is jump, and this is an [UNKNOWN].
-
5:26
You can say state, you can say world, you can say foo.
-
5:29
Those would all be parameters to this function.
-
5:32
So, I'm jump is fine here.
-
5:34
I'm gonna redefine it below.
-
5:35
If that'll work fine.
-
5:36
We'll just leave this identity thing here for a moment.
-
5:39
so, we'll say, jump takes a state.
-
5:42
And what does it do?
-
5:42
Well, it's actually pretty easy.
-
5:44
All we need to do is add in a couple values to this current state of the world.
-
5:48
So, the way you do that enclosure is with assoc.
-
5:51
So let's, let's look at a ripple real quick.
-
5:54
So, lets' say we have here's what a map looks like in Clojure.
-
5:57
Like, this says, this is like a hash.
-
5:58
This says the val, you know, key foo goes to three.
-
6:02
And if I took assoc of foo goes to three, and said, I want you to associate
-
6:10
bar goes to four, we get back, bar goes to four, foo goes to three.
-
6:15
By the way, these data structures are immutable.
-
6:16
Now, what does that mean?
-
6:18
It means you never change them in place, ever.
-
6:19
Assoc is now taking that map, and manipulating it.
-
6:23
And giving you back a new one, and giving you back that same map.
-
6:27
It is taking it and returning a new one.
-
6:28
This is an interesting idea.
-
6:30
I think it's really powerful.
-
6:31
We'll get into this a little bit more.
-
6:32
But all this, these core data structures, the arrays, the maps, the vectors,
-
6:36
all these things are all immutable.
-
6:38
So, here's what we're gonna do.
-
6:39
We're gonna call assoc on state.
-
6:41
So, we're saying, hey, state.
-
6:43
I want you to set a new value, for the following keys.
-
6:46
So, user-has-clicked, needs to be true.
-
6:48
Cuz now we've clicked.
-
6:49
Jump is like a click.
-
6:50
We need to set the time of last click, because we need to know,
-
6:54
the game needs to know, when did the user click, because that,
-
6:57
that length of time that's elapsed, affects how much gravity affects Flappy.
-
7:00
Cuz we want Flappy to jump, and then coming crashing back down to the earth.
-
7:04
So, we need to record when the last click was, so
-
7:05
that we can make some calculations.
-
7:07
So, record the time of last click, and I'm gonna,
-
7:09
I'm gonna pull the time of last click out of state.
-
7:12
So, I'm gonna get from state, the current time.
-
7:15
It looks like this.
-
7:18
I'm gonna actually grab a little more real estate here.
-
7:21
And flappy-velocity we need to set.
-
7:24
So, when we actually make Flappy jump we set it with a jump-velocity.
-
7:28
And jump-velocity is defined up above.
-
7:30
It's a global.
-
7:30
It just says, when you do click,
-
7:32
how much of a vertical impulse do we give to Flappy?
-
7:36
So, fingers crossed, we'll save this, and click, and we'll see Flappy jump.
-
7:39
Hey!
-
7:41
Flappy jumps, and is affected by gravity now,
-
7:43
cuz that user has clicked true, means now Flappy is affected by gravity.
-
7:47
Can I get a little [SOUND] you guys excited?
-
7:49
[SOUND] Hey!
-
7:52
Thank you, so we have our first function, live coded for you.
-
7:55
This is custom home grown, organic code hand put together for you, right here.
-
8:01
This is a very sustainable conference.
-
8:02
This kinda thing is important to all of you, I know.
-
8:05
So here, so questions so far.
-
8:07
What do you think of this?
-
8:08
Are you freaked out?
-
8:09
Are you worried?
-
8:09
Are you bored?
-
8:11
Tell me some reactions or questions or thoughts.
-
8:13
Yeah.
-
8:14
>> Hold on, I've got a mic for you.
-
8:18
>> With ClojureScript, do,
-
8:19
do the functions, do they all have to have one parameter in and one parameter out?
-
8:22
Or can you have multi in and out?
-
8:24
>> Nope it's not like Haskell.
-
8:26
it, it, the functions can have as many parameters, in and out as you want.
-
8:29
So, you can return a collection from a, a function.
-
8:31
There's basically one return value, I'm pretty sure.
-
8:34
But you can say,
-
8:35
I'm gonna return you a whole map of 25 things, which actually this function does.
-
8:39
So when we call assoc state, and
-
8:40
we add these three things in there, we get back the whole state map.
-
8:43
And the state map is actually pretty big, and
-
8:45
I can show it to you really quick, actually.
-
8:47
So, I added a thing to print the, the state map, as the game goes on.
-
8:51
And you can see it down there.
-
8:55
Data is flowing through this thing.
-
8:56
And we're, we're, we're re, basically reprinting this every eight milliseconds.
-
8:59
You can see the time delta is going up, meaning it's been long since the, the,
-
9:02
the game time started.
-
9:03
The current time is incrementing.
-
9:05
Our exposition is incrementing.
-
9:07
Things like that.
-
9:08
Things are changing.
-
9:09
But we're, we're constantly returning this map through our function pipeline.
-
9:12
So, you can of this like basically a pipeline of
-
9:13
functions that update what's going in the world.
-
9:15
And then we take the very final map of state, and we call, say, hey render.
-
9:20
Render this whole thing.
-
9:21
And we get what's in, in the browser.
-
9:22
Good question.
-
9:24
Other questions.
-
9:28
>> How ugly is the JavaScript that the compiler spits out?
-
9:32
>> How ugly is it?
-
9:33
It's not bad.
-
9:34
It's actually pretty reasonable.
-
9:35
so, there are several modes for compilation.
-
9:38
So, in development mode it uses reasonable symbol names.
-
9:41
Like reasonable variable names, reasonable function.
-
9:42
Keep, like maintains the function names, thing like that.
-
9:44
So, the code I actually the output of JavaScript is actually fairly readable.
-
9:47
I find my self not needing to go to it very often,
-
9:49
because ClojureScript actually has source maps.
-
9:52
So, let's actually break our function real quick.
-
9:55
And instead of assoc [INAUDIBLE] all this, well we'll do that, but
-
9:59
then we will throw.
-
10:01
nope, and let's see, now when I jump, let's see if that's actually through.
-
10:11
Put that through, let's get rid of this.
-
10:19
It's not assoc that.
-
10:21
Instead let's throw here.
-
10:23
Let's, save.
-
10:28
[SOUND] Are we actually throwing?
-
10:37
[SOUND] Did I filter on my console.
-
10:39
I don't think I am.
-
10:44
Well, that's you can kinda see it here.
-
10:46
So, it's not jumping to the line with the,
-
10:47
you may be right about that but you can see barely probably.
-
10:53
That these right here [UNKNOWN] dot cljs,
-
10:55
like I'm actually getting real source in the browser.
-
10:58
So, when things blow up, it blows up on the actual line of the ClojureScript,
-
11:01
not on the line of the JavaScript.
-
11:03
Which is like a super nice thing, like really good free debugging.
-
11:06
And you can do, like,
-
11:06
normal things like moving through thing, moving the code, and all that.
-
11:09
Yeah, great question.
-
11:10
>> Anyone else?
-
11:13
>> Yeah.
-
11:15
>> Yeah, could you show the.
-
11:16
>> Hold please- >> I'll, I'll repeat the question.
-
11:17
>> The rule is waiting for the microphone.
-
11:18
Sorry, rules are rules.
-
11:20
>> Cramping my style.
-
11:20
[SOUND]. [BLANK_AUDIO]
-
11:24
>> So, because ClojureScript is doing things is working with immutable data
-
11:28
structures, and JavaScript inherently doesn't support that.
-
11:31
>> Yep. >> Does that mean that if you look at
-
11:33
the profiler tab, you see a lot of member usage, or does their shortcut tricks for.
-
11:38
>> That is such a good question, and that, that so, yeah we have these immutable data
-
11:41
structures, which me, and I'm constantly returning this new state map, right?
-
11:44
And so, I must be like building up these tons and tons of intermediate things.
-
11:47
And it's kind of true and kind of not.
-
11:49
So, Clojure uses a really smart technique called structural sharing.
-
11:53
So, if I have a vector of a million elements, and
-
11:55
I change one of the very ends, or one of the mil, any,
-
11:57
any one of at random, rather than copying those million elements, elements and
-
12:01
having one changed, it insteads holds those elements in a tree, effectively.
-
12:06
And will chop off one branch of the tree, replace that one thing, and
-
12:09
point to the rest, to the the original.
-
12:10
Does that make sense?
-
12:11
So, like-
-
12:13
>> [INAUDIBLE]. >> Exactly the tree grows.
-
12:15
And so like, this grows at like log 32 of something, of like, of the size of the,
-
12:19
the things in there.
-
12:20
Like it has a very, very high branching factor.
-
12:22
So you get a lot of reuse.
-
12:23
And it actually turns out to be like,
-
12:24
really quite efficient, in terms of speed and memory use.
-
12:26
That was one of the big problems you have to solve right away when you start doing
-
12:29
mutable data structures, is how do we sufficiently share the old stuff?
-
12:32
But since the old stuff can never change,
-
12:34
you can safely point to it in the new data structures.
-
12:37
Yeah, it's a really good, that's a good intuition, a good,
-
12:39
good thing to ask, ask about.
-
12:41
And solved, I think, pretty nicely.
-
12:42
And the, this implementation has been copied like Closure's implementation of,
-
12:45
I think, like hash map tries or something, or trie mapped hashes or some crazy thing.
-
12:49
Has been like, they're pulling that into Scala.
-
12:51
And like, this, so this, this was sorta like almost a research problem for
-
12:54
a little while, and there wasn't a really good implementation.
-
12:56
And now, this is being like, sort of spreading through the world.
-
13:00
Yeah.
-
13:01
Got more.
-
13:02
[BLANK_AUDIO]
-
13:05
>> It's working, Ben.
-
13:06
>> It is working, right?
-
13:08
Also note that it hasn't blown up either.
-
13:11
[LAUGH].
-
13:12
>> It looks pretty ClosureScript looks pretty Lispy.
-
13:15
>> Mm-hm.
-
13:16
>> Is that what it's based on?
-
13:18
>> In fact it is, yeah.
-
13:19
ClosureScript is a Lisp, yep.
-
13:21
If you use Steam if you use Closure like so, Closure and ClosureScript
-
13:25
are basically the same language, they just compile the different targets.
-
13:28
Closure compiles to JVM, ClosureScript compiles to JavaScript.
-
13:32
And yeah, if you've used Steam or Common Lisp, it's a very, very similar language.
-
13:36
Yep. >> Are you using,
-
13:38
are you using something Closure specific for your view layer here?
-
13:41
Or-
-
13:42
>> yeah. Good question.
-
13:43
I love this.
-
13:45
let's, let's open this bit.
-
13:49
So, this is something called Sablono.
-
13:53
So, this is how you draw things in Sablono.
-
13:54
For instance, this is how you draw a pillar.
-
13:56
So you pass it some variables that it needs.
-
13:58
And then we make a div, and then we make another div, with some style, and
-
14:02
some height.
-
14:03
Here is the full, this is the full thing basically, that, that is [UNKNOWN] Flappy.
-
14:08
So, we have a div, with a class of board, on mouse down we bind to this thing.
-
14:12
So, capture the clicks.
-
14:13
There's our score.
-
14:15
A little bit of conditional here, and, here's a nice thing about this,
-
14:19
it's like, notice we can use like we can use Lisp sort of,
-
14:21
we can use this language right in our template, much like other things, but
-
14:24
we have a div and we wanna map pillar on pillars.
-
14:27
So, we're actually mapping this function up here, for
-
14:29
every pillar in our collection to, to sort of render each of those.
-
14:32
[BLANK_AUDIO]
-
14:34
Yep.
-
14:36
Other questions? These are great questions.
-
14:39
You guys are killing it.
-
14:40
[BLANK_AUDIO]
-
14:43
All right let's write more ClosureScript.
-
14:45
So, that was a pretty easy one.
-
14:46
Let's write something a little bit more complicated.
-
14:48
Let's go back to where we were.
-
14:49
Let's make sure jump still works.
-
14:51
Yeah, it does.
-
14:53
And then we crash the bottom.
-
14:54
Okay. That's cool.
-
14:55
so, has anyone played the original Flappy Bird?
-
14:59
Yeah, okay.
-
15:00
So, in the, in real Flappy Bird, when you start,
-
15:02
Flappy is oscillating, gently, on a sine curve, until you start tapping.
-
15:09
It's just like, sort of a, a nicety of the game.
-
15:10
So, let's actually implement that right now.
-
15:12
So, let's get rid of let's define this below a sine-wave identity.
-
15:16
So, we're gonna write a function called sine-wave that again, takes a state.
-
15:19
This is gonna be what all our, our functions do.
-
15:20
Oh, actually no, there's one more thing.
-
15:22
I wanna come back here and refactor this.
-
15:25
So here here we are associating, we wanna pull, right here, we're
-
15:28
getting the value of current-time from the cur, from the state, as it's passed in.
-
15:32
Because we want to include that.
-
15:34
Or we want to set that to be time of last click.
-
15:35
There's actually a shortcut for this.
-
15:37
So, this is a key word.
-
15:38
It's like a, a symbol in Ruby.
-
15:40
It's an immutable thing.
-
15:42
It's like a little label, basically.
-
15:44
But these are actually functions.
-
15:45
So, I can put this in the function position.
-
15:47
So, rather than using this get thing, I can call,
-
15:49
current-time, as a function, on state.
-
15:52
Is that clear?
-
15:54
Is that confusing?
-
15:56
Maybe.
-
15:57
So, if we have let's say, let's, let's say x is a map, with foo going to two.
-
16:03
We got x.
-
16:06
I can call, foo on x, and get back two.
-
16:10
Weird, right?
-
16:11
But kinda handy it's gonna let us refactor this a little bit, so we just got rid of
-
16:14
that get, and now instead, we are using, this keyword as a function.
-
16:17
The keywords are functions in ClosureScript, and
-
16:20
I think we're still good, yep.
-
16:22
Yep! We appear to be still working,
-
16:24
let's go to reload just to be safe.
-
16:26
no, we broke something.
-
16:26
Oh, because we have a sine wave in progress here.
-
16:29
Let's just make sure we're good.
-
16:30
Yeah, okay cool.
-
16:32
All right, so let's implement sine-wave.
-
16:36
So, I basically want Flappy's initial path to sort of trace this nice
-
16:39
gentle sine wave up and down.
-
16:42
And how does that work?
-
16:43
Well, we'll do it like this.
-
16:44
The first thing I wanna do, is just for.
-
16:48
So, we have this variable time delta,
-
16:50
which tells us how long it's been since we started the game.
-
16:52
So, we're gonna use that as our, basically like our tick, and we're gonna feed that
-
16:55
through a sine function, that'll sort of give us this, this oscillation.
-
16:58
And it's not gonna start off very pretty, but it'll get us in the right direction.
-
17:01
So, here's how we define local variables in ClosureScript, time-delta, on state.
-
17:09
So, this right here says opens a basically, opens a, a lexical scope.
-
17:13
And says, within this list, or
-
17:15
within this scope, I want time-delta to be bound, to be bound to this value.
-
17:19
So, what, what it,
-
17:20
what I'm doing right here is pulling out the time-delta from state, and storing it.
-
17:24
Just like time-delta equals basically.
-
17:27
And now, I wanna assoc.
-
17:30
Again, we're, this is setting the value.
-
17:32
In state, I want to set Flappy's y.
-
17:36
[BLANK_AUDIO]
-
17:38
Which is just a value in there, and we're gonna set it to.
-
17:41
Hey, look at this.
-
17:42
JavaScript [INAUDIBLE].
-
17:43
[BLANK_AUDIO]
-
17:46
One sec. That's what JavaScript [INAUDIBLE] looks
-
17:49
like in here.
-
17:50
We say, this is basically saying, hey,
-
17:52
js Math, call the sin function, with time-delta.
-
17:56
Pretty painless. Didn't have to require anything.
-
17:57
Didn't have to do any fancy work.
-
17:59
Just kinda works nicely.
-
18:00
People in the back, is the font size okay, or would you like it bigger?
-
18:05
Great. okay, so
-
18:06
let's look at Flappy when we start.
-
18:09
There's Flappy.
-
18:11
Flappy's freakin out.
-
18:15
so, this is hard to tell but Flappy is in fact, tracing a sine curve.
-
18:19
It's just kind of like a really spastic, highly caffeinated one.
-
18:21
[SOUND] This is Flappy after an Aeropress session.
-
18:28
Okay, so let's smooth this out.
-
18:32
Let's make Flappy a little more reasonable.
-
18:34
Let's see if we can do both here, that'd be cool.
-
18:35
Yeah, here we go.
-
18:36
Okay. So, basically I want to apply a dampener.
-
18:40
To this value.
-
18:41
To the time delta, cuz the time delta actually gets pretty big.
-
18:44
And so we want time delta to be a lot smaller.
-
18:45
Whoa!
-
18:46
To be a lot smaller.
-
18:48
So, let's multiply it by [SOUND] this.
-
18:54
This is not a magic value at all.
-
18:59
Okay.
-
19:00
Now, you can probably just barely see that Flappy is now tracing a nice sort of
-
19:04
gentle sine curve but it's a pretty small one uh,so let's let's make
-
19:09
that sine curve [INAUDIBLE] make that buh, result a little bit bigger.
-
19:12
So here, we'll multiply by 30, the thing we just did.
-
19:18
Let's see how that works.
-
19:19
Okay.
-
19:20
Flappy is now mellow, coming down off the caffeine high.
-
19:23
Things are looking good.
-
19:25
But we're now, we're way too high.
-
19:27
This, this oscillation is supposed to take place sort of,
-
19:30
in the, in the middle of the screen.
-
19:33
So, the last thing I'm gonna do,
-
19:36
is add [SOUND] Flappy's starting state, which is held in start y.
-
19:41
To this value, and then oops, yeah, and
-
19:45
hey, we have a nice mellow oscillation in the middle of the screen.
-
19:50
If we restart, yeah, there we go.
-
19:52
That should look familiar if you've ever played the game before, this is
-
19:56
roughly what Flappy does until, you start jumping, and then you jump around.
-
19:59
All right.
-
20:00
So, we have another function written.
-
20:02
That's cool.
-
20:03
Here's the thing, though, it's sort of ugly.
-
20:07
Like I wouldn't fault you if you said, like, this looks gross.
-
20:11
And the reason it looks gross, well you could probably have several arguments as
-
20:14
to why you think it looks gross.
-
20:15
my, my position is this looks sort of gross because like
-
20:18
the interesting stuff is kind of working inside out.
-
20:20
So the first thing I do, in terms of order of operations, is actually multiply time
-
20:24
delta times this factor, and then I take the sin of that, and then I multiply it
-
20:29
by 30, and then I add the start y, and then I store it in this state map.
-
20:34
And so, like the actual flow of operations is kind of hidden, and you have to sort of
-
20:38
become a little bit of a list [UNKNOWN] yourself to figure out what's going on.
-
20:41
It's not totally clear, and so my position is that we can do better.
-
20:46
So let's do that.
-
20:49
So closure script has this great operator.
-
20:52
In fact, actually a macro.
-
20:54
And a macro is something that rewrites code.
-
20:56
So if you like metaprogramming, macros are like metaprogramming plus plus.
-
20:59
so, when we compile this code, there's actually a phase
-
21:03
where the macros in ClosureScript get a chance to manipulate code.
-
21:07
So it it gives it a, a thing, they say here's the, here's the original code, and
-
21:10
macros go, they tear it apart, and they reorder things, and they put stuff in
-
21:13
different places, and they say, here's the code, Now compile that, and run that.
-
21:17
And it lets us do some really interesting things, like,
-
21:19
kinda like change syntax, basically.
-
21:20
So here's what it can look like.
-
21:22
So, we still have a sine wave function, it still takes our state, but
-
21:25
now we're gonna use this thing called a threading operator.
-
21:28
A threading operator says, I want you to take a value and stick it into a series of
-
21:31
expressions, or a series of forms that are gonna come next.
-
21:34
So first we're gonna grab our time delta out of the state like we did before.
-
21:38
Okay, and now I want you to f, the next thing you need to do,
-
21:42
if you look above, is multiply that by our,
-
21:44
our smoothing factor, our dampener, and I'm gonna do that this way.
-
21:50
And this actually, will take, well, the way this works when you see this arrow,
-
21:54
it says, okay, evaluate this form.
-
21:55
We're gonna get our time delta, take the result of the value in that form, and
-
21:59
stick it right here.
-
22:02
Basically feeds it, threads it, I'm gonna move that to the top so
-
22:05
you can see that better, threads it into this spot for us.
-
22:11
So, now that I've redefined sine wave, let's see, woop, it blew it up.
-
22:15
Where is our error?
-
22:23
No protocol so,
-
22:30
oh right, because sine wave needs to return.
-
22:33
We need to take this value, so let's take this value.
-
22:36
We're basing,
-
22:37
the issue is that we're not returning the map that we promised we'd returned.
-
22:40
So let's assoc state flappy-y, and
-
22:45
this will take the time delta, multiply it by this, and then feed it right here.
-
22:51
So, this map, this thing,
-
22:52
this little weird arrow thing is called the thread [UNKNOWN].
-
22:54
It threads it into the last spot of all the forms that remain in the pipeline.
-
22:59
So now, fingers crossed so this may work.
-
23:02
See. [SOUND] oop.
-
23:07
[LAUGH] Flappy's fell from the ceiling.
-
23:11
I think, yeah, okay.
-
23:12
So we're back to where we were before.
-
23:13
Where we are now actually, this is just multiplying,
-
23:16
we're not taking the sine yet.
-
23:18
But you'll see Flappy is slowly moving down,
-
23:19
because he's being multiplied by, this, this, dampener, again and again.
-
23:24
So, let's come here, and now,
-
23:26
the next thing we need to do is to call sine on this, right?
-
23:28
So sine, jsmath of the result, which we don't need to specify, we just,
-
23:32
it just knows it's gonna feed it in there, and now, you can see,
-
23:36
flappy's back to its like, gentle but small sine wave.
-
23:40
Now we can, the next thing we do is multiply that by 30, right?
-
23:43
So you multiply it by 30, now we're here.
-
23:45
The next thing we need to do is add, just the start and save and bam!
-
23:51
Pretty good, right?
-
23:53
So, this function that we just wrote here, is equivalent to the one above it.
-
23:57
These two sine-waves do the same thing, but one is inside out, effectively from
-
24:03
order of operations, and one perceives linearly through a series of forms.
-
24:07
This is one of the niceties that Lisp gives you, Lisp in general,
-
24:10
the half macros.
-
24:10
They give you the ability to sort of rework the,
-
24:12
the syntax when it makes sense for you.
-
24:15
This is sort of a limited use of, hey I can like, I can decide how to
-
24:18
reorder these forms and what this macro does when we call this, is it,
-
24:21
in fact, really rewrites it to be this.
-
24:25
The output of this,
-
24:26
of this macro is this code that then gets, gets compiled and executed.
-
24:31
So, thoughts?
-
24:33
Questions?
-
24:34
Emotions?
-
24:36
This, thumbs up.
-
24:37
I had a double thumbs up right there.
-
24:38
That was awesome. That's a good emotion.
-
24:39
>> [INAUDIBLE] >> Yeah, the question is, can I-
-
24:42
>> Rules are rules, questions go into the microphone.
-
24:44
>> How about, can I just, can I just repeat them?
-
24:45
>> No, I would much rather have them speak into the microphone.
-
24:47
>> Why was it?
-
24:48
>> If you insist.
-
24:49
I was just asking to make sure if you could,
-
24:53
yeah, delete that out since now you've, you've put in there so-
-
24:56
>> In fact, yes. >> And this is,
-
24:57
this is a dumb question, but since I have no experience in [CROSSTALK].
-
25:00
>> Please ask dumb questions, I love dumb questions.
-
25:02
>> Do you still need the, the def as well.
-
25:03
I don't know the difference between def and defn [CROSSTALK].
-
25:05
>> Oh, such a good question.
-
25:06
That's not a bad question at all.
-
25:08
So defn says, I'm going to, I want you to bind a function to this name right here.
-
25:13
So defn says I'm going to give you a name and
-
25:15
an ARD list and a body and I want you to associate those things.
-
25:18
Def just says I want you to map a name to a name, map a name to a name,
-
25:24
so because identity is already a function, just define, anytime someone
-
25:28
references sine wave, just, instead, replace it with this function.
-
25:31
But down here I want to say,
-
25:33
I want to define a function called sine wave so I need the defn.
-
25:37
The defn actually expands to this, def sine-wave is
-
25:42
a function that takes state and then blah, blah, blah.
-
25:50
So yeah, I could re,
-
25:51
we could rewrite this is, this right here, defn I believe is even a macro.
-
25:54
I think it just rewrites it into this.
-
25:58
Good question.
-
25:59
Not, not a dumb question at all.
-
26:00
Good stuff.
-
26:01
Other questions?
-
26:04
There's one right here.
-
26:04
[BLANK_AUDIO]
-
26:07
>> Can, can you modify the generated JavaScript?
-
26:10
>> Could I modify the gener, oh, like with a macro?
-
26:12
[LAUGH] That's a good question.
-
26:15
I don't think so.
-
26:15
I mean, I guess.
-
26:17
Hm, so there's not a hook that I know of that's like,
-
26:20
okay now that he JavaScript is compiled let's get in there and mess with it.
-
26:25
This is Macros are actually make
-
26:27
transformation of lisp fairly easily because what you get.
-
26:31
So what you might have noticed which is a little bit weird is that these things,
-
26:35
this looks like code right here, this looks like a special thing.
-
26:37
This is in fact just a data structure.
-
26:39
It's a list.
-
26:40
So things in curly and, and parens are lists.
-
26:42
Whose first element is a symbol def,
-
26:43
and then a symbol sine-wave, and then a symbol identity.
-
26:45
And this right here is also a data structure.
-
26:48
It's a list whose first element is the symbol defn,
-
26:51
whose second element is a sine-wave,
-
26:52
whose third element is a vector whose argu, whose that has a state in there.
-
26:56
And then a series of forms.
-
26:58
So in fact, Lisp is written in its own data structures.
-
27:01
This is, there's a fancy word for this.
-
27:02
It's called homoiconicity.
-
27:04
Which is, I've actually written code that is, in fact, not really code.
-
27:07
This code is all data.
-
27:08
It's all data structures.
-
27:10
But I can actually evaluate those data structures and have them turn in to code.
-
27:13
And so because of this homoiconicity,
-
27:16
because I have code that looks just like the list of vec, things and vectors.
-
27:19
I can say, hey,
-
27:20
closure, here, take this data structure and perform manipulations on it.
-
27:24
Move the thing that's in the first position to the last position and
-
27:26
put this inside this and move this over there and
-
27:28
I'm just editing data using closure and that's, that's all macros do.
-
27:31
So macros are sort of made possible and easy, er, I guess easy.
-
27:34
There are other languages that have them, but
-
27:35
they're made simple because this code is in fact just data.
-
27:39
This is sort of a subtle thing to grasp it's one of those things that like you
-
27:42
hear and you're like I kinda think I know what that means but not really.
-
27:44
You kind of got to get in there and play with it a little bit.
-
27:46
So if it didn't make perfect sense to you that's totally normal.
-
27:49
You sort of have to get in there and get a little bit of experience.
-
27:51
But I can tell as someone that has a little more experience there it's a really
-
27:54
cool thing that, that let's you do some great stuff with the language.
-
27:58
You come to really appreciate it.
-
27:59
And all those weird parens that at first you're like why are all the parens there,
-
28:01
they look gross,
-
28:02
you start to really appreciate writing your code in data structures.
-
28:06
You actually do this right now by the way.
-
28:07
Everyone writes code in data structures, they're strings.
-
28:10
Your program is one long string, right?
-
28:12
So if you want to do manipulations on that and to write, have code,
-
28:14
[UNKNOWN] code you need to chop apart strings, using like reg Xs or
-
28:17
parsers, which is like actual languages use, right?
-
28:20
So we all write in data structures, they just all kind of suck.
-
28:23
Closure scripts, or closure lists in general, but
-
28:25
they're good at data structures, they're real ones that have structure and
-
28:27
you can actually get in there and edit them efficiently.
-
28:29
Good question.
-
28:32
Let's [UNKNOWN].
-
28:36
>> So once ES6 is more widely adopted by browsers, what happens to ClosureScript?
-
28:41
>> Not sure.
-
28:42
That's a good question.
-
28:43
I think it'll keep working.
-
28:44
Do you, is there anything that pops out at you as like,
-
28:45
that will stop working if ES6 gets adopted?
-
28:49
>> Not that I can think of.
-
28:50
It's, it's more a lot of the stuff that you get from languages like
-
28:54
closure script and coffee script are now being implemented natively with ES6 so
-
28:58
what, what's the benefit then?
-
29:00
>> Yeah. >> Once most of those
-
29:00
things are [CROSSTALK]. >> It kind of remains to be seen I guess.
-
29:02
At least to me like how, how much of ES6 happens and what does it look like and
-
29:05
how long does it take and does closure script stand still?
-
29:09
While that happens, like pretty unlikely to me, I think.
-
29:11
So I think, there are many languages that target that JVM and
-
29:15
many languages that target the CLR and things like that.
-
29:16
We are going to have a number of languages that produce JavaScript to let you
-
29:19
run code in the browser and people will endlessly debate which one is better and
-
29:23
which one they'll like more and whose right and whose wrong and am I a jerk?
-
29:26
Probably.
-
29:27
Other questions?
-
29:30
Yeah.
-
29:31
[SOUND].
-
29:39
>> How well does decompilation work?
-
29:42
>> How well does decompilation,
-
29:43
like can people go back from the JavaScript to the ClosureScript?
-
29:46
I have no idea.
-
29:48
The, in, in development mode the output of JavaScript is pretty predictable so
-
29:52
you could probably figure out what the original Closure script was.
-
29:55
I don't know if anyone's tried to do this.
-
29:58
in, in, production the outputted JavaScript is minified,
-
30:03
of course, but also it goes through the g, Google Closure Compiler, compiler CLS.
-
30:07
U-R-E [INAUDIBLE] and a J.
-
30:10
So Google has their own optimizing compiler.
-
30:12
So the code that ClosureScript outputs is in,
-
30:14
in fact, optimized to be optimized by the Google Closure Compiler.
-
30:19
That's not a confusing phrase at all.
-
30:21
And what comes out, it does a ton of deadput elimination and
-
30:24
it does a lot of optimization and magnification and all that.
-
30:26
So, which is,
-
30:27
one of the really nice things that comes out of that is ClosureScript, itself,
-
30:29
is like a handful of K, right?
-
30:30
Like, so if you want to send down the whole language to the browser that's a bit
-
30:33
of a bummer if you don't need it all.
-
30:35
But the cool thing is when you compile code in ClosureScript,
-
30:37
it then goes to the Google closure compiler, and
-
30:39
says, hey you never used any of this stuff over here, I'm gonna kill it all.
-
30:42
And so you get, you know, a, a smallest bit of this code that you actually need.
-
30:45
Keeps your, downloads light weight and fast.
-
30:47
Which is really cool.
-
30:49
[BLANK_AUDIO]
-
30:52
yeah.
-
30:53
oh, to your, behind, oh.
-
30:56
sure.
-
30:58
Whoa!
-
30:58
>> So you had mentioned that everybody has their own opinion on
-
31:01
what the best programming language is.
-
31:02
>> Yeah. >> I'm interested your opinion on,
-
31:04
what are the arguments or benefits of writing web apps in Closure?
-
31:07
>> What are the benefits of writing web apps in Closure?
-
31:10
So I, I don't have a ton of experience here.
-
31:12
I've written sort of one web app in closure where people paid for
-
31:14
it and money was exchanged for this, and then, like a couple others a little bit.
-
31:21
Go there.
-
31:22
And so, the benefits to me in Closure are what we've seen so far and
-
31:25
the same thing's in ClosureScript,
-
31:27
like this is basically the exact same language as Closure just it compiles at
-
31:30
the JavaScript.
-
31:31
So the immutable data structure are huge.
-
31:32
They basically eliminate a large class of bugs, where you hold on to something and
-
31:36
it gets mutated and you didn't know about it.
-
31:38
Like that whole thing goes away entirely.
-
31:40
The ability to do macros are pretty wonderful.
-
31:44
It's fast.
-
31:45
It runs on the JVM.
-
31:46
You can sort of sneak Closure into various organizations,
-
31:49
because they have JVM stuff there, but, and if so if you said, you know,
-
31:52
hey we want to use Ruby, like oh, we don't have like the setup for that.
-
31:54
All our stuff is in Tomcat or whatever.
-
31:55
But you can sneak Closure in a little bit easier, which I think is nice.
-
31:59
There's really interesting stuff happening in the language.
-
32:01
Like if you're, if you're interested in it start poking around at
-
32:03
the libraries that are coming out for it.
-
32:04
And the people that are going there,
-
32:06
to me are some of the most interesting people in the field.
-
32:08
So like, I work in Ruby primarily, I write a ton of Rails apps.
-
32:11
And a lot of really smart Ruby people that have been in the, the field for
-
32:14
a while are leaving and they're going to Closure, and they're really happy with it.
-
32:17
So, that to me is like, a huge endorsement.
-
32:18
People I respect and people who I think are technically very advanced.
-
32:21
Are really intrigued by this language which is intriguing me too.
-
32:26
>> What's, what's the process for integrating with external library so
-
32:30
let's say you wanna use moment or
-
32:31
some [UNKNOWN] or something like that >> Yeah.
-
32:33
>> Is that, is that complicated or?
-
32:36
>> It's not too bad so there are, a lot of people will wrap
-
32:40
those external libraries so there, there is like a, [UNKNOWN] wrapper.
-
32:43
For use in closure scripts.
-
32:45
So more popular languages,languages will tend to get wrapped in an API that looks
-
32:48
more closure scripty.
-
32:49
But as you saw but like as we can see right here in the sign.
-
32:52
This sign call right here, calling out to JavaScript,
-
32:54
native JavaScript is actually pretty easy and painless.
-
32:56
So if you want to you can start calling out to external libraries.
-
32:59
One thing you'll find is that this is a functional language and so when you're,
-
33:02
if you're used to something that's like it's [INAUDIBLE] and
-
33:04
object oriented language from inside a functional language you're gonna get
-
33:06
like a little bit of an impedance mismatch.
-
33:07
Right, like, it's like, this isn't quite-
-
33:08
it's not quite what I'm expecting.
-
33:10
And you'll find that like, it might ugly up your closure script a little bit.
-
33:13
But it's, it's not so bad.
-
33:15
But there is a bit of like, a parallel world developing.
-
33:18
Where it's like," Yeah, we don't really wanna use those external stuff, so
-
33:20
like, we'll build our own whatever."
-
33:22
The great stuff is being wrapped; there are j queer wrappers and stuff like that.
-
33:34
So, because, closure script is based off closure.
-
33:36
And closure is a functional language.
-
33:38
>> Yeah.
-
33:38
>> And I, it's a purely functional language, right?
-
33:41
closure. >> no, it's actually not.
-
33:43
>> It's not, okay.
-
33:43
So, would this language right here,.
-
33:47
What happens, what's up with the scoping on it?
-
33:50
So, say you wanted to call a function above it.
-
33:51
I assume that you have a main function that is essentially your single call that
-
33:55
modifies all the state in some sort of series, right?
-
33:58
>> Yup. >> And so what if you had a dependency,
-
34:00
because like you said, you have a functional program right here
-
34:04
that's actually calling the J S math function, which is calling another.
-
34:08
Function outside, so there's like a side effect there.
-
34:10
>> Yep. >> So how, I, I guess the thing is like,
-
34:12
functional thinking is a completely different than object oriented thinking.
-
34:16
And so how do you sort of prepare yourself for writing it in a functional way and
-
34:21
getting the most out of these [UNKNOWN] languages?
-
34:24
>> Prepare yourself for writing in a functional way.
-
34:25
There are a couple of good books that are, I, I, you just kinda, you need to do it.
-
34:28
Like there was a ti, a point in time where you didn't know how to
-
34:30
use object oriented programming either, right?
-
34:32
And like you wrote stuff like almost totally imperatively, and
-
34:34
you put everything in one file and there were no classes and
-
34:36
things like that, right?
-
34:37
So [UNKNOWN] kinda the same way, what I found is my program started being kind of
-
34:40
object [UNKNOWN] in the beginning but closure pushes you pretty quickly to
-
34:43
say like, you have data and you have functions, and you feed functions through
-
34:46
data and like, you start to think of your programs as transformations of data.
-
34:50
And that's basically what's happening here, right, like we start with a,
-
34:52
a state of the world, we feed that state through a bunch of functions that
-
34:56
modify it really, return new, new versions of it right.
-
34:58
And then at the end we render that whole thing.
-
35:01
And so starting the, there's a like, there's a book called The Joy of Closure
-
35:04
which is good at teaching you sort of like these functional ideas, but I just found
-
35:07
out like my, my mental model of how I, I approach things has changed over time.
-
35:12
To be more functional like that and its a number of ideas like okay most
-
35:15
things are actually data transformations, you know?
-
35:17
But I think its one of those things you just kinda gotta do it for a while.
-
35:19
I dunno if theres like, theres no shortcuts, probably.
-
35:23
Okay, we have seven minutes and 48 seconds left.
-
35:25
Lets write another function and then talk a little bit more.
-
35:27
Uh,We might even get to get the score done, before this is over, we'll see.
-
35:31
So lets talk about collision.
-
35:33
So right now Flappy oscillates, Flappy jumps, but Flappy can happily crash into
-
35:38
the ground and into the pillars and that doesn't seem quite right.
-
35:42
So let's write' collision' real quick.
-
35:46
And this is going to make our later stuff a little bit harder because we're going to
-
35:48
collide with stuff but that's okay.
-
35:50
So let's just detect if we're touching the ground first.
-
35:53
We're gonna, we'll get to higher order functions now which I
-
35:55
think are interesting.
-
35:56
So, collision, takes the state of the world,
-
35:58
like everything else, and it updates the world like everything else.
-
36:02
It updates the state with the, this game is running flag.
-
36:05
So the game is running, it goes to true when you click start, and then if
-
36:08
you crash it goes to false, which says, you know, stop, stop moving the world.
-
36:11
So the games will keep running.
-
36:13
The value we want to put in game-is-running is
-
36:17
not touching-ground state.
-
36:20
Now if I have been good and awesome, when I save this file,
-
36:24
the game will stop because Flappy is touching the ground.
-
36:27
Let's see if we can get his live road reloaded.
-
36:29
Ready?
-
36:30
Hey cool, so collision returned true.
-
36:33
Or collision rather updated game is running to false because touching ground
-
36:38
returned true.
-
36:39
Not just reverses the bullion value of whatever gets to it So
-
36:42
touching ground returned true, so not set false and we said game is
-
36:47
running to false which made this thing stop scrolling and display restart.
-
36:51
So now if we crash into the ground the game stops, cool.
-
36:55
So that's one way that flappy can collide.
-
36:59
Another way is if it touches a pillar.
-
37:01
This was a little more complicated but not too bad.
-
37:03
So you are, so the game is running, if we're gonna call and.
-
37:09
So if you ware not touching the ground.
-
37:12
And it was, if none of the pillars are in contact with flappy.
-
37:16
Right?
-
37:16
So we actually have a cool collection of pillars.
-
37:19
Pillars never go away, the just get sort of scrolled off the screen, so we can be
-
37:23
smart about it, but we'll just be dumb and set check every pillar and say for any
-
37:26
pillar or any of the pillars in contact with flappy and what does that look like?
-
37:30
Well, we'll say.
-
37:31
Not any.
-
37:33
So not any takes a function and a collection and it retu, it,
-
37:37
it evaluates and then the functions called a predicate.
-
37:40
Predicate meaning it returns true or false.
-
37:41
And so it checks that predicate against every element in the collection.
-
37:44
It gets fed in there.
-
37:46
This is probably a fair, fairly familiar concept to people.
-
37:49
So we need a,
-
37:50
and then it will return, this will return true if none of the, none of the ,.
-
37:55
Elements make the predicate return true.
-
37:57
So you'll want to say it, the game should keep running if you're not touching
-
38:00
the ground and you're not colliding with any of the pillars.
-
38:02
So that looks like this.
-
38:02
So not-any wants as its first argument a function.
-
38:05
So let's give it one.
-
38:06
Well, here's how you write a function.
-
38:07
This is anonymous function.
-
38:08
This is a function literal.
-
38:10
So it's a function that takes a pillar and it calls so
-
38:15
you are not touching a pillar if.
-
38:17
You both are in a pillar, pillar,
-
38:24
given a pillar and you are not in the pillar gap.
-
38:29
Just giving the state and the pillar.
-
38:35
[SOUND].
-
38:39
Yes.
-
38:40
So, here's our function which says, I'm gonna give you a series of pillars and
-
38:44
I want you to return true if flappy has collided with a pillar.
-
38:47
And you're collided with a pillar if you're in the pillar by an in-pillar
-
38:51
basically checks your x position, like, are you within the x of a pillar?
-
38:54
And then in-pillar-gap checks your y position basically.
-
38:59
So, you've crashed into a pillar.
-
39:00
If you're in a pillar x-wise, but you are not in the gap between the top and
-
39:04
bottom of the pillar.
-
39:06
So, that's our function.
-
39:07
So we now need to pass the collection of pillars into it, which we'll do so here.
-
39:13
So this is, you can see by indenting hopefully the, the argument.
-
39:15
So we have not-any takes two arguments.
-
39:17
The first is this function, the second is the collection of pillars.
-
39:21
Oh, and pillars needs to actually come out of state.
-
39:24
So we pull the pillars from the state.
-
39:31
Yeah. That looks good.
-
39:31
So let's see if this works for us.
-
39:37
So crash into a pillar and hey, it totally works.
-
39:39
[SOUND] None of you are very impressed.
-
39:43
[LAUGH] There you go.
-
39:46
Thank you.
-
39:47
[APPLAUSE] I'm doing this, doing it from the fly up here.
-
39:49
On the fly, you get it right?
-
39:50
[UNKNOWN] All right?
-
39:52
Cool. Tough crowd. [LAUGH].
-
39:54
Okay. So that's collision.
-
39:56
So here we have, what are we doing?
-
39:57
Yeah. So we have, high,
-
39:58
high order functions which I think is cool.
-
40:01
We have, sort of boolean flipping bits here.
-
40:03
We have and here which is nice.
-
40:04
This is, this is, probably what you'd expect like logical and effectively.
-
40:08
We have pulling [UNKNOWN] out of state.
-
40:11
So we have three minutes left so I want to implement.
-
40:13
Actually no we'll forget score.
-
40:15
Let's talk for three minutes instead.
-
40:16
Let's do like last minute questions, thoughts, concerns and then we'll wrap up.
-
40:20
And I'm happy to talk after this by the way I love talking about
-
40:23
stuff obviously so.
-
40:27
>> Hi, Ben. Can you hear me?
-
40:30
You're still writing ruby I assume?
-
40:33
I'm curious how you feel learning closure has affected your, the way you right ruby.
-
40:38
>> Yeah that's a great question.
-
40:39
It definitely has affected it.
-
40:41
This idea of thinking about programs as transformations of
-
40:44
data that are functional, hasn't impac,
-
40:46
impacted my ruby because Ruby is actually a fairly functional language itself.
-
40:49
It was inspired by things like Small Talk, and, which is, I guess, object oriented.
-
40:52
But it was inspired by a little bit of lisp in there, right?
-
40:55
And so, Ruby has a handful of pretty powerful functional idioms.
-
40:59
Like this, like, not any.
-
41:00
Ruby has a very similar thing.
-
41:01
You know? Doing things like
-
41:03
mapping over a collection, all that stuff, is very easy.
-
41:05
And Ruby has, like, these beautiful blocks.
-
41:07
But it's also object oriented, so it kind of has like a little bit of a marriage and
-
41:11
a slight mismatch, like you have some objects and you have some functional and
-
41:14
I have found that writing FlowJo script has pushed my Ruby more functional.
-
41:19
Now when I do that, I feel like things actually turn out really well,
-
41:21
like I don't think I've ever refactored to make something more functional and
-
41:24
gone, now I don't really understand it.
-
41:27
I find functional programming to be a little bit more disciplinarian.
-
41:30
It's a little bit more like I say I just want this thing done in this like,
-
41:33
roughly, I, I want this to happen.
-
41:35
As opposed to like, do all these things, move these things over here,
-
41:37
add this to this.
-
41:39
And so I, I think it's been a, a positive impact.
-
41:41
Also, there's a very famous quote by, I think, Eric S.
-
41:43
Raymond, which is Lisp is worth learning for the profound enlightenment you
-
41:48
get once you, sort of, once everything sort of clicks.
-
41:50
And it will change the way you use other languages even if you don't end up
-
41:53
using Lisp a lot.
-
41:53
And that's been really true for me.
-
41:55
So even if this particular Lisp doesn't, doesn't jump out of you.
-
41:58
If you if Scheme does, if Racket does, if any of those other Lisp,
-
42:02
if common Lisp does like go try a language that looks like this.
-
42:06
Especially like the weirder this looks to you.
-
42:08
The more like your initial factor is like ew,
-
42:09
ick, like the more you should try this out I think.
-
42:13
It will change how you program other languages.
-
42:14
>> Yeah.
-
42:15
>> Just a note on what you're saying, I find that my JavaScript was a lot
-
42:18
more functional and a side effect that it's a lot more testable as well,
-
42:23
so I find functional to be a lot more testable right now.
-
42:26
>> Beautiful, yeah that's the great thing.
-
42:28
So. >> Huge fan of that.
-
42:29
>> So my, my question is was, was, is, is, did you say this codes online somewhere?
-
42:35
>> Yeah it will be online.
-
42:36
>> Okay. >> I don't know let's do it now who cares.
-
42:38
Here it is. This is my
-
42:39
Gethub.com/r00k/flappy-bird-demo.
-
42:41
It's wrote full of zeroes because i chose it when I was like twelve.
-
42:45
How embarrassing.
-
42:46
Yeah so this is online.
-
42:51
This is actually forked from somebody else.
-
42:53
This is Bruce Hauman's code.
-
42:55
It was the original Flappy Bird that I sort of refactored a bunch, and
-
42:58
hacked around with and then sort of created this talk out of.
-
43:00
So you can go see his original if you want, but mine's a little better.
-
43:04
>> [LAUGH] >> It's true.
-
43:05
He had bad variable names all over the place.
-
43:09
Any other brain busters?
-
43:10
[BLANK_AUDIO]
-
43:13
>> Awesome.
-
43:14
>> All right. >> We just hit zero.
-
43:15
Well done, team.
-
43:16
Good work. Thank you very much.
-
43:22
[APPLAUSE]
You need to sign up for Treehouse in order to download course files.
Sign up