A World Without Assignment
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 65 | |
Author | ||
License | CC Attribution - ShareAlike 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/37590 (DOI) | |
Publisher | ||
Release Date | ||
Language | ||
Producer |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
Ruby Conference 201461 / 65
2
3
4
6
9
11
14
17
18
19
20
25
27
29
30
32
34
35
39
40
46
47
50
53
55
56
58
61
63
00:00
VideoconferencingPoint (geometry)Type theoryAdventure gameProper mapString (computer science)Physical systemComputer animation
00:51
Data structureComputerComputer programVariety (linguistics)PhysicalismPressurePoint (geometry)Computer programmingInterpreter (computing)Content (media)Multiplication signObservational studyData structureGroup actionXML
01:32
Expert systemFunctional programmingSelf-organizationMereologyArithmetic meanComputer programmingTwitterObservational studyProduct (business)BuildingConfidence intervalAreaTotal S.A.Video gameData structureComputer animation
02:16
Data structureProgramming paradigmBuildingPerformance appraisalMathematicsFunction (mathematics)ComputerFunctional programmingComputer programmingElement (mathematics)Programming languageProgramming paradigmNeuroinformatikFunctional programmingComputer scienceFunctional programmingComputer programmingElement (mathematics)State of matterHistory of mathematicsState observerData structureOrder (biology)Computer animation
02:51
Data structureFunctional programmingObject (grammar)Numbering schemeSingle-precision floating-point formatCloningCodeCondition numberComputer animation
03:15
Slide ruleCodeSoftware testingConcurrency (computer science)Expected valueCodeFunctional programmingFunctional programmingSoftware testingGravitationComputer programmingReduction of orderProgramming languageBlock (periodic table)MereologyPhysical systemConcurrency (computer science)Thread (computing)State of matterMetropolitan area networkArithmetic progressionView (database)Process (computing)GradientComputer animation
04:49
Positional notationFunction (mathematics)Square numberCondition numberConditional probabilityElectronic mailing listProgramming languageSlide ruleFunctional programmingDecision theoryRow (database)Dependent and independent variablesNumbering schemeMultiplication signRight anglePerturbation theoryEquivalence relationCASE <Informatik>Electronic mailing listNP-hardWave packetSpacetimeGame theoryUniform resource locatorCondition numberRootDialectCausalityLabour Party (Malta)Open setFamilyComa BerenicesSign (mathematics)CodeResultantComputer clusterRepresentation (politics)Parallel portPositional notationComputer programmingPredicate (grammar)Parameter (computer programming)Absolute valueGroup actionSystem callOperator (mathematics)Level (video gaming)NumberPower (physics)Element (mathematics)RecursionComputer animation
09:24
Condition numberFibonacci numberFactory (trading post)RecursionCanonical ensembleTotal S.A.QuicksortNumberMultiplication signStandard deviationParameter (computer programming)Fibonacci numberNumbering schemeSummierbarkeitMathematical optimizationComputer animation
10:10
System callEmpennageMathematical optimizationPotenz <Mathematik>Mathematical optimizationSystem callNumberGradientPotenz <Mathematik>CASE <Informatik>Power (physics)Multiplication signMathematicsBit rateComputer animation
10:42
Mathematical optimizationSystem callEmpennageMathematical optimizationSystem callMultiplication signProduct (business)Power (physics)SpacetimeMultiplicationBinary multiplierCASE <Informatik>Online helpNumberToken ringFunctional programmingVideoconferencingProgramming languageComputer animation
12:11
Multiplication signSpacetimeComputer programmingFunctional programmingElectronic mailing listProgramming languageInterpreter (computing)Form (programming)MereologyData structureObservational studyBuildingGroup actionComputer animation
13:02
MathematicsInterpreter (computing)Data structureNeuroinformatikLine (geometry)MathematicsFunctional programmingPoint (geometry)Computer animation
13:26
Functional programmingComputer programmingElectronic mailing listDigitizingFraction (mathematics)Order (biology)IntegerCountingComputer fontSet (mathematics)NumberArithmetic progressionData managementFluidMathematicsNominal numberPlanningParameter (computer programming)2 (number)Prisoner's dilemmaComputer animation
14:21
AliasingFigurate numberLine (geometry)CodeMathematicsPoint (geometry)MereologyIntegerElectronic mailing listParameter (computer programming)AliasingNominal numberComputer animation
15:16
MathematicsFraction (mathematics)Electronic mailing list1 (number)CASE <Informatik>Element (mathematics)Right angleNumberLine (geometry)Diskrete MathematikRoundness (object)Computer animation
16:31
CASE <Informatik>Variable (mathematics)CodeSystem callElectronic mailing listSubstitute goodStudent's t-testMultiplication signComputer animation
17:37
Stack (abstract data type)Substitute goodParameter (computer programming)Figurate numberReading (process)CodeFunctional programmingCASE <Informatik>NumberMultiplication signElement (mathematics)Mathematical analysisOrder (biology)ResultantFraction (mathematics)RecursionPoint (geometry)MathematicsGodNominal numberWordArchaeological field surveyComputer animationLecture/Conference
20:29
Condition numberMathematicsNumbering schemeElectronic mailing listFigurate numberCodeLie groupLogicCASE <Informatik>Game theoryNumberCondition numberMereologyComputer animation
21:27
Condition numberFunction (mathematics)Lambda calculusSystem callFunctional programmingProgramming languageBitLambda calculusFunctional programmingNumbering schemeElement (mathematics)Predicate (grammar)CASE <Informatik>Multiplication signElectronic mailing listImplementationOperator (mathematics)Closed setParameter (computer programming)2 (number)Inclusion mapSquare numberSet (mathematics)Right angleProduct (business)Observational studyDenial-of-service attackBit rateFilm editingGame theoryComputer programmingSystem callPoint (geometry)Open setLine (geometry)Computer animation
24:32
Numbering schemeGroup actionObservational studySpacetimeLocal ringComputer animation
24:55
Duality (mathematics)Numbering schemeNumberComputer scienceInterpreter (computing)Video gameData structureMereologyComputer programmingProgrammer (hardware)SequelNormal (geometry)Group actionObservational studyRight angle
25:33
Data structureComputerComputer programEducational softwareProgrammer (hardware)Group actionObservational studyProgramming languageMereologyComputer scienceFunctional programmingDreizehnRevision controlFunctional programmingShared memory
26:31
Computer programmingFunctional programmingTurbo-CodeMathematicsBasis <Mathematik>Functional programmingFunctional programmingAdventure gameProcess (computing)Point (geometry)Software developerMultiplication signGodSpeech synthesisCommon Language InfrastructureProduct (business)Observational studyComputer animation
27:48
Digital photographyDigital photographyPoint (geometry)Revision controlWebsiteSlide ruleComa BerenicesPresentation of a groupLine (geometry)Computer animation
Transcript: English(auto-generated)
00:21
It should be obvious by now. I've lost my voice. So if you want to see this talk with proper audio, leave the room. From the contrary, because I've been just talking about the worst. Otherwise, please be nice. And please be quiet. Keep the wrestling and the typing and everything else to a minimum
00:43
so that I don't have to use any more points than I need to. And like, this is going to be an adventure for both of us. So, Gogoruko 2010 was my first conference. Jim Weaver gave the keynote and he covered a wide variety of topics including physical chemistry, emission spectra, and this book.
01:03
He had this book recommended to him by many other nerds and he talked about the study group he set out to go through. He demonstrated the content for the first two chapters and then at the very end he pointed out that everything in the 90 minute talk he had given hadn't used assignment. And that talk by Tim Leiberg is the inspiration for this talk.
01:23
This book is the structure and interpretation of computer programs. It was the programming 101 book at MIT for a very long time. It is wonderful. So a little bit about me. I'm Aja Emerly. I utilize R&B on Twitter. I'm able to be able to meet everyone who talks. My phone is down there so you can't interrupt me tweeting your memes.
01:43
I'm the organizer on GitHub and I blog, hopefully more frequently in the future, at magnimizer.com. I'm not an expert on this stuff in any means but I have been part of three political study groups. I'm part of Seattle R&B and I'm interested in the esoteric and academic parts of programming.
02:01
I'm truthfully seeing functional programming all over the place and I knew when this talk I was reading Twitter and someone tweeted out that all of the not Ruby talks or Ruby calls this year are about functional programming and that that might be a hint. So, functional programming. What's that? Here's the Wikipedia definition.
02:21
Computer science functional programming is a programming paradigm. A style of building, structure and elements of computer programs that treats computer computation as the evolution of mathematical functions and avoids state and label data. This is a comment from one of my co-workers who I respect a lot.
02:41
The idea of mutable state is a suspicious and easing of this stuff. And these are general observations from the talk I was mentioning. So in this talk I'm going to focus on one aspect of functional programming and that is not using mutable data structures. So there will be no assignment in any of the code in this talk.
03:01
There will be not a single, single person Ruby. There's a lot of scheme in this talk and in the scheme you use setbang. So there will be no setbang. And if modifying an object seems important we'll clone and create a new one instead. Setting expectations. There are 112 slides. Lots of code.
03:20
Lots of parentheses. And no ponies. Sorry to hear me. Why should I care? So, functional programming is powerful. First of all, it's easier to test. There's less setup, less stopping and walking and you always start from your own state.
03:41
Previous tests can't pollute the state for the next test. Functional programming supports concurrency very well. If nothing's a modified state, it doesn't matter how many threads you have because you don't have to deal with blocks on shared resources. Reduced systems frequently use functional programming techniques.
04:02
When your code doesn't modify state, it's always safe to reuse it. Other programs are other parts of the same program. Gravity. Functional programs tend to be very brief and very concise. Some people think this is awesome. I am one of them. Some people think this isn't great. I am not one of them. I'm sorry if you aren't.
04:22
You already use Ruby. It blends itself very well with functional techniques. And you're probably using these techniques badly without knowing it. Do any JavaScript to guarantee you're running some functional stuff. Functional-ish stuff. And doing it badly. So you might as well do it right. And learning it in Ruby is easy.
04:41
It's easy to apply these techniques to Ruby and I find that when I'm learning a new paradigm, it's best to move it with language I'm already comfortable with. So I'm going to do this talk half in scheme, half in Ruby. I believe everyone should be able to program a language that's really hot to make it easier. I've got my slides laid out side by side.
05:00
Ruby is on the right and in red because they all start with R. Scheme is on the left and in blue. So the first thing you need to know about Scheme is that unlike Ruby, it uses prefix notation. That means the operator comes first. So instead of 5 plus 3, you have plus 5, 3.
05:20
And you're like, well, that's kind of lame. Except when you look at the next line, you see that you can do 1 times 2 times 3 with only a single times using this kind of technique. You're powerful. Grouping is pretty obvious. You never have to group things with parentheses. And you can call name functions, not just mathematical operators the same way. You can add 1 as a successor function for numbers.
05:45
So you can define functions. Define function, name, and argument. So we're defining a function called square n. And then after that is the body times n and n. And then like we have tough to end in Ruby,
06:01
we use parentheses in the scheme to denote could, blocks, or group. So the closed parentheses is the level to the end. And then again, we call that with function name and then the argument in parentheses. Conditional scheme has several conditionals. And I'm going to use a con for this talk. It's like case in Ruby.
06:21
So this is definition of absolute value. If our argument is greater than 0, we return our argument. If it is equal to 0, we return 0. If it is less than 0, we return the opposite of it. This is another conditional prefix notation. It's awesome because it can do a unary notation exactly the same way it would do a subtraction.
06:41
And because the last time I gave this talk, this blew people's minds. Yes, you can do this in Ruby. You don't have to put something after the case. If you do this, it just evaluates each of the clauses and the whens and it falls through to the first one that's truthy. And since everything is truthy or false in Ruby, this works great. I use it all the time. I learned this from one of our senior programs at Seattle RB.
07:02
Have this to your arsenal. You take nothing else and put it in this talk. So back to our conditionals. This is a slightly modified version of the scheme side. This is half a real schemer. We'll write it. It's much more condensed. I think it's pretty. You might think it has too many parentheses. To me, it's okay. You'll get over it.
07:23
Because people asked, do you also have an if-then scheme? This is defining a predicate function in bony. A predicate function is a coercive function that returns every true or false. If the temperature is greater than 65, it is bony. Pound t in Ruby and scheme is true.
07:41
Pound f in the scheme is false. And you can see the Ruby on the other side. These are exactly the same code laid out the same way in two different languages. So most functional languages heavily use lists. In scheme, we represent lists with a quote, an open parenthesis,
08:04
the elements of the list with no commas. This always messes me up when I'm switching back and forth between languages, and then a close parenthesis to close the list. I'm going to represent lists in scheme by a raise in Ruby. They are not the same at all. If you know scheme, I'm sorry. But this was the easiest way to make the parallels
08:22
for our purposes of this talk. So most functional languages make heavy use of firsts and rests. Car is first in most lists dialects. If you want to know why, ask Wikipedia. I don't have the space in voice to explain that right now. Car is just first.
08:41
Note it's prefix notation again. The function goes before the list. Cdr is rest. In Ruby to get rest, I have to do one dot dot negative one. That's gross. So I'm just going to assume that rest exists. And when I was actually building these slides, I reopened array and added the rest method and set it equal to the equivalent of self one dot dot negative one.
09:07
And when you're doing things with lists, it's often up to know if your list is empty. We have empty a in Ruby. We have null a in scheme. I am using the Canadian pronunciation of the question mark there if you've not heard that before.
09:22
And knowing if your list is empty is really important for recursion. So let's do this in the canonical recursion example that you see all the time, factorial. Here's the standard recursive definition of factorial. If our argument is one, factorial of one is one.
09:41
So we return that. Otherwise, we return the number times the factorial of the number minus one. Scheme in Ruby side by side. Here's the other canonical recursion example, Fibonacci. If our number is zero, we return zero. If our number is one, we return one. Otherwise, we return the sum of the Fibonacci of the number minus one
10:03
and the Fibonacci of the number minus two. This returns the nth Fib number. So now I'm going to go into something slightly more complicated called tail call optimization. So this is exponentiation. And specifically, this is taking the number b, the base,
10:21
if you remember your seventh and eighth grade math, and raising it to the nth power. Anything raised to the zeroth power is one. So that's our base case. If n is equal to zero, we return one. Otherwise, we multiply our base times b to the n minus one-th power. So this has a small problem, though,
10:42
is that the stack ends up looking like this. It gets more and more because we're saving off these. I'm doing two to the fourth. We're saving off these two times. Two to the third, two times two to the second, two times two to the first, two times two to the zeroth. And we can reduce this stack size with an idea called tail call optimization.
11:06
So what we're going to do is we're going to add a helper function. I'm calling this x-t. And this has an accumulator. So we now have b, the base, same as before. c is the number of times we need to raise that to a power. It's a counter, which is why it's c.
11:22
And p is the partial product, the multiplication we've done thus far. And so what we're going to do is we're going to say that if our counter is zero, we've done all the multiplications we intend to do, we're going to return p. Otherwise, we're going to take recursive call to our helper of b.
11:40
We're going to subtract one from the counter and multiply b times our product thus far. If you've used inject, you've probably dealt with these accumulators as you go before. And if our language supports tail call optimization, this will help our stack. You'll note that our original function is still there. We're hiding the helper, and we're going to call our helper function
12:01
with the same b and n, and we're going to use one. Anything raised to the zero is one. That's our base case as the initial partial product. So when we run this in a language that's tail call optimized, this is what our stack ends up looking like. We don't end up accumulating those two times that need to keep going. So we don't have as much stack to unwind,
12:21
and it uses less space. So this is a semi-contrived example that I'm going to go into now. This is my favorite thing to test a new functional language on, and part of a study group was Seattle RB that we just finished on a book called Build Your Own LISP in C. And we were building a language that if you squinted really hard,
12:43
it might have been a LISP. It's a really good book. I recommend working through it, but it's not going to teach you a LISP. One of the last assignments was write a functional program using this LISP-ish language. So this was the one I chose. It's a little more complicated than some of the stuff I've shown you, which is why I like it, and I think it's kind of cool.
13:01
And the problem is making change. It comes from the structure and interpretation of computer programs, that book I referenced earlier, chapter one, and the book phrases it this way. How many different ways can you make change for a dollar given half dollars, quarters, dimes, nickels, and pennies? And this is too complicated to dive straight into. So the first thing you do is you want to simplify that.
13:26
And I end up with, how many ways can you make some amount with some coins? And this phrasing is way more simple and way more general. And from this, I get a basic function outline. I'm going to define a function count change, and it's going to have two arguments, amount and coins.
13:42
I'm going to say that amount is the number of cents. If you've done any work in programming using money, you know that you almost always want to represent it as an integer number of pennies, because dealing with floats when you can only have two digits of precision is a pain. And I'm going to say that coins is the list of coin denominations.
14:02
I'm going to assume that I'm living in Fort Knox, and I have an infinite number of any given denomination, but I have a set of denominations. I'm also going to assume that my denominations are in descending order by value.
14:21
So back to my phrasing before. How many ways can you make some amount with some coins? Well, that's still hard enough that I can't figure out what the first line of code to write is, so I'm going to simplify again. How many ways can you make one cent in using no coins? This is the audience participation part of the talk. How many ways can you make one cent using no coins?
14:43
So that makes it easy. I'm going to have a case statement, and if I have no coins, I can't make change. So let's try running it. Again, one cent is our amount. That first argument is an integer number of cents, and my coins is a collection of denominations, so it's an empty list.
15:00
Zero. Awesome. Because I am limited to slides, and I wanted to keep these in the realm of readable for humans, I'm going to alias count change to cc, just to make it easier to see from that one. So rerun it to make sure that that worked. Awesome. Next problem. How many ways can you make one cent using pennies?
15:21
Yep. Like that. If you feel like you're doing your third grader's homework right now, you should. So we're going to add another case. When the amount we're looking for is equal to the first element of our denominations list, we can make change one way. Awesome. Run it. Still works.
15:42
Slightly more tricky. Five cents using pennies. How many ways? Yep. Looks like that. So now things get a little more complicated. I'm going to need to add a case for that. And I'm going to walk you through what this line means in English. If you've taken discrete mathematics or done any combinatorics,
16:03
this is a pretty standard way of doing it. We're going to assume we're going to use one of the first coin, and then we're going to try to count the number of ways that we can make change of the remaining amount. So amount minus coins first is saying we're going to use one penny. We're going to end up with four coins, and we're going to figure out how many ways you can make four cents using the same coins.
16:24
So we run it. Five cents. One penny. One way. Okay, we're doing some good so far. How many ways can you make five cents using nickels and pennies? Yep. One nickel. Five pennies.
16:41
So let's try it and see if our code works. That's not right. So something went wrong. For most of you, I'm guessing it's not obvious right now exactly what's going wrong, and it wasn't to me. So what I did is I substituted the args in for the variables in the code.
17:02
And let's look at it one case at a time. Well, the list five one is not empty. The array five one is not empty, so we're going to skip that case. We have this case here. We're trying to make five cents. We have a nickel, so we return one. Well, that's not right, because that misses the case where we don't use nickels at all.
17:20
So we need to add a recursive call here. What we need to do is we need to say, okay, it's great that you can use nickel, but you should also try to make that same amount using everything but nickels, which is coins.rest. So let's see if this works. That worked great. Even more complicated. How many ways can you make ten cents using nickels and pennies?
17:43
Three. Two nickels, a nickel and five pennies, and ten pennies. Let's see if we got all the gazes down. That's not right again. So again, let's substitute in the arguments and figure out where we're going wrong.
18:02
Well, we skipped the first case again. We skip the second case now, because ten does not equal five. So there's something wrong in our recursive case, our fallback case. And again, we're missing a case where we don't use nickels at all.
18:21
And so we need to add that case in. We're going to add the number of ways to make our ten cents using everything but our first coin denomination to the number of ways to make ten cents using our first coin denomination. When I was taking combinatorics, a professor called this weirdo analysis. You claim that the first element of your collection is the weirdo,
18:42
and you count all the ways to do something with the weirdo, and all the ways to do something without the weirdo, and you add them together. So if that helps you remember this technique, awesome. I'm sure that Professor Levin would be very happy. So we now want to rerun our code. We get three, which is the right result. So now I put my QA hat on from when I was doing QA,
19:03
and I ask awesome questions, such as, how many ways can you make seven cents using only nickels? Well, the answer is zero. And I'm going to run the code. You get this. So that's not right. Also, it's not good. So what's going on?
19:22
Substitute the arg's in again. So I've grayed out everything that we skip. What we end up with is this case where we're going seven minus five is two, and we're trying to make two cents using nickels. And we just keep ending up in this case. So the next time we go through, we're trying to make negative three cents using nickels. And then we're trying to make negative eight cents using nickels.
19:43
And eventually we run out of stack, and that's bad. So I think we're missing a case. We're missing a base case to prevent infinite recursion. And that's this case. If the amount we're trying to make is less than the first coin in our denominations array, we should try to make that amount using whatever's left in the denominations array.
20:05
This is where I am absolutely 100% assuming that the coins in the coins array are sorted in descending order. Since I get to decide who calls this and how they call it, I'm going to say that's a fair assumption to make. If I'm really worried about it, I can sort that array in a helper function before calling into this recursive code.
20:23
And if I do that, it works. So at this point, we're ready to tackle the original problem. How many different ways can you make change of a dollar given half dollars, quarters, dimes, nickels, and pennies? And the answer is 292.
20:41
So here's the same code in the scheme. It's exactly the same cases as the Ruby. We have a cond instead of a case. We're using null question mark instead of empty. We're turning zero in that case. We have a less than again with prefix notation. Car instead of first. We have the case where our amount is equal to the first coin in our set.
21:03
We're doing one plus, figuring out the number of ways to make the amount with the rest of the coins. And so on. It's exactly the same code. More parentheses, but the logic that we just applied to Ruby applies directly to Scheme and vice versa. You can really tell when you're looking at some of the stuff that Ruby was heavily influenced by LISPs.
21:23
Because Scheme is a LISP. I left that part out, sorry. So a little bit more fun on functions. This is a function called member. In Ruby we call it include question mark, but every other language I have ever used calls it member.
21:40
Basically we're saying, given a list L and something, some item N, is N in the list L? At first we check and see if we have an empty list L. If we do, then clearly N can't be in it, so we return false. Remember, pound F is false. Otherwise we take the car of L, the first element of L, and see if that's equal to the thing we're looking for.
22:02
Well if it is, then the thing we're looking for is clearly in the list. So pound T for true. Otherwise we see if the thing we're looking for is in the rest of the list, the tail of the list. So pretty straightforward. Here's the exact same thing in a smaller font, because I want to show something very clever here.
22:23
This is me defining the predicate any, which exists in Ruby, basically like this. I've grayed out the stuff that I didn't have to change. The only thing I had to change was the stuff in bold.
22:41
This points out to me that all of these recursive functions, these operations on list, end up looking a lot the same. So all it does is it takes, instead of a thing to look for, it takes a function that's a predicate that returns true or false. And it tells you if any of the members of that list are true for that predicate. Here's the full implementation. Again, we check to see if our list is empty and return false if it is.
23:04
Otherwise we see if our predicate is true for the first element, just like we saw if our first element was equal to the thing we're looking for. And return true in that case. If neither of those cases passes, we then go to the case where we try to find out if our predicate is true for the rest of the list.
23:20
So if I'm going to do this, I'm going to use anonymous functions. On the left, you see how you define an anonymous function in Scheme. On the right, you see how you define an anonymous function in Ruby. They look a lot alike, don't they? I'm using the lambda syntax, not the stabby-proc syntax or the proc.new syntax on purpose.
23:42
In this function, all it does is squares the argument. In Ruby, you have to do .call with the argument. In Scheme, you throw an extra set of parentheses around your lambda and put the argument at the end of the, right before the closing paren. So here's mean calling or any function with, in the first line, a lambda
24:06
that returns true if any of the elements are greater than five, less than five. That returns true. In the second case, it's turning true if any of the elements are equal to five, and that's false. And so at this point, I'm running out of voice, I'm running out of time.
24:23
But I intended this talk to be kind of a functional programming 101. In the end, it's actually just the first half hour of functional programming 101, and I highly encourage you to learn more. So some resources. This is the little schema. This book is awesome. Seattle RB is starting a study group tonight for this book.
24:42
I highly recommend that you start a study group for this book at your workplace with your friends and your local Ruby meetup. It's easy, it's short. You can read it in a weekend, but I and the book do not recommend that. It has space in it for jelly stains. And it is also written entirely in Socratic dialogue. Questions on the left, answers on the right.
25:02
A number of people who are not at all technical but not consider themselves programmers, I've seen picked this book up, and just follow along because it's not intimidating. And it's really awesome. I didn't bring my copy with me, but you should go buy one. Ryan has a copy of the Will O'Meller. This book has two sequels, The Seasoned Schemer and The Reasoned Schemer.
25:24
There's also The Little Lisper and The Little O'Meller. And they're all written in this style and they're all delightful. This is Destruction Interpretation of Computer Programs. It is also known as the wizard book in the way that computer scientists like to give their very heavy technical manuals very unintimidating names.
25:46
So I was part of a study group with Ryan Davis and Aaron Patterson about three years ago now, Ryan. It took us nine months to get through this book. It only has five chapters. That should tell you something. It's dense. I also know that I became a significantly better programmer in Ruby and in any other language I've ever used by finishing this book.
26:17
If you're the kind of person who likes lectures, there are open courseware lectures from the late 80s to go along with this.
26:24
The sweaters are awesome. They really are. I really highly recommend it. If you're more like me and you're an auditory learner, there's a bunch of talks on Confreaks that kind of give you an introduction to functional programming. Functional Programming in Ruby by Pat Shaughnessy at Go Ruko 2013 is great.
26:44
Parenthetically Speaking by Jim Weirich at Go Go Ruko 2010 is the talk that I referenced. Sadly, only the first 45 minutes were captured and put online and that's most of the physical chemistry and less of the nerding. You should still watch it though because physical chemistry is awesome.
27:02
Functional Principles for OA Development by Jessica Kerr at Ruby Midwest 2013. This talk is on turbo and I am intimidated and delighted by Jessica on a regular basis. If you want someone who's a little more animated than me, watch this talk. Also really, really, really well done mathematically.
27:20
I hand-waved a lot of the math. And then why not, Adventures in Functional Programming was a RubyConf keynote at RubyConf Denver. And I was in the room and I've watched the talk twice because I could barely follow along. And I had finished SICP at that point. But Jim just did an amazing job. You know, little baby steps from this is a stabby proc to oh my god, I don't understand what's going on anymore.
27:46
And you should totally watch it. It's an amazing talk. Photo credit for the pony. Thank you guys for being nice. And I like dinosaurs. I'm giving out dinosaurs to folks who teach me something or ask interesting questions.
28:03
I think I've got about 60 left. So you should come find me at some point. I saw folks taking pictures. These slides are already online at my website because I gave this talk at Mountain West RubyConf. I will also post this version of the slides within the next hour, phagomizer.com.
28:22
You can see them. I am on speaker if you want to read this presentation. Other than that, thank you all very much. I can probably take a couple of questions because my voice is holding out.