3 <link rel=
"stylesheet" href=
"css/csshake.min.css">
4 <link rel=
"stylesheet" href=
"css/animate.css">
5 <link href=
"https://fonts.googleapis.com/css?family=Press+Start+2P&display=swap" rel=
"stylesheet">
7 href=
"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/styles/atom-one-dark.min.css">
8 <script src=
"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/highlight.min.js"></script>
9 <script>hljs.initHighlightingOnLoad();
</script>
10 <title>Crazy Wide-Eyed Functional Programming
</title>
14 font-family: 'Press Start
2P', cursive;
18 background-color: #f98012;
19 background-image: url(
"img/tile.png");
20 background-repeat: repeat;
22 image-rendering: crisp-edges;
23 background-position-x: -
33px;
24 background-blend-mode: multiply;
34 letter-spacing: -
20px;
35 transform: rotate(
90deg) scale(
1,
1.5);
43 font-family: 'Press Start
2P', cursive;
44 text-shadow:
2px
2px
0 #
000;
50 text-shadow:
2px
2px
0 #
000;
56 text-shadow:
10px
10px
0 #
00000069;
62 box-shadow:
10px
10px
0 #
00000069;
65 background: #
6187a8e3;
70 justify-content: center;
75 #cloudguy, #cloudguy2 {
78 justify-content: center;
87 justify-content: space-around;
106 #cgquotes, #cloudguy2
> div
> div {
108 text-shadow:
2px
2px
0 #
000;
121 image-rendering: optimizeSpeed; /* STOP SMOOTHING, GIVE ME SPEED */
122 image-rendering: -moz-crisp-edges; /* Firefox */
123 image-rendering: -o-crisp-edges; /* Opera */
124 image-rendering: -webkit-optimize-contrast; /* Chrome (and eventually Safari) */
125 image-rendering: pixelated; /* Chrome */
126 image-rendering: optimize-contrast; /* CSS3 Proposed */
127 -ms-interpolation-mode: nearest-neighbor; /* IE8+ */
134 #rant .shake-constant, .crazy, .span {
135 display: inline-block;
138 #rant .shake-opacity {
150 box-shadow:
10px
10px
0 #
00000069;
151 border:
2px solid black;
152 background-color: #
3f6382;
157 box-shadow:
10px
10px
0 #
00000069;
158 border:
2px solid black;
165 span[class^=
"code-friends"].on, span[class^=
"code-friends"].on
> span, span[class^=
"code-friends"].on
> span
> span {
166 color: #f98012 !important;
169 span[class^=
"promise"].on, span[class^=
"promise"].on
> span, span[class^=
"promise"].on
> span
> span, span[class^=
"promise"].on
> span
> span
> span {
170 color: #f98012 !important;
190 <div style=
"height: 20%; text-align: center;">
191 <img style=
"height: 100%; display: block; margin-left: auto; margin-right: auto; margin-bottom: 10px;" src=
"img/cloudguy.gif" />
192 <div id=
"cgquotes" style=
"width: 80%; margin: auto;">Welcome to the talk!
</div>
197 <li>Thanks for the opporunity to talk about programming with you all
</li>
202 <div class=
"slide-title">=<< What's up with that Title?
>>=
</div>
207 <li>A few people asked me about the title, so I thought I'd clear up what it means
</li>
212 <div class=
"slide-title">=<< What's up with that Title?
>>=
</div>
213 <div class=
"slide flexotron idk">
214 <div style=
"justify-content: right;">
215 <img class=
"shake-constant shake" src=
"img/wide-eyed-crazy.png" style=
"width: 70%; margin-right: 10%;">
217 <div style=
"justify-content: left">
218 <div style=
"display: flex; align-items: center; width: 70%">
219 <div id=
"rant" class=
"textbox" style=
"display: block;height: auto; width:100%; margin-left:10%;">
220 <span class=
"crazy">It’s functions,
</span><span class=
"shake-constant shake-opacity">pure
</span><span class=
"crazy"> functions! Pure functions and their values, PURE FUNCTIONS FOREVER AND FOREVER AND FOREVER A HUNDRED YEARS
</span><span class=
"shake-constant shake-opacity">monad
</span><span class=
"crazy">... some... things... Me and
</span><span class=
"shake-constant shake-opacity">monads
</span><span class=
"crazy"> runnin' around and...
</span><span class=
"shake-constant shake-opacity">applicative functor
</span><span class=
"crazy"> time... a- all day long forever... All a - a hundred days
</span><span class=
"shake-constant shake-opacity">applicatives
</span><span class=
"crazy"> and
</span><span class=
"shake-constant shake-opacity">functors
</span><span class=
"crazy">! Forever a hundred times.... OVER and over
</span><span class=
"shake-constant shake-opacity">monad transformers
</span><span class=
"crazy">... adventures dot com... W W W dot at
</span><span class=
"shake-constant shake-opacity">lambda calculus
</span><span class=
"crazy"> and
</span><span class=
"shake-constant shake-opacity">category theory
</span><span class=
"crazy"> dot com w..w..w... function composition adventures... Ah- hundred years… Every minute
</span><span class=
"shake-constant shake-opacity">referential... transparency
</span><span class=
"crazy"> dot com.... w w w a hundred times...
</span><span class=
"shake-constant shake-opacity">composition
</span><span class=
"crazy"> dot com...
</span>
224 <div class=
"fig">Fig
1.1 What most people thing a typical functional programming advocate looks like
</div>
228 <li>Regarded as eccentric crazies with wild ideas
</li>
229 <li>Spout nonsense like
"monads" every
2 seconds
</li>
235 <div class=
"slide-title">=<< Obligatory Quote
>>=
</div>
240 <li>Before I get to far in to it, I want to add some framing to the talk
</li>
241 <li>My goal is not to teach you functional programming, my goal is to spark some curiosityt
</li>
246 <div class=
"slide-title">=<< Obligatory Quote
>>=
</div>
247 <div class=
"slide flexotron">
248 <div class=
"textbox">If you wish to build a ship, do not divide the men into teams and send them to the forest to cut wood. Instead, teach them to long for the vast and endless sea.
</div>
252 <li>Before I get to far in to it, I want to add some framing to the talk
</li>
253 <li>My goal is not to teach you functional programming, my goal is to spark some curiosityt
</li>
254 <li>And I think this obligatory quote (every good talk has a quote) conveys the framework I used when writing these slides
</li>
255 <li>Also we like boats and ships and stuff like that here, so make sense I guess.
</li>
260 <div class=
"slide-title">=<< Obligatory Quote
>>=
</div>
261 <div class=
"slide flexotron">
262 <div class=
"textbox">If you wish to build a ship, do not divide the men into teams and send them to the forest to cut wood. Instead, teach them to long for the vast and endless sea.
<br /><br /> - Some French Guy. Idk. Who cares, I'm not cultured. I'm Australian.
</div>
266 <li>Before I get to far in to it, I want to add some framing to the talk
</li>
267 <li>My goal is not to teach you functional programming, my goal is to spark some curiosityt
</li>
268 <li>And I think this obligatory quote (every good talk has a quote) conveys the framework I used when writing these slides
</li>
269 <li>Also we like boats and ships and stuff like that here, so make sense I guess.
</li>
270 <li>And of course, don't forget attribution. So that everyone knows you're cultured and read important things
</li>
271 <li>With that in mind, don't take any code examples too seriously, they are to demonstrate the big picture idea.
</li>
276 <div class=
"slide-title">=<< What is this Talk About?
>>=
</div>
281 <li>So what is this talk about?
</li>
282 <li>Let me start by telling you some things it is not about
</li>
283 <li>Which is something you're not supposed to do as an educator but whatever
</li>
288 <div class=
"slide-title">=<< What is this Talk About?
>>=
</div>
290 <h1>This talk is
<span class=
"highlight">not
</span> about:
</h1>
291 <div class=
"textbox" style=
"width: 60%; margin: auto; text-align: left;">
294 <li>Convincing you to stop using whichever language you like
</li>
295 <li>Maths nonsense
</li>
296 <li>So what is it about?
</li>
302 <div class=
"slide-title">=<< What is this Talk About?
>>=
</div>
303 <div class=
"slide flexotron">
304 <div style=
"text-align:center; font-size:60px; text-shadow: 4px 4px #000; padding:20px;" >Perspective
</div>
308 <li>When trying to explain to someone why they should learn functional programming, there are many perspectives to try explain it from. For this discussion, I've settled on a very meta one. Perspective itself. As said, this is not a talk about haskell, it's about viewing programming through different perspectives
"</li>
313 <div class="slide-title
">=<< What is Functional Programming? >>=</div>
314 <div class="slide flexotron
">
315 <div style="text-align:center; font-size:
60px; text-shadow:
4px
4px #
000; padding:
20px;
" >Programming with functions.</div>
319 <div class="slide-title
">=<< What is Functional Programming? >>=</div>
320 <div class="slide flexotron
">
321 <div style="text-align:center; font-size:
60px; text-shadow:
4px
4px #
000; padding:
20px;
" >Programming with functions.<br /><br />No, really. Everything is a function.</div>
325 <div class="slide-title
">=<< What is a Function? >>=</div>
326 <div class="slide flexotron
">
327 <div style="text-align:center; font-size:
60px; text-shadow:
4px
4px #
000; padding:
20px;
" >A mapping between sets that associates every element of the first set to exactly one element of the second set.</div>
331 <li>It's important to understand that that's it.</li>
332 <li>This is different to functions in procedural languages - actually the name "function
" is a misnomer in that context. Really they should be called prodedures or subroutines (hence the name procedural)</li>
333 <li>A function is a mapping. It's equivalent to something like an array in PHP. It associates one value to another one</li>
334 <li>In the same way that a PHP array cannot mutate state, a function cannot</li>
335 <li>This has some interesting consequences...</li>
340 <div class="slide-title
">=<< What is a Function? >>=</div>
342 <h1>No equivalent constructs for:</h1>
343 <div class="textbox
" style="width:
60%; margin: auto; text-align: left;
">
349 <li>Probably a bunch of other constructs I forgot</li>
352 <div class="textbox
" style="width:
60%; margin: auto; margin-top:
10px;
">*In pure functional programming, there are true variables. That is, once you declare the value of a variable, you cannot change it. Contrast this with procedural languages where you can reassign a variable whenever you like.</div>
356 <div class="slide-title
">=<< Huh? >>=</div>
357 <div class="slide
"></div>
360 <li>And of course this all begs the question....</li>
366 <div class="slide-title
">=<< Huh? >>=</div>
367 <div class="slide flexotron
">
368 <div class="textbox
" style="text-align:center; font-size:
40px; text-shadow:
4px
4px #
000; padding:
20px;
" >Who in their right mind would wanna do that?!</div>
372 <li>You're trying to tell me FP is awesome be because it has ... less features?</li>
373 <li>This is true, but it makes no difference. You can accomplish anything in FP that you can accomplish in a procedural language</li>
378 <div class="slide-title
">=<< Huh? >>=</div>
381 <div class="textbox
" style="width:
60%; margin: auto; text-align: left;
">
383 <li>Learning is good</li>
384 <li>Brain plasticity</li>
385 <li>Greater perspective</li>
391 <li>The best answer I can give is, "learning is good
". I think that's something everyone at moodle can agree on</li>
392 <li>Learning FP is gonna require you to wrestle your brain in to shapes it's never taken before. Which will leave it with the plasticity to learn a greater variety of things you encounter.</li>
393 <li>It will also make the math/logic part of your brain very buff</li>
394 <li>As we know, the brain has 3 main cortexes. The passion cortex, the power cortext, and the logic cortex</li>
395 <li>As programmers we need to engorge mostly the logic cortext, but also the passion cortex - as this is a profession that involves other people.</li>
396 <li>Communicating about programs written in the functional style is actually easier than the programs written in the procedural style. More on that later</li>
397 <li>And lets not forget that our very own MoodleNet is written in Elixir. A functional language.</li>
402 <div class="slide-title
">=<< Paradigms >>=</div>
403 <div class="slide flexotron
">
404 <div style="text-align:center; font-size:
60px; text-shadow:
4px
4px #
000; padding:
20px;
" >Paradigms</div>
408 <li>Let's talk about paradigms for a bit</li>
409 <li>In particular, let's talk about the two most widely used paradigms. Which also happen to be the most at odds</li>
414 <div class="slide-title
">=<< Paradigms >>=</div>
415 <div class="slide flexotron
">
416 <div class="textbox flexotron
" style="position: relative; width:
30%; height:
50%; margin-right:
20px;
">
417 <span class="textbox
" style="box-shadow: none; position: absolute; top: -
20px; left:
30px;
">Declarative</span>
418 <div class="textbox
" style="position: relative; width:
80%; height:
60%;
">
419 <span class="textbox
" style="box-shadow: none; position: absolute; top: -
20px; left:
30px;
">Functional</span>
420 <ul style="text-align: left; margin-top:
65px;margin-left:
40px;
">
428 <div class="textbox flexotron
" style="position: relative; width:
30%; height:
50%; margin-right:
20px;
">
429 <span class="textbox
" style="box-shadow: none; position: absolute; top: -
20px; left:
30px;
">Imperative</span>
430 <div class="textbox
" style="position: relative; width:
80%; height:
60%;
">
431 <span class="textbox
" style="box-shadow: none; position: absolute; top: -
20px; left:
30px;
">Procedural</span>
432 <ul style="text-align: left; margin-top:
65px;margin-left:
40px;
">
443 <li>So here they are. Declaritive and imperative, and inside those we see sub-paradigms (there are more, for example SQL is declaritive but not functional, and Assembly is imperative but not procedural - although the vast majority of imperative languages are indeed procedural):</li>
444 <li>And then inside the boxes we see some examples of language that embody that paradigm</li>
445 <li>For the purposes of this talk it's probably OK to just think of declaritive and functional as interchangeable, and some for imperative and procedural. I'll probably mix them up</li>
446 <li>So why am I showing this? Well, let's look at this through a different perspective... Some of you might have realised that imperative and declaritive are both words used to describe human language, and that's relevant</li>
447 <li>Learning a new paradigm is beneficial the same way learning a new human language is</li>
452 <div class="slide-title
">=<< Gramatical Mood >>=</div>
453 <div class="slide flexotron
">
454 <div class="textbox
" style="position: relative; width:
30%; height:
50%; margin-right:
20px; padding-top:
40px;
">
455 <span class="textbox
" style="box-shadow: none; position: absolute; top: -
20px; left:
30px;
">Declarative</span>
456 A sentence which expresses a statement of fact.
457 <ul style="text-align: left; margin-top:
65px;margin-left:
40px;
">
459 <li>I like climbing.</li>
460 <li>Ice is cold.</li>
461 <li>Mathieu is shredded.</li>
464 <div class="textbox
" style="position: relative; width:
30%; height:
50%; margin-right:
20px; padding-top:
40px;
">
465 <span class="textbox
" style="box-shadow: none; position: absolute; top: -
20px; left:
30px;
">Imperative</span>
466 <span>A sentence which expresses instructions, or requests.</span>
467 <ul style="text-align: left; margin-top:
65px;margin-left:
40px;
">
468 <li>Shut the door.</li>
469 <li>Don't eat my burger.</li>
470 <li>Let's go to the pub.</li>
471 <li>Don't make eye contact with Mathieu.</li>
477 <li>We can see here that in the declaritive mood you express statements of fact. They aren't instrcutions</li>
478 <li>Contrast this with the imperative style of expression where there is a very clear instruction to carry out</li>
483 <div class="slide-title
">=<< Gramatical Mood >>=</div>
484 <div class="slide flexotron
">
485 <div class="textbox flexotron
" style="position: relative; width:
30%; height:
50%; margin-right:
20px; padding-top:
40px;
">
486 <span class="textbox
" style="box-shadow: none; position: absolute; top: -
20px; left:
30px;
">Declarative</span>
489 <div class="textbox flexotron
" style="position: relative; width:
30%; height:
50%; margin-right:
20px; padding-top:
40px;
">
490 <span class="textbox
" style="box-shadow: none; position: absolute; top: -
20px; left:
30px;
">Imperative</span>
496 <li>To make it more concise... here's the smallest definition I can think of</li>
497 <li>And this applies to programs too. In the functional paradigm we no longer have the "instruction words
" - things like, for, while, goto, variable reassignment</li>
502 <div class="slide-title
">=<< Big Brain Moment >>=</div>
507 <div class="slide-title
">=<< Big Brain Moment >>=</div>
508 <div class="slide flexotron
">
509 <div class="textbox
" style="text-align:center; font-size:
40px; text-shadow:
4px
4px #
000; padding:
20px;
" >Programming languages <span class="shake-slow shake-constant
" style="color: #f98012
">ARE</span> human languages.</div>
513 <div class="slide-title
">=<< Why is declaritive mood good? >>=</div>
518 <li>But in both cases, it seems like we lose something useful in the declaritive mode. What do we get by giving up these things?</li>
523 <div class="slide-title
">=<< Why is declaritive mood good? >>=</div>
524 <div class="slide flexotron
">
525 <div style="text-align:center; font-size:
60px; text-shadow:
4px
4px #
000; padding:
20px;
" >Atemporality</div>
529 <div class="slide-title
">=<< Why is declaritive mood good? >>=</div>
530 <div class="slide flexotron
">
531 <div style="text-align:center; font-size:
60px; text-shadow:
4px
4px #
000; padding:
20px;
" >Independant of or unaffected by time.</div>
535 <div class="slide-title
">=<< Why is declaritive mood good? >>=</div>
536 <div class="slide flexotron
">
537 <div style="text-align:center; font-size:
50px; text-shadow:
4px
4px #
000; padding:
20px;
" >Declarative programs express what <span class="shake-slow shake-constant
" style="color: #f98012
">they actually do</span> Leaving more "brain space
" to focus on solving the problem.</div>
541 <li>A declaritive program expresses its operation in terms of relationships.</li>
542 <li>In an imperative paradigm, thinking about the program means thinking about changes over time</li>
543 <li>In a declaritive one, thinking about the program means thinking about relationships</li>
548 <div class="slide-title
">=<< To Recap >>=</div>
551 <div class="textbox
" style="width:
60%; margin: auto; text-align: left;
">
553 <li>Because sometimes there is such a thing as too much freedom</li>
554 <li>Functional programming is awesome because it stops you shooting yourself in the foot</li>
555 <li>"Constraints liberate, liberties constrain
"</li>
560 <li>Some problems are simply very difficult to solve in an imperative way.</li>
561 <li>Especially when we are talking about events that are happening in parallel and may run at different speed/times</li>
562 <li>In the imperative paradigm, you quite easily come up against data races by virtue of the way the program is expressed</li>
568 <div class="slide-title
">=<< Some Code (Finally) >>=</div>
573 <div class="slide-title
">=<< Some Code (Finally) >>=</div>
574 <div class="slide flexotron
">
575 <div style="text-align:center; font-size:
50px; text-shadow:
4px
4px #
000; padding:
20px;
" >Enough of this philosophy and linguistics mumbo jumbo, already!</div>
579 <div class="slide-title
">=<< Some Code (Finally) >>=</div>
581 <h1>The Great Dividers</h1>
583 <div style="display: flex;
">
584 <pre style="margin: auto;
"><code style="font-size:
20px;
"><span class="code-friends1 code-friends4
">x = x + 1;</span></code></pre>
586 <div style="display: flex; margin-top:
20px; margin-bottom:
20px;
">
587 <span style="margin: auto;
">and:</span>
589 <div style="display: flex; margin-bottom:
50px;
">
590 <pre style="margin: auto;
"><code style="font-size:
20px;
"><span class="code-friends2 code-friends3
">function repeat(x) {
591 return x + repeat(x);
592 }</span></code></pre>
594 <h2>OK, so what?</h2>
595 <div style="display: flex;
">
596 <div class="textbox
" style="margin: auto; width:
60%; font-size:
20px;
">In the declaritive paradigm, <span class="code-friends1
" onmouseenter="activateFriends(
1, true);
" onmouseleave="deactivateFriends(
1);
" style="display: inline-block;
">this</span> code hangs while <span class="code-friends2
" onmouseenter="activateFriends(
2, true);
" onmouseleave="deactivateFriends(
2);
" style="display: inline-block;
">this</span> code runs. In the imperative paradigm <span class="code-friends3
" onmouseenter="activateFriends(
3, true);
" onmouseleave="deactivateFriends(
3);
" style="display: inline-block;
">this</span> code hangs, while <span class="code-friends4
" onmouseenter="activateFriends(
4, true);
" onmouseleave="deactivateFriends(
4);
" style="display: inline-block;
">this</span> code runs.</div>
601 <div class="slide-title
">=<< Some Code (Finally) >>=</div>
603 <div style="display: flex; margin-top:
50px;
">
604 <pre style="margin: auto;
"><code style="font-size:
20px;
">x = x + 1;</code></pre>
606 <div class="flexotron
" style="height:
80%;
">
607 <div class="textbox
" style="position: relative; width:
30%; height:
50%; margin-right:
20px; padding-top:
40px;
">
608 <span class="textbox
" style="box-shadow: none; position: absolute; top: -
20px; left:
30px;
">Declarative</span>
609 "x is the same as itself plus one.
"<br /><br /><br /><br /><br />
612 <div class="textbox
" style="position: relative; width:
30%; height:
50%; margin-right:
20px; padding-top:
40px;
">
613 <span class="textbox
" style="box-shadow: none; position: absolute; top: -
20px; left:
30px;
">Imperative</span>
614 "Evaluate the thing on the right of `=` then store it in the thing on the left of `=`.
"<br /><br /><br />
615 A list of instructions that can be followed.
621 <div class="slide-title
">=<< Some Code (Finally) >>=</div>
623 <div style="display: flex; margin-top:
50px;
">
624 <pre style="margin: auto;
"><code style="font-size:
20px;
">function repeat(x) {
625 return x + repeat(x);
628 <div class="flexotron
" style="height:
80%;
">
629 <div class="textbox
" style="position: relative; width:
30%; height:
50%; margin-right:
20px; padding-top:
30px;
">
630 <span class="textbox
" style="box-shadow: none; position: absolute; top: -
20px; left:
30px;
">Declarative</span>
631 "The repeat of `x` is `x` appended to the repeat of `x`
"<br /><br /><br />
632 An infinite list of `x`!
634 <div class="textbox
" style="position: relative; width:
30%; height:
50%; margin-right:
20px; padding-top:
40px;
">
635 <span class="textbox
" style="box-shadow: none; position: absolute; top: -
20px; left:
30px;
">Imperative</span>
636 "To evaluate the repeate of `x`, first evaluate the repeat of `x`
"<br /><br /><br />
637 ...Yeah, you see the problem?
643 <div class="slide-title
">=<< Big Brain Moment >>=</div>
644 <div class="slide flexotron
">
645 <div class="textbox
" style="text-align:center; font-size:
40px; text-shadow:
4px
4px #
000; padding:
20px;
" >Programming languages <span class="shake-slow shake-constant
" style="color: #f98012
">ARE</span> human languages.</div>
649 <div class="slide-title
">=<< Some Code (Finally) >>=</div>
651 <h1>Real Haskell Code That Runs</h1>
652 <pre><code class="haskell
">repeat x = x ++ repeat x
653 threeFs = take 3 (repeat "f
")
660 <li>Let's think about the way this is understood</li>
661 <li>To get 3 fs, take 3 fs from an infinite list of fs - totally fine, makes complete sense</li>
666 <div class="slide-title
">=<< Some Code (Finally) >>=</div>
668 <h1>Real JavaScript Code That Hangs</h1>
669 <pre><code class="javascript
">function repeat(x) {
670 return x + repeat(x);
673 threeFs = repeat("f
").substr(0,3);
675 > InternalError: too much recursion
680 <li>By contrast, this reads as "First compute an infinite list of fs
" - which as we saw before was a problem. And even that human sentence clearly has a problem.</li>
685 <div class="slide-title
">=<< Big Brain Moment >>=</div>
687 <h1>What did declaritive mode give us?</h1>
688 <div class="textbox
" style="width:
60%; margin: auto; text-align: left;
">
690 <li>Atemporality</li>
691 <li>The ability to wield infinity!</li>
697 <div class="slide-title
">=<< Promises >>=</div>
698 <div class="slide flexotron
">
703 <li>Let's think about promises...</li>
704 <li>Seems like an odd tangent but let's go with it</li>
705 <li>And just as before, I'm gonna break one of the carinal rules of teaching by telling you what promises are not...</li>
710 <div class="slide-title
">=<< Promises >>=</div>
711 <div class="slide flexotron
">
712 <div style="position: relative; text-align:center; font-size:
40px; text-shadow:
4px
4px #
000;
" >
713 <div class="angereyWrap
"><div class="angerey
">>:(</div></div>
714 <div class="angereyWrap
"><div class="angerey
">>:(</div></div>
715 <div class="angereyWrap
"><div class="angerey
">>:(</div></div>
716 <div class="angereyWrap
"><div class="angerey
">>:(</div></div>
717 <div class="angereyWrap
"><div class="angerey
">>:(</div></div>
718 <div class="angereyWrap
"><div class="angerey
">>:(</div></div>
719 <div class="angereyWrap
"><div class="angerey
">>:(</div></div>
720 <div class="angereyWrap
"><div class="angerey
">>:(</div></div>
721 <div class="angereyWrap
"><div class="angerey
">>:(</div></div>
722 <div class="angereyWrap
"><div class="angerey
">>:(</div></div>
723 Promises <span class="shake-slow shake-constant
" style="display: inline-block; color: #f98012
">do not</span> make things asynchronous!</div>
727 <div class="slide-title
">=<< Promises >>=</div>
729 <h2>What problems do promises solve?</h2>
730 <div class="textbox
" style="width:
60%; margin: auto; text-align: left;
">
732 <li>Asynchronous request management</li>
733 <li>Error handling for computations which may fail</li>
734 <li>Probably more too</li>
737 <h2 style="margin-top:
50px;
">What are promises then?</h2>
738 <div class="textbox
" style="width:
60%; margin: auto; text-align: left;
">
740 <li>A value (which may or may not be available yet) wrapped in some additional context</li>
741 <li>Functions to instantiate the wrapper (Promise.resolve, Promise.reject)</li>
742 <li>A rule for composing these wrapped values (then)</li>
748 <div class="slide-title
">=<< Promises >>=</div>
750 <h1>Terminology/syntax recap</h1>
751 <h2>JavaScript arrow functions</h2>
752 <div style="display: flex;
">
753 <pre style="margin: auto;
"><code style="font-size:
20px;
">x => x + 1;</code></pre>
755 <div style="display: flex; margin-top:
20px; margin-bottom:
20px;
">
756 <span style="margin: auto;
">is equivalent to:</span>
758 <div style="display: flex; margin-bottom:
50px;
">
759 <pre style="margin: auto;
"><code style="font-size:
20px;
">function(x) {
764 <div style="display: flex;
">
765 <div class="textbox
" style="margin: auto; width:
60%; font-size:
20px;
">A method of combining two things of the same type in to another thing that is also of the same type</div>
770 <li>A quick note on composition: So far you may have come across function composition. There's lots of different kinds of composition, but function composition is incredibly common, especially in programming. However in the example we are talking the composition of promises. In the sense that we combine to promises, and get another promise.</li>
775 <div class="slide-title
">=<< Promises >>=</div>
777 <h1>Promise composition</h1>
778 <div style="display: flex;
">
779 <div class="textbox
" style="margin: auto; width:
60%; font-size:
20px;
">The `then` method of a promise accepts a function as an argument. This function takes a value and returns a new promise. The new promise "combines
" the previous two using the "composition rule
" given to `then`.</div>
781 <div style="display: flex; margin-top:
100px
">
782 <pre style="margin: auto;
"><code style="font-size:
12px;
"><span class="promise3
"><span class="promise2
"><span class="promise1
">Promise.resolve("Some value
")</span>.then(x => Promise.resolve(x + " and another value
"))</span>.then(x => Promise.resolve(x + " and another one!
"))</span>;</code></pre>
784 <div style="display: flex;
">
785 <div class="textbox
" style="margin: auto; width:
60%; font-size:
20px; margin-top:
50px;
">There are three promises in the above snippet. <span onmouseenter="activatePromise(
1)
" onmouseleave="deactivatePromise(
1)
" class="promise1
">One</span>, <span onmouseenter="activatePromise(
2)
" onmouseleave="deactivatePromise(
2)
" class="promise2
">two</span>, <span onmouseenter="activatePromise(
3)
" onmouseleave="deactivatePromise(
3)
" class="promise3
">three</span>.</div>
787 <div style="display: flex; margin-top:
100px
">
788 <pre style="margin: auto;
"><code style="font-size:
12px;
">Promise.resolve("Some value
").then(x => Promise.reject("It's all gone wrong
")).then(x => Promise.resolve(x + " and another one!
"));</code></pre>
790 <div style="display: flex;
">
791 <div class="textbox
" style="margin: auto; width:
60%; font-size:
20px; margin-top:
50px;
">The above snippet still results in a promise, but it is a "failed
" one. Any subsequent `then` after the `reject` has no effect.</div>
796 <div class="slide-title
">=<< Promises >>=</div>
798 <h1>OK great but who cares?</h1>
799 <div class="textbox
" style="width:
60%; margin: auto; text-align: left;
">
801 <li>We are <span class="shake-constant shake-opacity highlight
" style="display: inline-block;
">declaring</span> how we want promises to compose</li>
803 The order that the promises actually resolve their values in is not important
804 <ul><li>In other words, we don't have to worry about <span class="shake-constant shake-opacity highlight
" style="display: inline-block;
">timing</span> anymore</li></ul>
806 <li>We can <span class="shake-constant shake-opacity highlight
" style="display: inline-block;
">declare</span> a failure anywhere in the chain</li>
812 <div class="slide-title
">=<< Promises >>=</div>
813 <div class="slide flexotron
">
814 <div style="position: relative;
">
815 <img src="img/thonking.gif
" />
816 <div class="thonkingWrap
"><div class="thonk
">atemporality?</div></div>
817 <div class="thonkingWrap
"><div class="thonk
">declaritive?</div></div>
818 <div class="thonkingWrap
"><div class="thonk
">functions?</div></div>
819 <div class="thonkingWrap
"><div class="thonk
">composition?</div></div>
824 <li>This sure is starting to sound familiar.</li>
829 <div class="slide-title
">=<< Promises >>=</div>
833 <pre style="margin-bottom:
50px;
"><code class="javascript
"><span class="code-friends1
" onmouseenter="activateFriends(
1);
" onmouseleave="deactivateFriends(
1);
" style="display: inline-block
">Promise.resolve</span>(<span class="code-friends2
" onmouseenter="activateFriends(
2);
" onmouseleave="deactivateFriends(
2);
" style="display: inline-block
">"We start here
"</span>)
834 <span class="code-friends3
" onmouseenter="activateFriends(
3);
" onmouseleave="deactivateFriends(
3);
" style="display: inline-block
">.then</span>(<span class="code-friends4
" onmouseenter="activateFriends(
4);
" onmouseleave="deactivateFriends(
4);
" style="display: inline-block
">x =></span> <span class="code-friends5
" onmouseenter="activateFriends(
5);
" onmouseleave="deactivateFriends(
5);
" style="display: inline-block
">Promise.resolve</span>(<span class="code-friends6
" onmouseenter="activateFriends(
6);
" onmouseleave="deactivateFriends(
6);
" style="display: inline-block
">x + " then get here
"</span>))
835 <span class="code-friends7
" onmouseenter="activateFriends(
7);
" onmouseleave="deactivateFriends(
7);
" style="display: inline-block
">.then</span>(<span class="code-friends8
" onmouseenter="activateFriends(
8);
" onmouseleave="deactivateFriends(
8);
" style="display: inline-block
">x =></span> <span class="code-friends9
" onmouseenter="activateFriends(
9);
" onmouseleave="deactivateFriends(
9);
" style="display: inline-block
">Promise.resolve</span>(<span class="code-friends10
" onmouseenter="activateFriends(
10);
" onmouseleave="deactivateFriends(
10);
" style="display: inline-block
">x + " and finally here!
"</span>))</code></pre>
837 <pre><code class="haskell
"><span class="code-friends1
" onmouseenter="activateFriends(
1);
" onmouseleave="deactivateFriends(
1);
" style="display: inline-block
">Right</span>(<span class="code-friends2
" onmouseenter="activateFriends(
2);
" onmouseleave="deactivateFriends(
2);
" style="display: inline-block
">"We start here
"</span>)
838 <span class="code-friends3
" onmouseenter="activateFriends(
3);
" onmouseleave="deactivateFriends(
3);
" style="display: inline-block
">>>=</span> (<span class="code-friends4
" onmouseenter="activateFriends(
4);
" onmouseleave="deactivateFriends(
4);
" style="display: inline-block
">\x -> </span><span class="code-friends5
" onmouseenter="activateFriends(
5);
" onmouseleave="deactivateFriends(
5);
" style="display: inline-block
">Right</span> (<span class="code-friends6
" onmouseenter="activateFriends(
6);
" onmouseleave="deactivateFriends(
6);
" style="display: inline-block
">x ++ " then get here
"</span>))
839 <span class="code-friends7
" onmouseenter="activateFriends(
7);
" onmouseleave="deactivateFriends(
7);
" style="display: inline-block
">>>=</span> (<span class="code-friends8
" onmouseenter="activateFriends(
8);
" onmouseleave="deactivateFriends(
8);
" style="display: inline-block
">\x -></span> <span class="code-friends9
" onmouseenter="activateFriends(
9);
" onmouseleave="deactivateFriends(
9);
" style="display: inline-block
">Right</span> (<span class="code-friends10
" onmouseenter="activateFriends(
10);
" onmouseleave="deactivateFriends(
10);
" style="display: inline-block
">x ++ " and finally here!
"</span>))</code></pre>
843 <div class="slide-title
">=<< Promises >>=</div>
847 <pre style="margin-bottom:
50px;
"><code class="javascript
"><span class="code-friends1
" onmouseenter="activateFriends(
1);
" onmouseleave="deactivateFriends(
1);
" style="display: inline-block
">Promise.resolve</span>(<span class="code-friends2
" onmouseenter="activateFriends(
2);
" onmouseleave="deactivateFriends(
2);
" style="display: inline-block
">"We start here
"</span>)
848 <span class="code-friends3
" onmouseenter="activateFriends(
3);
" onmouseleave="deactivateFriends(
3);
" style="display: inline-block
">.then</span>(<span class="code-friends4
" onmouseenter="activateFriends(
4);
" onmouseleave="deactivateFriends(
4);
" style="display: inline-block
">x =></span> <span class="code-friends5
" onmouseenter="activateFriends(
5);
" onmouseleave="deactivateFriends(
5);
" style="display: inline-block
">Promise.resolve</span>(<span class="code-friends6
" onmouseenter="activateFriends(
6);
" onmouseleave="deactivateFriends(
6);
" style="display: inline-block
">x + " then get here
"</span>))
849 <span class="code-friends11
" onmouseenter="activateFriends(
11);
" onmouseleave="deactivateFriends(
11);
" style="display: inline-block
">.then</span>(<span class="code-friends12
" onmouseenter="activateFriends(
12);
" onmouseleave="deactivateFriends(
12);
" style="display: inline-block
">x =></span> <span class="code-friends13
" onmouseenter="activateFriends(
13);
" onmouseleave="deactivateFriends(
13);
" style="display: inline-block
">Promise.reject</span>(<span class="code-friends14
" onmouseenter="activateFriends(
14);
" onmouseleave="deactivateFriends(
14);
" style="display: inline-block
">"Oh noes!
"</span>))
850 <span class="code-friends7
" onmouseenter="activateFriends(
7);
" onmouseleave="deactivateFriends(
7);
" style="display: inline-block
">.then</span>(<span class="code-friends8
" onmouseenter="activateFriends(
8);
" onmouseleave="deactivateFriends(
8);
" style="display: inline-block
">x =></span> <span class="code-friends9
" onmouseenter="activateFriends(
9);
" onmouseleave="deactivateFriends(
9);
" style="display: inline-block
">Promise.resolve</span>(<span class="code-friends10
" onmouseenter="activateFriends(
10);
" onmouseleave="deactivateFriends(
10);
" style="display: inline-block
">x + " and finally here!
"</span>))</code></pre>
852 <pre><code class="haskell
"><span class="code-friends1
" onmouseenter="activateFriends(
1);
" onmouseleave="deactivateFriends(
1);
" style="display: inline-block
">Right</span>(<span class="code-friends2
" onmouseenter="activateFriends(
2);
" onmouseleave="deactivateFriends(
2);
" style="display: inline-block
">"We start here
"</span>)
853 <span class="code-friends3
" onmouseenter="activateFriends(
3);
" onmouseleave="deactivateFriends(
3);
" style="display: inline-block
">>>=</span> (<span class="code-friends4
" onmouseenter="activateFriends(
4);
" onmouseleave="deactivateFriends(
4);
" style="display: inline-block
">\x -> </span><span class="code-friends5
" onmouseenter="activateFriends(
5);
" onmouseleave="deactivateFriends(
5);
" style="display: inline-block
">Right</span> (<span class="code-friends6
" onmouseenter="activateFriends(
6);
" onmouseleave="deactivateFriends(
6);
" style="display: inline-block
">x ++ " then get here
"</span>))
854 <span class="code-friends11
" onmouseenter="activateFriends(
11);
" onmouseleave="deactivateFriends(
11);
" style="display: inline-block
">>>=</span> (<span class="code-friends12
" onmouseenter="activateFriends(
12);
" onmouseleave="deactivateFriends(
12);
" style="display: inline-block
">\x -></span> <span class="code-friends13
" onmouseenter="activateFriends(
13);
" onmouseleave="deactivateFriends(
13);
" style="display: inline-block
">Left </span>(<span class="code-friends14
" onmouseenter="activateFriends(
14);
" onmouseleave="deactivateFriends(
14);
" style="display: inline-block
">"Oh noes!
"</span>))
855 <span class="code-friends7
" onmouseenter="activateFriends(
7);
" onmouseleave="deactivateFriends(
7);
" style="display: inline-block
">>>=</span> (<span class="code-friends8
" onmouseenter="activateFriends(
8);
" onmouseleave="deactivateFriends(
8);
" style="display: inline-block
">\x -></span> <span class="code-friends9
" onmouseenter="activateFriends(
9);
" onmouseleave="deactivateFriends(
9);
" style="display: inline-block
">Right</span> (<span class="code-friends10
" onmouseenter="activateFriends(
10);
" onmouseleave="deactivateFriends(
10);
" style="display: inline-block
">x ++ " and finally here!
"</span>))</code></pre>
859 <li>So, if you've ever used promises, you've been doing declaritive style programming without even realising it!</li>
860 <li>They give us some new powers, we can now write atemporal code, which explains why they emerged in JS, a place where people are constantly dealing with requests that can finish in any order</li>
861 <li>So it's super cool that people using a language very far removed from haskell ended up solving the problem in the same way</li>
862 <li>Although both are independed discoveries, I don't think it's a coincidence promises appeared given the nature of the JS world.</li>
867 <div class="slide-title
">=<< Composition >>=</div>
868 <div class="slide flexotron
">
873 <li>Let's think about composition...</li>
874 <li>I touched on it before, but it's so important that I think it deserves its own little bit</li>
875 <li>I don't really have that many slides for this bit because composition is not really something you can make drawings of easily</li>
876 <li>I do have a few illustrations though</li>
881 <div class="slide-title
">=<< Composition >>=</div>
882 <div class="slide flexotron
">
883 <img src="img/composition0.png
" style="height:
700px;
" />
887 <div class="slide-title
">=<< Composition >>=</div>
888 <div class="slide flexotron
">
889 <div style="position: relative;
">
890 <div style="position: absolute; top: -
40px; left: -
106px
">If we can go from here to here</div>
891 <img src="img/composition1.png
" style="height:
700px;
" />
896 <div class="slide-title
">=<< Composition >>=</div>
897 <div class="slide flexotron
">
898 <div style="position: relative;
">
899 <div style="position: absolute; top: -
40px; left: -
106px
">If we can go from here to here</div>
900 <div style="position: absolute; max-width:
425px; text-align: center; bottom:
149px; left:
220px
">And we can go from here to here</div>
901 <img src="img/composition2.png
" style="height:
700px;
" />
906 <div class="slide-title
">=<< Composition >>=</div>
907 <div class="slide flexotron
">
908 <div style="position: relative;
">
909 <div style="position: absolute; top: -
40px; left: -
106px
">If we can go from here to here</div>
910 <div style="position: absolute; max-width:
425px; text-align: center; bottom:
149px; left:
220px
">And we can go from here to here</div>
911 <div style="position: absolute; text-align: center; bottom: -
70px; left:
82px
">Then the composition (if it exists) goes from here to here</div>
912 <img src="img/composition3.png
" style="height:
700px;
" />
917 <div class="slide-title
">=<< Composition >>=</div>
919 <h1>OK great but who cares?</h1>
923 <div class="slide-title
">=<< Composition >>=</div>
925 <h1>OK great but who cares?</h1>
926 <div class="textbox
" style="width:
60%; margin: auto;
">Big problems can often be chopped up in to smaller, easier to solve problems. If we can be clever about how we chop them up, such that the solutions to the individual problems can <span class="highlight
">compose</span> together to form a full solution, then we can infinitely speed up the process by adding more workers!</div>
930 <div class="slide-title
">=<< Composition >>=</div>
933 <div class="textbox
" style="width:
60%; margin: auto; text-align: left;
">
935 <li>The pyramids</li>
944 <div class="slide-title
">=<< Composition >>=</div>
945 <div class="slide
"></div>
948 <li>Think about how we do dev at moodle</li>
953 <div class="slide-title
">=<< Composition >>=</div>
955 <div class="textbox
" style="margin-bottom:
20px; width:
60% margin: auto;
"><h2>Do you get one "leet
" dev to solve the whole thing?</h2></div>
956 <img src="img/
10xdev.png
" class="textbox
" style="margin-bottom:
20px; height:
60%; display: block; margin: auto; padding-bottom:
0px;
" />
957 <div class="textbox
" style="margin-top:
20px !important; width:
60%; margin: auto
">With these biceps I can solve <span class="highlight shake shake-constant
">ANYTHING</span></div>
961 <div class="slide-title
">=<< Composition >>=</div>
962 <div class="slide flexotron
">
963 <div class="textbox
"><h1>No, you get friends to take a piece and help!</h1></div>
967 <img src="img/cloudguy.gif
" />
971 <img src="img/cloudguy.gif
" />
974 <img src="img/cloudguy.gif
" />
978 <img src="img/cloudguy.gif
" />
982 <img src="img/cloudguy.gif
" />
986 <img src="img/cloudguy.gif
" />
992 <li>This is why it's worth spending the time to plan things and figure out how to "chop up
" the work</li>
997 <div class="slide-title
">=<< Composition >>=</div>
998 <div class="slide flexotron
">
999 <div class="textbox
" style="text-align:center; font-size:
40px; text-shadow:
4px
4px #
000; padding:
20px;
" >Composition is nature's greatest hack</div>
1003 <li>My goal here was to try and convince you that composition really is important and is fundamental to the way we think</li>
1004 <li>At its core, composition is about relationships, and building complexity by combining them. Hey, wasn't the whole declaritive thing about relationships?</li>
1005 <li>And that brings me to my final point</li>
1010 <div class="slide-title
">=<< Composition >>=</div>
1012 <h1>What's this got to do with FP?</h1>
1013 <div class="textbox
" style="width:
60%; margin: auto;
">When writing programs (as an individual in this case, not as a group) we naturally want to break the solution up in to "building blocks
" that we put together to solve the problem (it's composition again).</div>
1014 <div class="textbox
" style="width:
60%; margin: auto; margin-top:
20px;
">The building blocks you use matter. Some compose better than otheres. Because of all the restrictions the functional paradigm places on the programmer (lack of mutation, lack of control flow), functions in a pure language are naturally well-suited to composition.</div>
1015 <div class="textbox
" style="width:
60%; margin: auto; margin-top:
20px;
">This is becoming more relevant than ever in the age of parallel computing</div>
1019 <div class="slide-title
">=<< Composition >>=</div>
1021 <h1>What's this got to do with FP?</h1>
1022 <div class="textbox
" style="width:
60%; margin: auto;
">When writing programs (as an individual in this case, not as a group) we naturally want to break the solution up in to "building blocks
" that we put together to solve the problem (it's composition again).</div>
1023 <div class="textbox
" style="width:
60%; margin: auto; margin-top:
20px;
">The building blocks you use matter. Some compose better than otheres. Because of all the restrictions the functional paradigm places on the programmer (lack of mutation, lack of control flow), functions in a pure language are naturally well-suited to composition.</div>
1024 <div class="textbox
" style="width:
60%; margin: auto; margin-top:
20px;
">This is becoming more relevant than ever in the age of parallel computing</div>
1028 <div id="cloudguy2
">
1029 <div style="height:
20%; text-align: center;
">
1030 <img style="height:
100%; display: block; margin-left: auto; margin-right: auto; margin-bottom:
10px;
" src="img/cloudguy.gif
" />
1031 <div style="width:
80%; margin: auto;
">Thanks for listening!!</div>
1037 var div, i, j, span, duration = "";
1038 var crazyTexts = [];
1039 var opacyTexts = [];
1040 div = document.querySelectorAll("#rant
> span.crazy
");
1041 for (j = 0; j < div.length; j++) {
1043 for (i = 0; i < div[j].innerText.length; i++) {
1044 duration = Math.floor(Math.random() * 5) + 100
1045 span += "<span class=
\"letter shake-constant shake-little
\" style=
\"animation-duration:
" + duration + "ms
\">";
1046 span += div[j].innerText[i] == " " ? " " : div[j].innerText[i];
1049 crazyTexts.push(span);
1052 opacities = document.querySelectorAll("#rant
> span.shake-opacity
");
1053 for (k = 0; k < opacities.length; k++) {
1054 shrek=Math.random();
1055 opacities[k].style.animationDuration = shrek + 's';
1056 opacyTexts.push(opacities[k].outerHTML);
1060 for (l = 0; l< crazyTexts.length; l++) {
1061 allText+=crazyTexts[l] + (opacyTexts[l] ? opacyTexts[l] : "");
1064 document.getElementById('rant').innerHTML = allText;
1068 var b = document.querySelectorAll('body')[0];
1069 setInterval(function(){
1072 b.style.backgroundPosition = x + 'px ' + y + 'px';
1075 urlParts = document.URL.split('#');
1076 window.console.log(urlParts);
1077 var currentSlide = urlParts.length > 1 ? urlParts[1] : 0;
1078 var bc = new BroadcastChannel('test_channel');
1079 document.getElementById('slide-' + currentSlide).style.display = 'block';
1080 document.onkeydown = checkKey;
1082 function checkKey(e) {
1084 e = e || window.event;
1085 if (e.keyCode == '37') {
1086 if (document.getElementById('slide-' + currentSlide)) {
1087 document.getElementById('slide-' + currentSlide).style.display = 'none';
1090 document.getElementById('slide-' + currentSlide).style.display = 'block';
1092 notes = document.querySelectorAll('#slide-' + currentSlide + ' .notes');
1094 bc.postMessage(notes[0].innerHTML);
1097 else if (e.keyCode == '39') {
1098 if (document.getElementById('slide-' + currentSlide)) {
1099 document.getElementById('slide-' + currentSlide).style.display = 'none';
1102 document.getElementById('slide-' + currentSlide).style.display = 'block';
1104 notes = document.querySelectorAll('#slide-' + currentSlide + ' .notes');
1106 bc.postMessage(notes[0].innerHTML);
1113 function activateFriends(n, noshake) {
1114 f = document.querySelectorAll('.code-friends' + n);
1116 for (fr = 0; fr< f.length; fr++) {
1118 f[fr].classList.add("shake-constant
");
1119 f[fr].classList.add("shake-slow
");
1121 f[fr].classList.add("on
");
1125 function deactivateFriends(n) {
1126 f = document.querySelectorAll('.code-friends' + n);
1127 for (fr = 0; fr< f.length; fr++) {
1128 f[fr].classList.remove("shake-constant
");
1129 f[fr].classList.remove("shake-slow
");
1130 f[fr].classList.remove("on
");
1134 function activatePromise(n) {
1135 p = document.querySelectorAll('.promise' + n);
1136 for (fr = 0; fr< p.length; fr++) {
1137 p[fr].classList.add('on');
1141 function deactivatePromise(n) {
1142 p = document.querySelectorAll('.promise' + n);
1143 for (fr = 0; fr< p.length; fr++) {
1144 p[fr].classList.remove('on');
1149 "Welcome to the talk!
",
1150 "I hope we'll have fun exploring functional programming together!
",
1151 "But while we wait let's share interesting facts and anectodes :)
",
1152 "If you can be disgruntled, can you also be gruntled?
",
1153 "0.9 recurring is exactly equal to one if you think about it.
",
1154 "In English, the word
\"ghoti
\" can be pronounced as
\"fish
\".
",
1155 "Your credit card details are somewhere in Pi.
",
1156 "It takes
366 people to make sure two of them share a birthday, but only
23 people to ensure a
50% chance.
",
1157 "1729 is the best number (I checked them all).
",
1158 "The secret to strengh is to eat only a banana for breakfast.
",
1159 "All of Back to the Future happened in the past.
",
1160 "Everything is in the future.
",
1161 "We owe functional and procedural programming to the pre-Socratics, Heraclitus and Anaximander respectively.
",
1162 "Preservative has a very different meaning in many European languages
"
1165 cgq = document.getElementById("cgquotes
");
1166 numQuotes = cloudGuyQuotes.length;
1168 setInterval(function(){
1169 if (currentQuote == 0 || currentQuote == 1) {
1172 currentQuote = Math.floor(Math.random()*(cloudGuyQuotes.length - 3)) + 3;
1173 console.log(currentQuote);
1176 cgq.innerText = cloudGuyQuotes[currentQuote];
1188 function animateCSS(element, animationName, callback) {
1189 const node = element;
1190 node.classList.add('animated', animationName)
1192 function handleAnimationEnd() {
1193 node.classList.remove('animated', animationName)
1194 node.removeEventListener('animationend', handleAnimationEnd)
1195 node.style.opacity = '0';
1196 if (typeof callback === 'function') callback()
1199 node.addEventListener('animationend', handleAnimationEnd)
1202 helpers = document.querySelectorAll("#cloudguys span
");
1203 setInterval(function(){
1204 quote = Math.floor(Math.random()*(helperQuotes.length));
1205 helper = Math.floor(Math.random()*(helpers.length));
1206 helpers[helper].innerText = helperQuotes[quote];
1207 animateCSS(helpers[helper], 'fadeOutUp');
1211 angeries = document.querySelectorAll(".angereyWrap
");
1213 shakes = ["shake
", "shake-hard
", "shake-slow
", "shake-little
", "shake-horizontal
", "shake-vertical
", "shake-rotate
", "shake-opacity
", "shake-crazy
", "shake-chunk
"];
1214 for (a = 0; a < angeries.length; a++) {
1215 randomness = (Math.round(Math.random() * 10) + 1) * -10;
1216 angeries[a].style.top = ((a > 4) ? (-180-randomness) : (180 + randomness)) + "%
" ;
1217 thing = ((Math.floor(Math.random() * 10) + 1) * 9) + "%
";
1219 while (usedPositions.includes(thing)) {
1220 thing = ((Math.floor(Math.random() * 10) + 1) * 9) + "%
";
1223 angeries[a].style.left = thing;
1224 angeries[a].classList.add("shake-constant
");
1225 angeries[a].classList.add(shakes[Math.floor(Math.random()*shakes.length)]);
1226 usedPositions.push(thing);
1229 thonkings = document.querySelectorAll(".thonkingWrap
");
1230 shakes = ["shake-slow
", "shake-little
", "shake-opacity
"];
1232 for (a = 0; a < thonkings.length; a++) {
1233 thing = Math.floor(Math.random() * 4) + 1;
1234 randomnessX = -(Math.round(Math.random() * 100) + 1);
1235 randomnessY = -(Math.round(Math.random() * 50) + 1);
1237 while (usedPositions.includes(thing)) {
1238 thing = Math.floor(Math.random() * 4) + 1;
1243 thonkings[a].style.left = randomnessX + 'px';
1244 thonkings[a].style.top = randomnessY + 'px';
1245 thonkings[a].children[0].style.transform = 'rotate(-40deg) scale(1, 1.5)'
1246 thonkings[a].classList.add("shake-constant
");
1247 thonkings[a].classList.add(shakes[Math.floor(Math.random()*shakes.length)]);
1250 thonkings[a].style.right = randomnessX + 'px';
1251 thonkings[a].style.top = randomnessY + 'px';
1252 thonkings[a].classList.add("shake-constant
");
1253 thonkings[a].children[0].style.transform = 'rotate(40deg) scale(1, 1.5)'
1254 thonkings[a].classList.add(shakes[Math.floor(Math.random()*shakes.length)]);
1257 thonkings[a].style.right = randomnessX + 'px';
1258 thonkings[a].style.bottom = randomnessY + 'px';
1259 thonkings[a].classList.add("shake-constant
");
1260 thonkings[a].children[0].style.transform = 'rotate(-215deg) scale(1, 1.5)'
1261 thonkings[a].classList.add(shakes[Math.floor(Math.random()*shakes.length)]);
1264 thonkings[a].style.left = randomnessX + 'px';
1265 thonkings[a].style.bottom = randomnessY + 'px';
1266 thonkings[a].classList.add("shake-constant
");
1267 thonkings[a].children[0].style.transform = 'rotate(215deg) scale(1, 1.5)'
1268 thonkings[a].classList.add(shakes[Math.floor(Math.random()*shakes.length)]);
1273 usedPositions.push(thing);