137 RR Book Club - Functional Programming for the Object-Oriented Programmer with Brian Marick
The Rogues Discuss their latest book club book: Functional Programming for the Object-Oriented Programmer with Brian Marick.
Special Guests:
Brian Marick
Show Notes
The Rogues Discuss their latest book club book: Functional Programming for the Object-Oriented Programmer with Brian Marick.
Special Guest: Brian Marick.
Transcript
AVDI:
[Electronic noise]
JAMES:
Avdi, you sound terrible.
CHUCK:
He’s shooting us with his death ray. Aaah!
[Hosting and bandwidth provided by the Blue Box Group. Check them out at BlueBox.net.]
[This podcast is sponsored by New Relic. To track and optimize your application performance, go to RubyRogues.com/NewRelic.]
[This episode is sponsored by Code Climate. Code Climate’s new security monitor alerts you immediately when vulnerabilities are introduced into your Rails app. Sleep better knowing that your data is protected. Try it free at RubyRogues.com/CodeClimate.]
[This episode is sponsored by SendGrid, the leader in transactional email and email deliverability. SendGrid helps eliminate the cost and complexity of owning and maintaining your own email infrastructure by handling ISP monitoring, DKIM, SPF, feedback loops, whitelabeling, link customization and more. If you’d rather focus on your business than on scaling your email infrastructure, then visit www.SendGrid.com.]
CHUCK:
Hey everybody and welcome to episode 137 of the Ruby Rogues podcast. This week on our panel, we have Avdi Grimm.
AVDI:
Hello from Pennsylvania.
CHUCK:
James Edward Gray.
JAMES:
I’m on vacation.
CHUCK:
Brian Marick.
BRIAN:
Hello.
CHUCK:
I just threw you in with the Rogues. Do you want to introduce yourself, Brian?
BRIAN:
My name is Brian Marick. The reason I’m on here is I wrote a book called ‘Functional Programming for the Object-Oriented Programmer’ which I understand is going to be the topic of this talk.
JAMES:
What?! That’s what we’re talking about? That does it. I’m hanging up.
BRIAN:
[Chuckles]
CHUCK:
I thought we were talking about hats.
JAMES:
[Chuckles] And who are you, Chuck?
CHUCK:
I’m Charles Max Wood from DevChat.TV. So yeah, we’re going to talk about this book.
JAMES:
Yeah, let’s talk about it.
CHUCK:
So, what made you decide to want to write this book, Brian?
BRIAN:
Well, that’s actually an interesting question. I don’t really remember. I had been a Lisp programmer, actually an implementer of a Lisp virtual machine in ’83 and ’84. So I was really fond of Lisp and I liked Clojure at that time mainly because it was a Lisp that looked like it had a chance of succeeding the way so many other Lisps haven’t. And the reason for writing the book, I think part of it was that I was interested in Leanpub the publisher and their model for doing publishing. So I wanted to play around with that and it seemed useful to play around with something real. And I
think part of it was just that I’m one of those people who figure things out by explaining them to other people. And this was a way to figure out the functional programming part of Clojure, since Clojure, the Lisps I’d used back in the 80s were not functional at all in the style they were used, not like Clojure is. And I suppose a part of it was that in somewhere around I think 2003 in my early Ruby days, I had written a book called, or I started to write a book ‘A Little Ruby, A Lot of Objects’ which was written in the style of ‘The Little Lisper’ and now ‘The Little Schemer’. And I had some nice ideas. I thought about how to explain Ruby’s object model and it seemed that I could repurpose that whole explanation into something where I could, I guess kill two birds with one stone which is one, to explain Clojure to people, and also second to explain how object models actually work in the clearest way to explain such things which is to have the readers of the book implement on.
JAMES:
Interesting. I would say that how you talked there about how your explanations were a big motivation, and I will say that’s absolutely my favorite part of the book. There are several sections where you explain concepts that are difficult to get your head around, the Lisp evaluator recursion, monads. And you have just absolutely the easiest on ramp to those complex topics. You pretty much had me when early in the book you had pictures of fat, funny looking birds gobbling things up and puking out results. It was great.
BRIAN:
Thank you.
CHUCK:
So, there are people out there though who would balk a little bit about putting objects into your functional stuff. Did you run into any of that as people read the book?
JAMES:
That’s a good question. Do you actually use objects when you use Clojure? Out of curiosity.
BRIAN:
So first question, people haven’t balked at that. I think that generally speaking, since it’s a book for people who are familiar with object-oriented programming, they like that it’s ground on something they’re used to. And it’s interesting I think to a lot of people how things actually work in something like Java or Ruby under the hood. So I haven’t seen a lot of complaints about that. I suppose I might if it were a book for functional programming people. But I’m very much not going after that audience. And I’ve already forgotten the second question.
JAMES:
It was when you’re programming Clojure do you tend to use things like objects?
BRIAN:
No, not so much. So at the place I work we have your typical JavaScript frontend that talks JSON to a Rails thing that talks JSON to other things that live behind it. And we are pretty much using the style of just accepting the fact that JSON is arrays of hashes and that’s what comes from the frontend. And we’re pretty much persisting that all the way through to the services and then back again to the frontend without going to the step of putting, converting that JSON into some sort of object of some sort of explicit class. So we’re passing hashes around all over the place. That’s pretty much my style of programming in Clojure and increasingly now in Ruby as well. When I use something approaching objects, I tend to maybe just because I’m old fashioned, I use the multimethods that Clojure had. And multimethods are from an object-oriented point of view, you can think of instead of just switching on the type of the object to decide method to actually invoke, you can switch on the type of the object as well as any property of any of the arguments. So you tend to get things that can act like objects but you’re not really thinking of them, I think, the same way as you think of objects. In fact, in the old Lisp literature they tended to call those things generic functions rather than things that talk to actual objects. There are Clojure programmers who do in fact make use of the fact that Clojure turns into Java under the hood and will use some Clojure features that lets them essentially create classes and instances of those classes albeit without inheritance. I don’t like that because I think it makes the code more awkward to use. And it seems to be primarily used… I think the good excuse for using that is just for speed. And I’m trying not to care that much about speed, at least until some profiler forces me to care about it. So no objects, not really.
AVDI:
Brian, one of the things I liked about this book is that unlike a lot of the functional programming literature out there, it’s coming from the perspective of someone who actually has a fair amount of object- oriented experience and not just academic experience. So you’re not coming at it with just a surface level idea of objects. My understanding, obviously you’ve spent a fair amount of time in the Ruby community doing Ruby code. I understand you’ve also done some Smalltalk as well, right?
BRIAN:
Very little Smalltalk, very long time ago.
AVDI:
Okay.
BRIAN:
I was a graduate student of Ralph Johnson’s who is one of the people who wrote the ‘Design Patterns’ book. And I was sort of the odd man out in his group because they were all Smalltalkers and I was the Common Lisp guy.
AVDI:
Okay, alright. Is it fair to say that you have spent a fair amount of time writing software with objects?
BRIAN:
Yeah.
AVDI:
Yeah, that’s what I thought. Because in reading this book, you didn’t use any of the really egregious straw man arguments that I’ve seen made about objects versus functional programming that I’ve seen other places. So I’m curious. Obviously, you did start out with some Common Lisp background, but I’m curious, having done objects for a while, what was it that drove you to start writing your new code in Clojure again?
BRIAN:
[Chuckles] So, back in the 80s when I was so much a fan of Common Lisp, a lot of the reason for that was that Lisp is a so-called homoiconic language which just means that you essentially write the syntax tree of the language directly in the main data structure. So there’s not really a parsing step. Internally, you can think of Lisp programs as being implemented in lists and that’s directly how you write them. And it gives you the ability to write code that writes code very easily. And that’s in Lisps, that’s what they call macros. So macros essentially give you the ability to write your own DSL, your own domain-specific language more flexibly even than Ruby does with the one caveat that it has to have parentheses, a lot of parentheses in it. But other than that, it’s very nice to be able to write programs that write programs. And that’s the thing that originally attracted me most to Lisp and that’s the thing, the main thing that pulled me over into wanting to use Clojure in products, because I would get the power of Lisps. I was not originally sold on the advantages of functional programming per se. The common thing people say, which is that functional programs are easier to reason about, and the people who say that are confounding reason about with prove theorems about. It’s certainly the case that functional programs are easier to prove theorems about. I was skeptical that that necessarily translated into programs that were more easier to maintain, easier to find bugs in, so on and so forth. I’ve since come to the conclusion that yeah, it probably is true, that functional programs not having state modification except in very limited constrained ways really does lead to programs that are easier to understand. And so I started out for the macros and I guess I stayed for the immutable state, which does actually seem to be paying off nicely.
JAMES:
So there are a lot of good things in there. One of the things you said is that you’re really attracted to this idea of Lisp and the way you write in the abstract syntax tree. That’s actually one thing I
think I kind of question about this book, is the title of the book. It says ‘Functional Programming for the Object-Oriented Programmer’ but in some ways I think it’s actually closer to Lisp for the objectoriented programmer. For example, there are plenty of functional languages that do not have that property and behave differently. And while some of these concepts apply to it, others don’t because they don’t have that Lisp flavor. Do you think it’s specifically the Lisp style of functional programing that you’re primarily attracted to?
BRIAN:
Yeah, actually I don’t in fact talk about macros anywhere in the book, I don’t think. It’s been a long while since I read it. But that part of Lisp, I don’t really cover. The main place that I would expect criticism that it’s really about Lisp and not about functional programming, [is when] it comes to static typing. So in part two of the book, I talk [inaudible] about [inaudible] at work where you’re basically passing hashes around the system and you think of the hashes as data flowing to the system and you tack on data as it moves through the system. And then at the end, you’ve got everything you want and you’ve got pieces of it and that’s your answer. Now that is not a style that works with static typing, because those hashes as they pass through there, they keep getting new fields and in some sense they keep changing their type as they go along. So in something like Haskell which is very strongly-typed, that style of programming wouldn’t even be possible. And so I actually do confess that I’ve been sort of waiting for some Haskell person to say essentially what you just said, which is, “This isn’t functional programming at all because it doesn’t have types and that’s really important.” But I think fortunately for me, no Haskell person has ever deigned to read the book. [Laughter]
BRIAN:
So they haven’t noticed. But I think specifically with the question of how I deal with types, I think the reader perhaps should be aware that this is a somewhat Lisp-centric style, at least when you’re talking about programming. When I talk about programming in the large, it’s a Lisp style of programming in the large. The programming in the small stuff I think applies to pretty much any functional language.
AVDI:
I found that that metadata annotating stuff that you were doing, what you call data flow, one of the most interesting parts of the book. By the way, I have a minor quibble with the naming there because what I know of as data flow programming is a very different thing.
BRIAN:
Yes.
AVDI:
It’s like stuff from Microsoft Excel through LabVIEW but basically things that involve streams of events. That’s what I think of when I think data flow. But that’s a minor thing.
BRIAN:
And there’s actually another kind of data flow yet again. [Laughter]
BRIAN:
So, yeah.
JAMES:
Wait a minute. Something in computers means three different things? Come on.
AVDI:
[Laughs] But it’s an interesting approach and I’ll try to describe it quickly for the listeners that didn’t read the book. Basically you have an example where you have a list of college courses. And you’re reasoning about what courses are still available and whether somebody can sign up for a course. And you start off with a list of courses with some basic information which are just key values in the Clojure version of a hash. And you run them through a series of functions. Each function is adding new data to that hash. So I’m looking at one now that looks at the courses limit versus the courses number of registered people. And then it adds on a spaces left key to the hash and then returns the new hash with that spaces left key added to it. And it adds on an already in predicate key that notes whether this user is already in that course. It’s an interesting style. I haven’t really seen that before. Is that something that you see a lot of in Clojure programming?
BRIAN:
I don’t really know, because I don’t look at that many other people’s Clojure programs that are doing anything at scale. It’s actually interesting that if you look at Martin Fowler’s ‘Patterns of Enterprise Application Architecture’.
AVDI:
Which I do frequently.
BRIAN:
That’s what he calls, I believe transaction flow. And so he talks about that style of data, specific data flowing down through a specific slice of the program and flowing up without ever bothering to put it into objects. And so he describes that as one style. And this style, the style he spends most of the book on, is more what we’re used to where data comes in and you turn it into objects. And those objects send messages around to compute data. Now what he says in that book is I think true, which is that that approach [inaudible] falling down as you get more and more pathways through the system. And then as you try to do it that way, you’ll more quickly become overwhelmed by the complexity [inaudible] and that going to an object style is the way to deal with the complexity. And I have to confess, so I’m getting paid a fair amount of money to do exactly that old fashioned transaction flow style in this suite of apps we’re working on. And I keep waiting to, this is the time when we’re going to hit the wall and we realize that we can’t scale this anymore, that we’ve got to do something more disciplined than tacking on new keys on the hashes. We haven’t hit that point yet. I’m willing to believe that we might yet hit that point. And if that happens then we’ll have to do something different. And maybe we’ll regret that we waited too long to do that different thing. So this is an experiment. I will say one thing which is that this style seems to me pretty [inaudible] dependent on the old idea of tests examples, because I was just pairing with one of the people here today. So you’re looking at these things that are flowing through the system and because they don’t have a fixed rate, when does it get [inaudible] key put onto it? And you look at the tests and the tests are the places that give you specific examples that let you understand what the state of that hash is at a particular point in the computation. So I think if we didn’t have our tests to back us up, I can easily imagine disaster.
AVDI:
That’s a really good point. You actually answered my next question before I asked it because looking at this style of code, the first thing that springs to my mind is that if I came to a project that used this a lot and it had already been in full swing for a while, I would be very confused about which keys are available at any given point in the data flow. What am I expecting that data to look like? Because I can’t go and look at a class definition somewhere that says, “Okay here is the list of methods that’s available on that object.” But yeah, that’s a good point, is that the tests really serve to document that. And that’s actually, this is a tangent of it, but an interesting argument in favor of the doctest style tests, in Elixir I’ve been doing these examples in Elixir instead of Closure, and it allows you to stick some basic unit tests in very much an example format. Basically you type them up exactly as you would type the code into the REPL in the comment right above the function. And it seems like that would be, then it enables you to then run that code as if it were a test. And that would probably serve pretty well to document what this function is expecting, what key this function is expecting to receive.
BRIAN:
Yeah, I actually experimented a fair amount with this a little where I actually intermixed the tests in the code. In Clojure, the tests have to come after the code because you can’t use things before they’re defined. So you have to read the Clojure program from the bottom up. And you’d have the ability to just run every test individually. And that’s sort of a nod toward literate programming and having an example of every function right next to that function so you’re focusing on both the example and the code that makes that example work. I’ve since drifted to the more conventional style of “Your source code is here and all the tests for it are over there.”
JAMES:
I may be wrong but I always view that problem of having the function I’m working on and the test visible to me at one time, I always view that as a problem my editor was designed to solve. [Chuckles]
BRIAN:
Yeah, that’s true. However, I have a fairly elaborate editor scheme that’s supposed to keep the tests and the code visible to me at the same time together with another Emacs buffer that shows the running auto-test part. Even with that, it’s still somewhat difficult to keep them visible at the same time. But I think you’re basically right that if you’re using a decent editor well, having to intermingle the tests in the code is maybe only slightly an advantage.
JAMES:
I want to go back to this concept of data flow for just a little bit because I do think Avdi’s right. It was one the very interesting parts of the book. You talk a lot about the shape of data and things like that. I can definitely see lots of advantages to it. So the one that was immediately obvious to me was how great it is for parallelization. So if you have just this hash that you start with and if each thing needs to add a few different keys to it to build up to this final calculation or display or whatever, often there’s no reason those couldn’t happen in some arbitrary order. This thing could look at it and add those keys. And then later the other thing could figure out what it needs and add the other keys. And the only thing you have to resolve there is the dependencies between the individual tasks. So if these keys depend on some others to get at it then obviously that thing has to come first. But I found that part very cool. But then I hear you say things like use Clojure’s multimethods so that you can dispatch based on qualities of the parameters and stuff. And then I hear you say that you’ve gotten to where you do this even in Ruby. And I must say that that surprises me a lot because moving up to a layer like Ruby, you don’t have things like multimethods and stuff. So I guess you would actually have to inspect those parameters and basically manage your own dispatch, which then seems like you’re trading off most of Ruby’s advantages in the object system for something else. So that’s just my thinking when I hear you say that. And so I’m curious to hear you tell me how that’s not the case.
BRIAN:
No, it’s not the case. Sorry, I probably wasn’t clear about what I carry over into Ruby. I don’t use multimethods in Ruby for exactly that reason. It just doesn’t fit the language. What I’m using in Ruby is the data flow style of passing hashes around. That’s the main thing that I’ve carried over into Ruby. So one way to think of that, in other applications not the one I’m working on now, I’ve done things like have all my objects descend from either Hash or OpenStruct rather than from Object so that they can act as hashes. And you can arbitrarily add keys to them. So that’s the sort of thing I’m doing in Ruby, not the multimethods. One other thing, I wanted to comment about what you said [earlier], parallelizing. That actually works really nicely. So one of the programs that I work on is called Owl, they’re all named after animals, but its job is to go and fetch data from lots of different places and consolidate it together. And so the first version of that was, “Fetch this from here. Okay, now fetch this from there, merge it in. Fetch this from there, merge it in.” And there’s a nice package in Clojure that lets you write in what looks like a linear flow but in fact you’re writing dependencies between the sources of information and the sinks of the information. And it takes care of the parallelizing for you. And that’s a really good example of the power that you get with macros because it lets you write something that looks really not that different from the original code but it gets turned [inaudible] complicated thing. And it was trivial amount of work for me to do that. And I think it was like a 2x speedup, because one of the services is the bottleneck so I didn’t get a
huge speedup for that. Another thing that, in this same application, it basically processes a stream of data, maps over it or collects over it in old-fashioned Ruby lingo. So you just map over it and do things to each element. And there is a function in Clojure called pmap which does exactly the same thing as map, except it tries to use up as many [inaudible] as it can. And you can safely do that because you know that the data isn’t going to be mutated out from under you. So literally in this particular case, I added the letter p to the front of map and I don’t remember the exact speedup. It was 2x or 4x, which is not bad for a single character change, I thought.
JAMES:
[Chuckles] For sure. One of the things that I run into when I’m doing functional programming that I have trouble with, I would love to just get your thoughts on, you have this excellent section in the book on when to name function and when to name parameters. And it’s just pure gold about the consequences of when we do and don’t decide to assign names to these things and making them appear just automatic or a separate concept and when we make that choice. And it’s a really great section. But one of the things I run into when I’m doing functional programming is this large proliferation of various similar functions. And I think one of the reasons for this a lot of the times is that recursion itself, or at least the way I do it and feel free to say, “It’s because you’re doing it wrong,” is that recursion itself tends to proliferate these large number of functions. Usually, there’s the big recursive function. But then almost always, I want at least one other that kicks the process off and hands off to that recursive function to set everything up the way it expects it the first time. So I’m curious how you choose names for all of these functions that generate without ending up calling them recursive-thingy-one or whatever and choosing some lame name for the inner function that’s only actually meant to be called by the outer function. Does that make sense?
BRIAN:
Well one of the things you said is so you have a recursive function, and a typical recursive function that’s going to do something to a long list of things might have an accumulator argument that accumulates the changes as they go through.
JAMES:
Right.
BRIAN:
And so the problem is that the end caller doesn’t want to know about those intermediate steps or that very first transformation, the caller wants to hand the list to work with and get the result back, they don’t want to pass in an empty, so far use this as an accumulator. Now essentially the way to do that is to have one function that can take variable optional parameters, which is slightly awkward to do in Clojure compared to Ruby. But you’ll have one function named do-my-thing and if it has one argument, it will call itself passing in an empty accumulator and otherwise it just does the recursive part. And that’s slightly awkward. But once you’ve seen it a thousand times, you know exactly what’s going on. Did that make sense?
JAMES:
Yes. So I think what you’re saying is, you don’t tend to make that second function. Instead, you would do it by just using a default argument or something.
BRIAN:
Yeah. Also back in the old days, it was very common to have a naming convention for that. So if you had a do-my-thing entry point and it called another function that did some setup work or it did some setup work and then called the recursive part, the convention would be do-my-thing, and put a star at the end. And everybody knew, “Oh I see that. That means this is actually a helper function for a function with exactly the same name without the star.”
JAMES:
Gotcha.
AVDI:
That seems to be common across a bunch of functional languages. I seem to recall it being common to use a single quote prime character in Haskell. And I think maybe some underscores in Elixir, although Elixir makes it a little bit easier to just define another version of the same named function with different arity.
BRIAN:
Yeah. It’s not a bad convention. For example, one of the apps I wrote uses actors fairly heavily. And so I once had a function that sends a message to an actor and there’s another function that is what you’d say is the guts of the actor doing that thing.
AVDI:
Right.
BRIAN:
So, I just have a naming convention that…
AVDI:
Message versus method.
BRIAN:
Pardon?
AVDI:
Message versus method.
BRIAN:
Yeah. So, I have a naming convention where if you say send-text, because this app sends text messages. If it says send-text and then I use a greater than and a bang, this is a message this function just fires, just puts a message on the actors queue and returns immediately. And the version with the star is the one that’s the actual function that takes the state of the actor, transforms it and produces a new state. And through the power of macros, I just have a single macro called defmessage that creates both of those functions for me automatically. And the only code that really needs to know about it is the test code because the test code wants to fun synchronously, not threads and all that crap. So the test code refers to the functions with the star on the end and not the other kind. So just cut all that point out because it’s impossible to understand what I just said. [Laughter]
BRIAN:
But naming conventions like that do seem to be maybe more common in functional languages where you’re sort of, since everything is a function, you use little annotations to talk about the kind of role that function plays in the bigger picture, maybe.
JAMES:
Kind of along those lines, you have this thing when you’re talking about higher order functions in the book where you actually go back and you implement something in Ruby showing what it would look like using the concept of higher order functions. I think you just pass a lambda around or something in this particular case. And it was interesting to me that you chose to do it that way because you only pass an individual lambda to a method or something. And it seems to me like Ruby optimizes for that being the super common case by making it possible to pass a block to each method, which almost turns into the higher order functions and how Ruby handles them. So, I guess my question is -- I’m sure we’ve seen the piece or the claim. I think it was from Paul Graham, that Ruby is almost an acceptable Lisp, or something. And I was just wondering if you feel that way because of the blocks in there and the kind of ability to do these sort of higher order function things. Another example that made me think of it, just to give more context, you’re talking about laziness which we should definitely discuss because it’s an awesome part of your book, and how you can turn some of these iterators into lazy things. And Ruby has actually started to pick that up quite a bit in recent versions. And now we have the .lazy that can just switch all those iterators and stuff. So, I was just wondering if you think it’s interesting that Ruby is pulling some of these concepts in.
BRIAN:
Well yeah, so let me digress for a second. The way I got started in Ruby was I was taking a shuttle bus up to a workshop at this ski resort in Utah and there were a couple of other people there that I didn’t know and we got to talking about it. And they asked me what I was doing and I said I was picking up this new language called Python and I was kind of liking it. And they turned out to be Dave Thomas and Andy Hunt. And so I was trapped with them on the shuttle bus for 45 minutes and this was just after the Pickaxe book had come out. And so by the end of it, I had agreed to by the book. [Laughter]
BRIAN:
I had a [markedly] different experience with Ruby than I had with Python because with Ruby, I guessed the way things would work, they would work that way. And even things like guessing the name of a method, it would actually be named that. And I at the time attributed that to the fact that Ruby had sort of a Lisp-y feel and I had heard but don’t know if it’s really true, that Matz had been a Lisp programmer and taken it as some sort of inspiration for Ruby. Does anybody know if that’s true?
AVDI:
So I have it straight from Matz’s mouth that the largest influence on Ruby is Lisp.
BRIAN:
Okay.
JAMES:
Yeah, that makes sense. Matz is an Emacs user. Yeah, the Common Lisp object system in many ways resembles parts of Ruby’s object system, I would think.
AVDI:
Yeah, it’s funny because I always think of Ruby as being sort of essentially Smalltalk at its heart but Matz really cites Lisp as the principle inspiration for it.
BRIAN:
So I think I’m not up on the latest version so I don’t know really that much about the laziness feature. We’re using 1.9.3 so that’s what I concentrate on. I think it’s certainly the case that blocks are an optimization for passing around lambdas, an optimization for the human reader and writer’s point of view. So I certainly think it’s good that these things are coming into Ruby. And a lot of those things that are coming into Ruby like laziness for example, or immutability, those weren’t part of Common Lisp back in the day when I was using Common Lisp. And so to some sense, Ruby maybe we could say Ruby was incorporating the state of the practice or state of the art of Lisp some years ago, Clojure, this Lisp and the newer functional ideas like immutability and such. And so it’s a natural progression that Ruby would begin to acquire those features as well. The only, I guess question is syntax in that it’s still awkward to use free-floating lambdas in Ruby because you have to, “Should this function call have a dot before the params or not?” It’s sort of awkward to have these two kinds of things. You’ve got functions and you’ve got methods. And it’s easier when you’ve only got one thing. So I don’t know how much the functional style will in fact be mainstream Ruby programming.
JAMES:
That’s interesting. You say you haven’t really looked too much at the newer features and the inclusion of lazy, so I’ve got good news for you. The description in your book of why to trust laziness and stuff is great. It’s about how you can just program it in a way that you think is the most natural and then leave it to the computer to sort out, “Oh that’s horribly inefficient because you did a map and then a select and then a map so you’re running over the list three times.” In current versions of Ruby, I believe lazy was added in 2.0, and it’s basically like you talked about earlier with pmap. You can stick a .lazy in there in the chain, the call chain, and then it returns an enumerator lazy object, lazy enumerator, and that object is much like you describe in Clojure where the ones that it makes sense to do so are rewritten in a lazy fashion. So instead of running through the entire list three times, it builds the pipeline for you and moves the first item of this list to the first item of that list and on down the chain and you just get these lazy operations for .lazy call. I’ve ran into a couple of cases where I’ve been able to have the .lazy and really make something more efficient or save from doing a lot of busy work or something. And it’s pretty cool stuff.
BRIAN:
Yeah. That sounds good.
AVDI:
One of the comments that a few people have made, people that have read the book, is that they felt like it really addresses functional concepts in the small really well but doesn’t really talk about organizing large functional programs as much. And I’m just curious, let’s say I finished your book, where do I go from there to find out more about organizing large functional programs?
BRIAN:
Well when you find out, tell me. [Laughter]
BRIAN:
The reason that it’s weak on that is because I didn’t and still to some extent don’t know the answer to that question. And what I’m doing here at work is, since they’re basically a lot of small services, the question hasn’t really come up either. So maybe part of the answer is kind of like Martin Fowler’s answer when people ask him, how do you scale agile software development? He says something cleverer than this but, “Don’t.”
JAMES:
[Laughs]
BRIAN:
Keep it simple. Scaling should be the last thing you want to do. So, maybe the answer is if you’re running into problems with scaling your functional program, maybe it should be two programs talking over some narrow channel. But that’s I think one of the main things I realized when I started learning Clojure was that a lot of what you get with an object-oriented language is you get a readymade organization for your program. So you know where to look for information about this particular object because that object has a class and you know where the functions for that class are. And so with the occasional exceptions like Array or Hash, there aren’t that many functions you have to sort through. But in something like Clojure, you can compare the Clojure API to the Ruby API. And the Ruby API is nicely organized by classes and sometimes subclasses. And the primary interface to the Clojure API is this just pile of a thousand or so functions and how do you find where you’re looking for? And that is the problem with large-scale organization. A guy named Jeffrey Fredrick, I think it was Jeffrey Fredrick, once said something really wise to me, which is that if you’re looking for a function in a system that you know must exist somewhere, when you finally find it, move it to the place you first looked. And I think that’s a useful advice for object-oriented code. And it seems to work pretty well. My main open source Clojure package is Midje, which is sort of the RSpec in some ways of the Clojure world. And I followed his advice. I had a lot of trouble organizing it and I followed his advice. And what I kept finding out was I’d moved something to where I looked for it first and then the next time I looked for that thing, I’d look for it in the place I’d moved it from first. And so the program didn’t seem to fall out into an obvious structure. And it’s been through three major, I guess you’d call them structural metaphors for how to organize things. And I still don’t think I’ve figured out the right way to do it. So I think the answer is I don’t know that we really have a super good idea how to do that. At least I don’t have a super good idea of organization in the larger functional programs.
JAMES:
I’m really glad I’m not the only one that suffers from this. [Chuckles]
CHUCK:
Alright, well are there any other aspects of the book that we need to discuss or should we move on to the picks?
JAMES:
I’ll say that the book is interesting. In some of the asides I’ve learned a few things about paintings that I didn’t know while reading this book, which was an interesting thing. Also, it’s extremely wellorganized. It has a glossary and it warns you that it has a glossary [chuckles]. It’s actually laid out really well and a lot of production effort into it. So I know you’ve mentioned that you were trying out the Leanpub system and I would say you managed to use it to great effect. It was well-received.
BRIAN:
Thank you. Except for no index.
JAMES:
[Chuckles] Except for no index, right.
BRIAN:
And I think there will never be an index because it’s too hard.
JAMES:
Right. Yeah, in professional publishing companies, they spend massive amounts of money to get people to spend massive amounts of time to go through and create the index because it’s a whirlpool.
BRIAN:
Yes. Okay.
CHUCK:
Alright. Well, let’s go ahead and do the picks. Avdi, do you want to start us off with picks?
AVDI:
Sure. I have a couple of blog series to pick today. First one is a blog series by Julia Evans and she’s documenting the process of, I believe building a kernel, in the Rust programming language. And it is a fascinating deep dive into what it’s like to program when you have absolutely nothing to work with. No runtime, no operating system, no nothing. Just putting your interrupt vectors into the right location in RAM and hoping that something happens when you hit a key and that kind of thing. Definitely reminds me of why I don’t do that stuff anymore.
JAMES:
[Chuckles]
AVDI:
But [chuckles] it’s a really great introduction to that whole mode of thinking, if you’ve never touched the bare metal before. And another really cool blog series that I was turned onto recently is this Jepsen blog series by Aphyr, not sure, Aphyr.com/tags/jepsen. And it’s this long series of blog articles where various SQL but particularly various NoSQL data stores are put through their paces. And particularly, they are subjected to a net split, a partition, sorry, between networks. And then it examines their properties, how they behave when that happens. And I’ve learned so much about the theory behind distributed systems and distributed system consistency and about the failure modes that people don’t often think about. I just highly, highly recommend this series. I have not finished it yet, but I’ve enjoyed each article that I’ve read. It’ll force you to think about the stuff that normally you just try to shove under the bed and not think about in hope that it won’t happen because this is the stuff that when it does go wrong, very often it goes wrong in ways that you didn’t expect because you didn’t realize exactly what sort of consistency properties your distributed data store actually has. So, I very highly recommend it.
CHUCK:
Alright. James, what are your picks?
JAMES:
So, just two. One, I saw this interesting hack, is what I’ll call it and what it calls itself. Xavier Noria, I think is how you say his name, I’m sorry if I messed that up, did his talk at BaRuCo 2012 in a
terminal and using this script that he basically calls Terminal Keynote. And it turns your terminal into a typical slide-sharing style application. The code’s kind of crufty if you look at the examples and a lot of things end up being in streams and stuff, but still it’s an interesting example of just how you could do this, how you would turn your terminal into a Keynote-y type thing, and just neat for giving ideas. And I enjoyed that. The other pick is I’ve been playing a lot of games because I’m on vacation, like I said. And one of the ones I’m really enjoying is Desktop Dungeons. It’s a puzzle game where it’s almost a rogue-like dungeon crawler but it’s all about puzzles. So, you have to balance. Exploring the dungeon is how you heal, so you have to balance exploring to find new bad guys that you could potentially take which you’re stealing from your healing potential when you’re actually fighting stuff. And calculating all that out to maximum benefit is tricky and fun. So I’ve been enjoying that game a lot. It’s also really tough. [Chuckles] So if you enjoy that tough aspect of it, that’s one of the things I’ve been playing. Those are my picks.
CHUCK:
Awesome. Alright, I’m going to give a couple of picks here. The first one that I’m going to pick is a little article I found. It was driving me crazy every time I moved something around on my computer or delete or empty the trash and things like that, it would make the noises. And I like having my computer not make noises. And so I found a little article that shows you how to turn that off. It’s just an option in your settings. I just didn’t know that it was there. Another pick that I have is RspecMode. And this was brought to my attention by one of my subcontractors. And he, every time I pair with him, he’d be using it on his setup, and it was just really convenient to be able to just hit a couple of the keys to have it run the specs. And so I’ve really been enjoying that. And then the last one that I’m going to pick is something that I’m going to be trying out here pretty quickly. I’ve been looking for an alternative to GoToMeeting because it doesn’t work on Linux. And it seems like every time I do one of my courses, somebody is on Linux and I hate making them use a Windows VM or just dial in and not be able to see the slides or what have you. And so I looked at TeamViewer but it just doesn’t quite fit my needs even if I buy a license. It just doesn’t have enough seats for enough people and it’s pretty expensive. I don’t have to pay for it once. So, I weighed that against some of the other options and then somebody pointed me to FuzeBox. And FuzeBox is a GoToMeeting alternative except it’s much less expensive and gives you a lot more seats. So I’m going to be trying them out, see what I think there. I didn’t go with Google Hangouts, is the other one people keep telling me about, just because I’m not quite sure how to make the Hangout private and things like that. And I’m looking for something just a little bit more professional in that. So anyway, those are my picks. Brian, what are your picks?
BRIAN:
My picks are really two categories. I always like things that claim everything I know was wrong. And here are two picks of two such categories. I once heard somebody say that the only purpose of his body was to keep his brain from falling onto the floor.
JAMES:
[Laughs]
BRIAN:
And we software people tend to think of ourselves as being effectively a brain in a vat. And that appears to be rather untrue when it comes to a lot of perception and thinking. And there’s a field called embodied cognition that talks about how cognition and perception is an interplay between the body and the mind and the environment. And so what I’ve prepared here is there’s a blog from a couple of psychologists who are embodied cognition people that I think forms a nice introduction.
I stumbled across it. That’s where I learned this stuff. There’s a popularization by a woman named Barrett called Beyond the Brain. And if you want to get into the really nitty-gritty stuff there’s a book called ‘The Ecological Approach to Visual Perception’. And it’s fascinating to realize, at least according to this person, how much the characteristics of the environment inform what it is that we see in the environment. So, that’s one topic. Another topic is something that sort of bugs me a lot of times, is that people in software tend to make a big deal about science and the scientific method. And there’s a reasonable argument to be made that a lot of what makes science work is in fact completely independent of what we think of as the right way to do science. And so I’ve been dabbling in this for [a couple] of years. There’s a particular author named Bruno Latour who has been doing work on this for a long time. And he is the founder of something that’s called actornetwork theory. And there are two books of his that I think I recommend. One is called ‘Laboratory Life’. It’s his first book. And it was him, he acted as an anthropologist going to visit a strange tribe with their strange customs, not speaking the language and trying to figure out what they were doing, except the tribe he was visiting was the Jonas Salk Institute of Biochemistry. And he was a French philosophy major trying to go there and figure out what are these people actually doing. And it’s really fascinating to look at how that works. And another book of his which I think is the clearest explanation as to the early [inaudible] of actor-network theory is a book called ‘Science in Action: How to Follow Scientists and Engineers through Society’. And it’s just such a completely different way of looking at something that we’re so convinced we already understand that I like to recommend it to people. Also, I gave a talk on this at OOPSLA a long time ago. And I wrote up a set of blog posts which sort of recapitulated that talk. And I will also send links to those blog posts.
JAMES:
That is awesome. I think you just filled up my reading list for a while.
BRIAN:
Good.
CHUCK:
Awesome. Alright. Well, thanks for coming, Brian. And thanks for writing your book.
BRIAN:
Oh, thank you for having me.
JAMES:
Yeah, thanks Brian. It was great.
AVDI:
Yeah, thank you very much.
BRIAN:
Okay. Well, I will be two minutes late to the standup and they will give me hell about it. But that’s pretty good, I think.
JAMES:
[Chuckles]
BRIAN:
I’ll blame Skype.
CHUCK:
There you go.
JAMES:
That’s right. Don’t let us keep you. Feel free to run off. Sorry we took so long.
BRIAN:
Talk to you later.
CHUCK:
Yup.
JAMES:
Bye.
CHUCK:
Bye.
JAMES:
Before we close out this episode though, let’s talk about our next book. Can we?
CHUCK:
Yeah, let’s do it.
JAMES:
So, we have decided that next we will read ‘Ruby Under a Microscope’ from Pat Shaughnessy. So, we’ve not yet talked to Pat about being on the show but we will definitely get on that. And we don’t know the date for all of that yet, but it’s coming soon. We will try to get discounts and stuff for the listeners as well. But yeah, that’s the book if you want to go ahead and get a jump on it.
CHUCK:
Alright. I also want to remind people about Ruby Rogues Parley. You can go sign up for that on the website. And I think that’s it. So, we’ll wrap this up and we’ll catch you all next week.
137 RR Book Club - Functional Programming for the Object-Oriented Programmer with Brian Marick
0:00
Playback Speed: