RR What Makes Beautiful Code
- Published on:
Ruby-Chan Why Beautiful Code?
- You know your code is written correctly by looking at it.
- Knots metaphor - If it’s shaped right, you know it’ll hold.
- The shape in your mind matches the shape on the page
- Eric Hodel - Audio evaluator of code
- Reveals the intention to someone
- 80 character limit
- 1 statement per line
- Comments are code smells
- Engage more senses-use more parts of the brain
- Short functions/methods
- Morph the language into the language of the problem domain (DSL’s)
CHUCK: We have from Oklahoma, one of the organizers of the Red Dirt Ruby Conference, the author of FasterCSV library, he can be found on twitter as @jeg2 -- James Edward Gray. JAMES: Hello, everybody!
CHUCK: From here in Utah, we have David Brady. He is the author of the tourbus library, he is a co-host on the ADDCasts – which are awesome. And he's currently a freelance developer. Welcome to the show, Dave.
DAVID: Thank you.
CHUCK: We also have from Pivotal Labs, Josh Susser. He blogs at blog.hasmanythrough.com. He is the number 51 committer to Ruby on Rails. And according to LinkedIn, he has six patents to his name.
JOSH: Seven, actually.
CHUCK: Seven, okay.
CHUCK: Welcome to the show, Josh.
JOSH: Thank you. Thank you.
CHUCK: And then we have the author of Exceptional Ruby, a blogger at Avdi.org/devblog and on twitter as @avdi, we have Avid Grimm.
AVDI: Great to be here.
CHUCK: And I'm Charles Max Wood. I am the host of the Rails Coach podcast, the Teach Me to Code podcast and screencasts. And I have another podcast where I just talk about stuff going on at IntentionalExcellencePodcast.com. And I will be also running an 8 week course -- video and online course -- at teachmetocodeacademy.com, on Ruby on Rails. So let’s go ahead and get started here. The question was, what makes beautiful code? And I think that’s an interesting question, not just for Rubyists, but just in general for coders. So, I put some feelers out on Twitter to see what people thought. But before we get into that, let’s see what our panelists think. And I´ll just let anyone chime in that wants to, but what makes beautiful code?
PETER: It has to be written in Ruby.
CHUCK: [Chuckles] Okay.
DAVID: It does not have to be written in Ruby.
PETER: Oh yes, it does! No, it doesn't!
JAMES: [inaudible] him from the call.
DAVID: [Laughs] Beautiful code to me is code that you look at it and its very intuitive, it satisfies two things; first time you see it, it’s intuitive and it leads you very clearly into what it is doing and it explains itself. And then every other time that you look at it, it doesn’t bore you to tears with stopping you to tell you what it’s doing. So it hits that sweet spot between being and being explicit; between being informative and being magical.
JAMES: Wow. I definitely wanna go after that, because I've been thinking about this question all day and what I was going to say on this podcast, and I'm definitely ill and heavily medicated, so I came up with this weird answer -- but I was sure was just the drugs was talking -- but it was basically what David Brady just said.
DAVID: I am James Edward Gray’s drug. [Chuck and James laugh]
JAMES: No, I really liked his idea of… I was trying to think of what makes something cool and it’s for me, it was like when I look at it, and it gives me that “Aha!” moment where I'm reading it, that shifts my thinking in some way or something like that. So that was actually what I was going to say too.
JOSH: So I've been actually thinking about this a lot too. I wanna put it in the context of the question of , “What makes anything beautiful?” And I think at some level, beauty is a survival adaptation that we evolved to consider other people beautiful, if they have that set of genetic characteristics that would make for healthy offspring, and passing on your own genes. And we evolved in certain environments where we would look at things and if they were things that would help us survive or not threaten us, they would be beautiful, and if they were things that was dangerous, we would find them fearful and ugly. So people look at spiders and get all freaked out because they are dangerous. And I don’t think that’s the entirety of aesthetic appreciation of things, but it’s a pretty good starting point to think of things. And so thinking about beautiful code, I think that beautiful code is code that is not threatening to us, it’s not going to be a problem for us to work with, it’s not going to get us woken up at three in the morning. And it’s code that contributes in our happiness and our survival.
CHUCK: Ah. [Chuckles]
JOSH: Is that way too philosophical?
JAMES: I actually really like the…
AVDI: Yeah, it makes a lot of sense.
JAMES: … “contributing to our survival” part.
DAVID: So from this, we can extrapolate that Ruby has big, wobbly eyes…
DAVID: …and C# has one eye bigger than the other and…
AVDI: Yes. I mean, if you look at Ruby Chan…
JAMES: [Chuckles] That’s what I was going to say.
CHUCK: Ruby Chan?
AVDI: Or is there a Ruby Chan? I forget.
JAMES: It’s Ruby Chan, but there was a new one posted…
AVDI: Did somebody just come up with…
JAMES: Yeah, just this week was another one posted. It’s an old meme about taking like this Japanese girl looking character and using her as a mascot for technical…
AVDI: I mean like originally, like way, way back in Japan, Ruby had a semi-official mascot and it was an red-haired anime girl. And that didn’t really translate well, so we got the gem that we have now.
JAMES: That’s awesome.
AVDI: Yeah, talk about beautiful Ruby.
CHUCK: Well, interesting, it almost seems kind of the metadata on programming. We're saying it kind of invokes this response, where it kind of hits both the elegant and the functional, and the descriptive, but I'm wondering if there is something maybe a little more concrete that people can do to make their code reach that stage. What practices are there that you can implement to make code beautiful?
DAVID: I´ll jump on that one, just because I'm feeling really chatty today. With a non-answer, which I'm going to basically say, we need to do this and then we'll open it up to how do we do it. And the reason we need to do this -- and I’ve coded this way my whole life -- based on something a climbing instructor taught me in high school. He was teaching us how to tie knots. You tie a figure 8 knot for one type of thing. You tie a square knot for something else. You tie a granny knot for no reason ever -- don’t do it. And he’s tying a sheepshank, which is fairly convoluted knot. If you are not a boy scout, it’s fairly convoluted knot. And he ties this gorgeous sheepshank and we are all tying this, and there are just these mangled lumps of rope. And he stood up and he says, “Okay, you are hanging from a cliff 200 ft. in the air. You need to tie beautiful knots. And the reason why is because at 200 ft. from the air hanging from this piece of rope, you can look at a beautiful knot and immediately know if it’s tied correctly. If it’s a sloppy knot, you can't. You have to investigate it; you have to tease it apart and play with it.” And should we spend all of our time making beautiful code in every situation? Not necessarily. Your harness strap that hangs down, that doesn’t really serve a function, that should be tucked up and out of the way. It does not need to be macro made into a series of beautiful knots all the way down your pant leg. But that’s my motivation for why do I write beautiful code. And the reason why is because beautiful code and be inspected very easily, it can be dealt with very easily. So that’s just me adding to the… I don’t know that I know how to write beautiful code or how I would change ugly code to a beautiful code, but that my motivation for why. I just wanna put that out there.
AVDI: That really speaks to me.
CHUCK: I agree, it does. But I wanna play devil’s advocate a little bit here, because we have other things like tests and things like that, that also tells whether or not the code is written correctly -- or at least functions correctly. Is there a difference between ‘written correctly’ and ‘meets the functional requirements’?
JAMES: Maybe it’s more functions as [unintelligible] done correctly, right?
DAVID: I don’t even think there's a difference necessarily between tested code and beautiful code. I mean, you can have ugly code, but I mean if ugly code that has tests on it is more beautiful to me. And I may be splitting hairs there.
AVDI: That metaphor really, really speaks to me. I thank you for that. That was Josh, right? CHUCK: It was David.
AVDI: David. Okay, yeah. Sorry about that. So I'm into knots as well. I learned my twenty knots in scouts. And It’s very, very true. The thing that really speaks to me about that, when I was thinking about my definition of beautiful code today, for me, it really has to do with the shape of the code. I think for me, beautiful code has a shape to it and it has a shape that matches the shape of the problem in your head. Like that shape can be seen in various levels; that can be even be the shape of the code on the page. Like Dave Thomas talked about zooming a code base out. When he is first coming on to a code base, zooming it out until he can actually read it, but he can sort of see the cadence of it. I think there's a lot of truth there because when you see certain rhythms in code or certain shapes to code, you can immediately sort of get an idea for what it’s doing. And so beautiful code for me, if you have a problem, which you see as a series of matches and then things to apply… if something a pattern matches, then the shape of the code on the page is a mapping of patterns to actions, then you have beautiful code because the shape in your head is the same as the shape on the page. And so that idea of a knot really speaks to me, because you can instantly see with a knot, you can see if it’s been tied well because it has that certain shape to it. And the other reason it really speaks to me is that, the thing about knots is very often, when you really need them, you don’t have the time to think about how to tie a beautiful knot. But the great thing about knots is that, you can practice them until it is second nature. You can practice a ball until you can tie it in the dark with your hands behind your back -- and always get it right. And so I think at the low level code construction level, there are a lot of things that we can do, that we can just practice until you don’t really have to think about it; it’s just second nature.
JOSH: Avdi, I like that image of the shape of the code. Did Eric Hodel showed you his audio analysis thing for Ruby code? He was showing that off on Ruby on Ales. Did you get to do it?
AVDI: I did not.
JOSH: He wrote this cute little script that used I think MIDI output or something like that.
DAVID: Oh my gosh, I did the exact same thing.
JOSH: And it would go through a Ruby source file, and every line took a certain amount of time. And if a line was just the word ‘and’, it would produce a tone, of which the pitch of which was proportional to the indentation of that ‘and’. So you can listen to the script play of Ruby program and you could hear [musical tones] and you could just listen to it and get a feel for what the shape of a program was.
JAMES: I'm not sure if this is the same thing or a different thing, but there was a gem plugin at one point called Gems Sing. And I'm not sure if it rhymes in modern Ruby gems, but you can install the plugin and then do gems sing, and the name of the gem, and it did something basically exactly like that. And it was interesting to play with on certain projects.
DAVID: That is so cool. So Avdi, your comment about the shape of code, I so often, when we talk about how to make the code beautiful, I will hear programmer say, “There should only be one statement per line. You should not ever go beyond 80 characters. You should have all these patterns.” And one of the reasons I left Python – and Python is a great language; don’t get me wrong --- but one of the reasons I left Python was the mandatory white space enforced a limit to how much I could compress the code. And I will occasionally -- this is just me, this is the type of knot that I like to tie -- I will occasionally write a very sparse function with one line right in the middle of it that is very, very dense. And usually, it’s some kind of math thing, where you are setting up to do this mathematical function, and then there's this 130 character vector operation and then a little bit of math cleanup and tear down. And the instinct, if you are just following the route of the, “The code should look like this. It should be indented this much. It should have this many characters on it.” I wanna push back on these people and say, “No, no, no, no, back up and squint at this. Do what Dave Thomas says; put it in a four point font or just just back away and look at this function on the page. And what does that tell you? What is the most important thing in this function?” And they point right at the long line. I said, “Okay, now what's the most dangerous thing in this function?” They point right at the long line. I said, “This is a well written function. You are afraid of the thing that you should be afraid of, and you are ignoring the boiler plate.” And I would claim that would be a beautiful function. Now can it be abstracted? Maybe. I'm being general, but you may be able to find out other refactors in specific cases.
AVDI: So this is the interesting thing about shapes is that for me, beauty is the shape in your mind matches the shape on the page. But the problem is, different people model problems differently in their minds, so that shape in their mind is different for you than it might be for me. And that’s something that I have to remember when I'm being very sort of judgmental about coding styles. I'm sort of pretty hardcore about the 80 character limit, because I find that I just can't think about very many things on one line at one time. It basically stifles my ability to think about the problem.
DAVID: That is fascinating. Because the reason I write that really dense line is because I have trouble keeping too many lines of code in my head. And so, when I have a function that rises to a crescendo, I put everything in that crescendo and… that is fascinating.
CHUCK: Avdi, you are cutting in and out.
JAMES: Try again, Avdi.
AVDI: How about now?
DAVID: Some of that can be, I think modeled a little bit better in some of the functional languages. I've always really liked the pattern of you give it a high level algorithm on the very first line. You see this in Haskell; you have a high level algorithm in the very first line and then it says, “where this symbol refers to this and this symbol refers to this and this symbol refers to this,” so you have that top level in the first line rather than setting up a bunch of variables, and then doing the having the algorithm. You have the algorithm first and then a bunch of where clauses saying, “Oh, and this is what all those stuff refers to.”
DAVID: Yeah. Actually, the best case where I've rigorously defended that shape with the really dense line was exactly that it was Math stuff. It was a physics engine and we've taken a car -- a remote controlled car game -- and we’d made remote controlled motor cycles. And there's a problem with motorcycles in a Physics engine, and it’s that they tend to fall over because they don’t have a four point base, so they have a 2 point base. And I ended up writing this function that had to handle the physics for the motorcycle. And I sat down and honest to God, I spent three days on the white board working up the various momentum components, the rotation, the torque in the bike in all three axes, the world, everything. And when I was done, this big long proof across three whiteboards came down to a simple subtraction -- a vector subtraction. And it was a weird thing; subtract the world’s Y axis from the bike’s torque in the x axis. Just cross product those and the bike will ride itself. And you know, it was this really weird, bizarre… it was arcane; it was total magic. And so, what that function was is it had all the Math set up, and it then it had this really long chunk of vector math and there was a comment right above it that said, “This rights the motorcycle.” And then the function went on. And so other programmers came along and they go, “Oh, that line is too long!” “Oh there's a comment.” Okay, we all know that comments are code smells, but there was a comment right above it that said, “This rights the motorcycle.” And now you know, as long as you are not concerned about righting that motorcycle, you don’t have to touch that line -- and you can just move on.
JOSH: So I think that speaks to a characteristic of beautiful code, which is that it reveals the intention to someone. And at Pivotal, we write all of our code to be delivered to clients, and usually, they take over the maintenance of the code after they are done with their engagement with us. So we don’t just write the code to work correctly or to be performant or what have you; we want the code to be something that our clients can walk away from an engagement at Pivotal and own the code and be happy working with it. And I was working on a piece of code yesterday, that we got it working and then we spent as much time getting it into a form that we liked after we had gotten it working. So we are working and then we've spent just as much time putting in form that we felt would reveal its intention, enough that someone six months or a year later would look at that code and will not have an issue dealing with that code.
DAVID: And that wasn’t a wasted day of you … your lanyards; that was you saying, “This is a really weird lump of rope. Some other climbers got to look at this.” “Let’s turn this into a knot that they can recognize.” JOSH: Yes, absolutely.
CHUCK: So I have to ask then, how frequently -- if you want a beautiful code -- do you have to refactor? Always? Almost always?
JOSH: I don’t know how often you have to refactor, but I think you have to think about refactoring all the time.
JOSH: So if you are just writing a one line method, there's not much to refactor there. But when you get to the point where you have one of those Gordian knot methods, you need to start cutting it up and refactor the pieces that do reveal its intention. Because even if… to abuse this metaphor, even if you have a really well constructed Gordian knot, nobody can understand it just by looking at it.
CHUCK: Right, but do you refactor as you go then, or do you write the whole thing and then refactor?
JOSH: Well, I like the red/green refactor cycle, where if you are test driving, you get the failing test, you get the passing test, and then you look at refactoring. And you can deal with that at many levels of granularity. You can deal with it at a small granularity, where you are looking at the internals of one method. Oh, I might wanna extract a method or move stuff around within the method, or you can look at it at a macro scale in the large scale organization of the software. But in the large scale stuff, you don’t do it as frequently. But I´ll refactor a 10 or 20 line method a couple times sometimes, before I'm done with it.
JAMES: I have to say two things; first of all, I think it’s amazing that we chose the abstract metaphor episode while I'm drugged -- and I'm just very grateful for that. But two, I've been sitting here and listening to you guys talk about knots and music and stuff like that, and I'm reminded that there's been a lot of brain studies about what makes experts and things like that. And one thing that comes up over and over again is that they will try to engage more of their senses when solving a problem, because it uses different parts of the brain. And so basically if you are using your ‘feeling’ part of the brain and your ‘seeing’ part of the brain, and your ‘smelling’ part of the brain, whatever; if you are using more part of the brains at once, obviously you are doing more processing, and so you generally do a better job. And you can see that with like musicians and stuff, right? When you are at a classical concert and the violin players playing like crazy; he is swaying back and forth to the music because he can feel it inside of them. And that sensation keeps them going. And it’s interesting that we are sitting here describing what we do and don’t like to see, we are trying to invoke a lot of that imagery or feeling or sensation, and it is obvious we are trying to use other parts of our brains as well.
DAVID: That is interesting. And it all starts with code smells, right? And then yeah, move on to code music.
JOSH: What you are talking about there was very interesting, but there have been research done on people who grew up deaf and how the linguistic centers of their brain interact with other parts of their brain. And with hearing people who have a spoken language and their linguistic centers are wired in very intimately with the auditory processing in their brain. But deaf people don’t have that connection; they have that connection between the linguistic parts of their brain and the visual processing centers. And deaf people have so much greater visual acuity than hearing people -- it’s crazy. They will play party games, kind of like charades where they draw shapes in the air and other people try and duplicate these abstract shapes, hearing people can't play this game at all because the deaf people are so far beyond us in it. And they’ve done quantitative studies on this that show that deaf people have much better visual processing. I wonder if that would have an effect on how deaf programmers would tie in with other parts of their brain, and would they use the same sort of metaphors that we use in programming?
JAMES: That’s awesome. From now on the eardrums of all programmers will be punctured. [Laughter]
JOSH: I don’t think we have to do that. [Laughter]
AVDI: I know I'm definitely a very audible… audible? I don’t know what the term is.
AVDI: Yeah, I'm an auditory programmer. Like for me, the lines of code that I can reason most clearly about are the lines that I can pronounce -- I have to be able to read it out. It’s one of the reasons that I personally really like Rspec. Really liked that development when I came out was for me, I have a much better time speaking Rspec lines than speaking Test::Unit lines. And that enables me to reason about them.
CHUCK: That’s an interesting thing -- not just in the sense that you can speak it and you can process it that way -- but overall, I think it’s also interesting. Steve Klabnik on Twitter, I asked people on Twitter what they thought made beautiful code. He actually said, “Clear, narrative structure, which kind of goes beyond just the line to the overall story that’s being told, so to speak.” And so you process each line but then, as you process each line, you know how it unravels into the overall story or… I guess it comes back to how it appears in your head and how that matches what is on the page.
DAVID: There's a game that I like to play that is absolutely insane. And I loved doing it because it breaks peoples brains and it breaks them in an informative way once they get past the part where they wanna hiss and drive a wooden steak through its heart. And that is that, with the exception of CoffeeScript and Python, most of us program in a whitespace-independent language. You could, through the liberal use of semicolons, compress your Ruby code into a single line of code. So, Ruby of course is white space-independent, right?
DAVID: We as programmers are very, very whitespace dependent. And if you want to prove to yourself just how dependent you are in the x and y axis of how you lay these tokens out on the page, try spending a day coding on a proportionally-spaced font and write narratives; make your code read… like if you wanna get really crazy, make your font italic and use like a font so that it looks like you are writing it by hand, and not on graft paper, but like on a stationary. What you will find is that you will start moving away from structures and start moving towards messages, which is a really fascinating thing that happens to your head, but it also changes very strongly how you represent beauty in the code and how you represent structure of code.
JOSH: David, are you aware that the original Smalltalk development environment used a proportional font for code?
DAVID: I am not aware of that, but I have repeatedly… I've said this recently, I recently started looking at Smalltalk. And the reason why is because I have a set of insanities that I have developed carefully and cultivated over 20 years, and I spoke to Small Talker about a month ago, 2 or 3 weeks ago and he have the same set of insanities. And so I went and found another Small Talker and he had the same set. And I was like, “I've come home.” It’s like gonzo when the UFO comes down and there's all these purple Muppets with the big, funky noses that’s like “I need to learn Smalltalk.”
JOSH: [Chuckles] I recommend it for anyone.
DAVID: That’s awesome.
CHUCK: So can I change tactics a little bit? I got about four tweets on this and I wanna read each one and then see what you guys think about what other people think beautiful code is. So first one that I got was from Timothy Rand and he said, “Beautiful code is concise but clear, and algorithmically clever.”
DAVID: [inaudible] positive definitions of the word, ‘clever’? Yes.
DAVID: Do you remember when ‘rock star’ used to be a positive word? [Laughter] And now it’s a four letter word you don’t want that stigma of being a rock star?
CHUCK: It’s a compound word; two four-letter words.
DAVID: Yeah, exactly. I would change the word “clever” to “elegant” or to perhaps, “interesting”. But when we start talking about clever where you outsmarted me with magic, then it becomes bad clever. I suspect that Timothy means the kind of clever when you look at something and go, “Oh, that’s clever! That’s cool!”
JAMES: Yeah, I do like it when I see a piece of code and in working it out in my head, it leads me to a realization or something like that. But if I see a piece of code, and it’s insanely complicated and I work it out and then I'm like, “We didn’t really gain anything from that as opposed to the usual three line idiom that everybody knows, then I would much rather see the three line idiom that everybody knows.”
DAVID: And I would argue that in that case, James that three-line idiom is more beautiful.
JAMES: I agree, absolutely.
CHUCK: All right, so we have another one here. It says, “The actual form of the code in the screen -- not the content -- can strike a deep aesthetic cord.” I think we’ve already talked a lot about that already.
AVDI: Amen to that.
JOSH: So related to that, why does everyone hate parentheses? [Chuckles]
AVDI: I don’t.
DAVID: Parentheses ran over my mother in a DUI accident and it’s been bitter ever since.
AVDI: [Chuckles] That’s what it seems like sometimes.
JOSH: I've looked at chunks of code written in Lisp-like languages or Lisp itself, and that’s some of the most impenetrable code I've ever seen -- and I've written microcode. So I'm curious if there are languages that are hard or impossible to write beautiful code in.
JAMES: I think there are. I think there’s languages where it’s harder. I mean… what's that language where it’s actually a 2D grid and you actually follow the grid around…
DAVID: Oh, the Befunge.
JAMES: Befunge, yeah. So you actually follow the code around. So I mean while it’s possible that certain algorithms could be expressed well that way, I'm pretty sure there are some that would be just a freakin nightmare to read.
DAVID: I would argue that a language is impossible to be beautiful in if you cannot rise above its elementary components. So you can write beautiful assembly language if you are willing to learn the 30 or 40 key operators that you see all the time and then use the call operators. I know they will start abstracting up into functions. But if you stay at a low-level chunky, chunky, chunky, you might as well be writing brain screw -- since we are not an explicit plot podcast -- but the brain language only has five tokens or 8 tokens; and as a result, the program looks like line noise. And it’s ugly; it’s nasty. It just looks like line trash. And that I think is the deal for me; I hated Lisp’s parentheses. And the reason I think that people hate parentheses especially in Lisp, is that parentheses are the only accidental complexity in Lisp. And it’s like you look at Lisp and all you see are all these freakin parenthesis. Where in Ruby, people don't see the complexity, the accidental complexity, because over here it’s a ‘do’ and over here it’s a pair of curly braces. Over here it’s an ‘each’ yielding to an array, because we can't actually map the thing; we actually have to yield it as a generator. So the accidental complexity varies enough, that it kind of blurs and drops into the background. But pick up Java and you should hate ‘public static void final’ just as much as you hate parentheses.
JOSH: So I want to respond to that in a different mode; that if you look at things… a well-designed building and attractive beautiful buildings, there are certain things that you do in the architecture of buildings to make things visually appealing. And one of them is repetition of common elements. So you'll have a column A with columns spaced regularly. But if you look at a wall that’s composed only of cinder blocks and has no other architectural detail, it looks ugly. It doesn’t even look elegantly simple; it just looks ugly just because you just took the same block and repeat it endlessly. But you can build things out of cinder blocks that look beautiful.
AVDI: I think the language is that… oh wait, I interrupted someone.
JAMES: No, it's fine. Go ahead.
AVDI: I think the language is that lend themselves to be maybe the ones that lend themselves to a fractal program shape. I think maybe part of the reason that internal DSLs are so popular in Ruby, I mean, the fact that you you might have some of these sort of very high level definition of something, like a chef definition or something like that, in this DSL and yet the form of the DSL is very similar to the form of your low level code, so you have that kind of fractal feel.
JAMES: I was actually going to say almost the same thing that David was talking a lot about how we have to be able to build abstractions. And what I think he basically means by that is we want to be able to slowly morph the programming language into the language of our problem domain, so that we can solve it that way. And I think in Ruby, we're very tuned to that. For example, I've been noticing this pattern in Ruby code that I wanna talk about on of my upcoming talks, but we used object inheritance in a totally different way. And one of those ways is that we use object inheritance just to give ourselves a space to lock down the DSL -- which is basically what active record is. If you inherit from active record base, not necessarily for the traditional reasons, you inherit from something in a programing language, is so that you have this space between the word ‘class’ and the word ‘end’ where you get this magical DSL of validations and associations and stuff like that, right? And that pattern is common in Ruby. We are commonly doing that; defining this localized DSLs so that we can zone in a problem.
JOSH: Amazingly enough, that’s a manageable approach. A lot of the Lisp-like languages come with defining ways of defining higher level syntax on top of the fundamental syntax; and it usually ends up being just a big mess because people go off and define their own syntax. And there is so much flexibility there, that you can get lost in it.
CHUCK: All right, we have one more tweet that I wanna put out there. Rob_rix on Twitter, he said, “Readability, methods and variable, self-document and are not too clever.” Which is kind of different from Timothy Rand. And “Brevity factored at a fine grain, so each phrase is short and sweet.”
PETER: I generally agree. I like that tweet.
JAMES: I prefer brevity over the long stuff, I think.
DAVID: Yeah, I'm going to speak to that long line of math with that comment above it that said, “This rights the motorcycle.” Why didn’t I, for example, just write motorcycle, this was in C, that motorcycle or p motorcycle arrow right self. I could have done that. I could have called the function on the motorcycle object, actually with C, not C++, so I would have to call the function on the structure. And the question is, “Why didn't I do that?” And the answer is because I was writing C for the PlayStation -- for a video game -- and I did not have enough time to set up a function call stack; I couldn’t afford the overhead of a function. Anybody remember that? Anybody code in the 1990s, when you couldn’t afford to call a function? And so it was idiomatic on…
JAMES: It’s still basically the same on Ruby.
DAVID: Yeah, we ignore it and we try to avoid, and we try to paper over that. And so it was an acceptable idiom to team that my Physics function was 250 lines long, and it’s because it had to be --- because it couldn’t call any other sub functions.
JOSH: You didn’t have an optimizing compiler that would inline?
DAVID: This is 1999 and the PlayStation tools were actually circa 1978. [Laughter] Game platform compilers were really way, way, way behind state of the art back then. Actually the physics function ended up getting to the point where it finally reached 800 lines of code, and our game suddenly dropped from 30 frames a second to 15. And we went in and debugged it and then found out that the physics function would no longer fit in the function cache on the PlayStation. And so we had to break it into two separate functions, so that it will fit in the cache and stay in the CPU’s RAM. And so, adding the function call doubled the speed of the program back up to 30 frames/second.
JAMES: I think that’s an interesting point though. As I've evolved, I've grown to hate comments more and more. And originally it was like, “Oh, comments are great, they tell me what it does.” And then I realized that they lie to you a lot of the time. And I was like, “Oh, maybe that’s not so good.” And then it was like, “Well, it's okay to put a comment when something is tricky and I need that little explanation hint.” And then more recently, I've began to that in that case, you just wrote the code wrong. I used to write these… like in Test::Unit, I’d write like ‘assert’ and then something and I’d put a comment at the end of the line telling me why I did that thing, what it meant, right? Until I realized eventually that assert has that second argument, which is for the failure message, which that’s [inaudible] job; that’s what it is supposed to do – tell you what went wrong. So you just [inaudible] the comment into that message.
AVDI: I have this working [inaudible] that says, b the time I'm done with the code, somebody should be able to come in and code review the code, and say, “This is so obvious, an idiot could have written it. Why we are paying you?” I can't say that I always hold to that rule…
DAVID: Because you couldn’t have done it yourself. [Laughter]
AVDI: But you know, I keep that rule in my head as sort of a counter balance to my natural inclinations as a hacker to do clever things. It’s just kind of my personal rule. The rule of, “Make it so simple, it looks like an idiot could have done it.”
DAVID: If your code is so simple that it looks like some idiot could have done it, that leaves you free to build an application that blows people’s minds.
DAVID: So I have a comment. Chuck is going to start cutting us off for time here, but has anybody ever had any experience of working with ‘dishonest’ code? I wrote a rant about this a while back, where like young programmers will spend all their time sneaking up on the compiler, to try and trick it into giving the answer that they want, instead of just saying, “I want this, do it.” And break it down and break it down, and break it down correctly. And because I'm the king of inappropriate metaphor, I feel like sometimes is there a difference between taking some code and saying, “I love you sweetheart, but we need to improve your character; you need to sit up straight and have good posture, and you need to wash your armpits and you need to bathe every day,” to improve the character of your code; versus, slicking up a fat daughter for a beauty contest. [Laughter] Okay, you guys are laughing. So you know what I'm talking about, right? In the code, right? Has anybody had that experience of working on just outright dishonest code?
AVDI: Okay, really quick story about dishonest code. One of my favorite lines of code ever was a line of C code, that it was a #define which is basically like a global constant definition. And it’s a #define seven. So the word “seven”. “#define seven = 5” -- and it’s the numeral ‘5’. DAVID: Awesome.
AVDI: I'm not done. And there was a comment next to it that said, “twelve”. [Laughter]
CHUCK: Wow, oh my gosh.
AVDI: So was two lies in one line.
DAVID: The best one I had along those lines was about comments would lie to you… and I tracked down the history in this one. It was assembly language and line of code was xor eax, eax. If you know your assembly language, if you xor a number with itself, you get zero. And on 286 era processors and older, it was faster to do that than it is to move a zero or write a zero to the eax register. And hint: the 286 didn’t have an eax. So there's your first code smell. It’s just as fast to just say, put a zero in eax. The comment next to it was put 1 in eax.
DAVID: And somebody had written put a 1 in eax and so it was, “move eax,1” and then they changed it later to “move eax,0” because they were putting the wrong constant in. And then, somebody came along and didn’t update the comment, and then somebody came along and optimized it to “move eax,eax” and left the comment “put 1 in eax”. And the end result is unless if you are in familiar with this 1980s era assembly language optimization, that this is actually a zero, you would believe the comment over the code. And down the road you would go 180 degrees out of phase with what was actually in the register.
JAMES: That’s kind of interesting. So just a throw a counter example to what we're discussing here, one of the things I did recently at the OK.Rb meeting, I wanted to try to bring up a topic that could help everybody. So I just went in and did a ruby -h in the shell to show the command line options, we just started just going through the list and walking down them and showing them to people. And along the way, we covered things like –p, -n, -i, which allows you to write simple Ruby scripts at the command line. I actually use those a lot. I'm pretty big on using Ruby in my shell whenever I can, to help me out with things. And I started showing tricks like rdf. Then I showed the one where you can do “if regex range operator, regex” And if you guys don’t know that, then you need to go back and look at Perl or atheist how Ruby inherits that one.
DAVID: That's the flip flop, isn’t it?
JAMES: Yes, it’s the flip flop. And I would probably describe that one as pure evil, but I do use it. I have used it and you it is probably dishonest and things like that, but maybe there are certain areas where it's okay. Like if I'm slinging together some shell command and the flip top operator helps me, then great, more power to me.
AVDI: You know, I would say that in that particular case, that’s something that pretty well expresses what you wanna do. I mean, you are selecting a range between this match and this match.
DAVID: And James, you spent a lot of time processing log files. Otherwise you wouldn’t have written the FasterCSV library. And the flip-flop is beautiful for that, right? It starts processing once you’ve finished processing all the header fragments of the file, now process the guts of the file, now stop processing because we’ve reached the footer of the file.
JAMES: What's funny about the flip-flop operator is try to expand it sometime. I mean, seriously try to expand it into the code that it requires to do the same thing. You know, I mean, just the start, you’re doing regex range regex, whereas really it should be something like $_matches regex .. $_matches regex. But even then you need a variable to track state…
DAVID: Yeah, you got a state machine in there. “Am I done processing the header? Am I done processing the data?” Yeah.
JAMES: Yeah, it’s an interesting, concise thing. And even like maybe to give a simpler example, almost every bash shell example I see, somebody doing something in bash where they want a conditional, I would say that the ‘and’ and ‘or’ operators are way more popular in bash as conditionals, than using an if because the ‘if’ in bash is clumsy. Whereas the ‘and’ and ‘or’ is very concise and simple, and it does a conditional.
DAVID: And very elegant, yeah.
CHUCK: All right, well I've got to cut it off, so that we can get through the picks and still end in less than 13 minutes. So we have two guest panelists, so I'm just going to explain really quickly; picks are really just anything that makes your life easier. It’s cool if it’s code related, but they don’t have to be. So just any tool that you are using or anything like that. Let’s go ahead and start with Peter; we haven’t heard from him in a while.
PETER: Yeah, was it Josh that was talking about dishonesty in code?
PETER: Oh. [Chuckles] Everyone thinks Josh said everything in this podcast.
JOSH: That's usually how it goes. [Chuckles]
JAMES: Josh’s episode.
PETER: Yeah, I was just going to say like the main dishonest thing I see is where people just don’t put test in, but they put the whole test harness and everything in, and you download the library and run with the test and that's like, “pending, pending, pending”. I actually hate that. That is very ugly code. So yeah, just to bring you one thing that’s slightly relevant to this. You may have heard of a guy called Michael Edgar. I think he works for Carbonica. He's been working on his thesis, which is called Static Analysis for Ruby in the Presence of Gradual Typing -- which I know sounds super, super exciting, but it’s basically resulted in a project called, Laser, which can be used to perform kind of static and semi-static analysis of Ruby code. And he's put together this toolkit called Laser that allows you to do lots of really cool things, like analyze the scopes of things, where the scopes are perhaps wrong within code, where it’s hard to tell like certain things that are going on blocks that are being ignored, stuff like that. I think Laser can eventually be used to produce a really good code beautification tools and all that kind of stuff. So I'm going to put in the link to his project for that -- and if you want to read his thing. Yeah, that’s my one thing. I´ll pass it on.
AVDI: Not to mention his blog posts are also fantastic.
CHUCK: Where is this blog? Just put a link in the chat and we'll add it in the show notes. All right, Dave go ahead.
DAVID: All right, so I always do something weird, so I'm going to do something just plain Jane vanilla and already in your toolkit probably, which is Minitest -- especially if you require Minitest/spec. I love Rspec and I love Cucumber, because I love those DSLs and I love writing expressive… I think expressive beautiful code. I'm not a huge fan of straight up Test::Unit where you have the assert, assert, assert. I love actually spec’ing things out and saying “It should behave this way and it must do this,” and that sort of thing. And I was really kind of weary of Minitest until somebody showed me Minitest/spec. And it’s for vanilla Rspec, it’s a drop in replacement; it’s the same syntax, it does the same things. And it is already rolled in with Ruby. And so, I believe it does not do as much monkey patching and craziness and weirdness as Rspec does. And the other simple tool -- actually has ‘simple’ in the name -- it’s a gem called SimpleCov. And you include SimpleCov and in your test harness, the very first thing you do before you require even your test framework, before you require any of your libraries, you require SimpleCov, and this turns on coverage logging of every file that gets touched after it loads up and starts. And it emits it out to a cove directory or coverage directory. And those two tools, make it so that on a brand new project you have code coverage metrics in under 2 minutes. And you are up and running and you have coverage, and there's no high ceremony; it’s just, “Give me coverage, give me test, let’s go.”
CHUCK: All right. James, go ahead.
JAMES: Okay, as I said many times, I'm drugged, so not clever. So instead, I'm just going to list the things I've been reading lately, that you should be reading too. And so I will start with the reason both Avdi and Josh are on this episode is because they wrote awesome blogs about beautiful code mostly -- or at least ways to get there or what good code practices. I think you should read both of those blogs. For Josh, that’s Has Many Through and Avdi’s is Virtuous Code, is that right Avdi?
JAMES: So those blogs, Google them. And if you are not reading them, you need to. They are amazing. Avdi recently did an awesome post on Ruby’s warnings, and why they are amazing and why you don’t understand them. And that should be required reading for all Ruby developers. And Josh has an awesome post pretty high on his blog that’s about improving readability by using Booleans to indicate true false flags… or sorry, symbols in the place of the Booleans as flags. And I've actually written about that exact same topic on my blog before, so I totally agree with that. And it’s a great and it’s stupid simple and it makes your code better. So both of these blogs, you should definitely be reading. And then for non-code, I've been reading John Ronson’s The Psychopath Test. And it's really great book about how he slowly gets into the world of identifying psychopaths and learns what the test are and you get the little criteria for how you should spot psychopaths. I'm only half way through his book at this point, and already, I'm thinking about family members I know and taking them off on the test and to see how far down the psychopath scale they are. So I really recommend that everybody read this book because next time you run into me at a conference, I'm probably sitting there listening to you talk, rating you on the psychopath scale, so you might as well at least be doing the same thing to me. So I recommend The Psychopath Test.
CHUCK: They actually had an episode on This American Life on the psychopath test, and it was really interesting; talking to people who would pass the test and failed the test, and it was really interesting.
JAMES: It is very interesting.
CHUCK: All right, well, I´ll go ahead and go next. One thing that I've been using a lot lately, I mentioned before that I got a virtual assistant, and she’s actually been helping me post a whole bunch of stuff. And she is actually posting all of my podcast episodes now, and I just pass them up to the raw WAV files, I pass them up to her using Dropbox, and then she processes them and uploads them and sends them… I get them back so I can put them in videos and stuff. But anyway, so that’s one tool that I highly recommend is Dropbox. Another one that I've used in the past to kind of get a feel for what is going on in my code, and it doesn’t necessarily lead you down the path of beautiful code, but it can point out problems in your code, and its implementation is metric_fu, which has a whole bunch of other like reek and roodi, which some of them bring up like cyclomatic complexity, and there's another tool reek is code smells. And so, even if it’s not giving you beautiful code, it can least give you better code. I´ll go ahead and put that in as well. It’s something that I've really liked and I've used in the past. And you can hook it into your CI machine and get the reports like every week and see whether you are improving or not improving.
DAVID: I wanna say there's an updated version of Metric_fu out there called metricality. I´ll look for that and include that if I'm right.
CHUCK: Okay. And then, let’s go ahead and let Josh give us a couple of picks.
JOSH: Okay, cool. I got to say this is one of my favorite bits of the podcast; the interesting picks that people put out there. So I have two. Last week there was a fair amount of time that the panelists talked about the fixtures in Rails, right? That was last week?
JOSH: And so one of my picks is the fixture_builder gem. I don’t know if anyone is familiar with that. It was loosely based on the fixture scenarios library that Tom Preston-Werner did way back when… way back when was a couple of years ago, I think. [Chuckles] So one of my favorites Ryan D -- he is RDY on GitHub -- has this called fixture builder and there's a gem from it. And what it does is you can programmatically create and populate… you can create objects and populate your database using whatever technique you like; you can just directly allocate active record object, you can use mechanize -- or factory girl if you are that crazy. And then once you've populated the database, fixture builder will dump the database into a bunch of YAML files, and it will create names for them based on rules about which of the fields or attributes in the records should be used to name it. And this I guess gives you the best of both worlds in dealing with fixtures. You can create them in whatever style you like, and so you don’t have to be dealing with the YAML files and figuring out what id and when one yaml file should be hooked into the other yaml file. And it’s a lot more robust than the foxy fixtures hash based associations. So you can create them however you want, and then you get all the benefits and speed of having yaml based fixtures.
DAVID: I am going to track down Ryan and give them my personal thanks, because last week I took a legacy project and a set of key models I added a method called fixture names, so that I could build yaml files out of the database, because everything depended on the structure of the data.
JOSH: I should say with one little bit of advice around there is that, fixture builder works best when you start your project with i. Trying to retrofit fixture builder into an existing project is much more difficult than I would like it to be. But when you start with it, it works pretty well. And I think the problem with transitioning to it is that usually, people create a lot of adhoc test objects in their tests, and the fixture builder works best if you are using what at pivotal, what we call the “cast of character” pattern for fixtures, where you wanna have all of the different scenarios that you are testing for, present in your fixtures all at once, so you may need to come up with list of players, the cast of characters for your… for all the fixtures that you’re using. And you wanna make sure that you are not breaking things when you add new fixtures there, so. That’s pick one. And I have a very quick pick for the second one, and that is Vivo Barefoot Shoes. So I think a lot of people have seen the Vibram FiveFingers shoes that look like you are wearing toe socks. I have a pair of those and I love them; they are actually really great shoes, very comfortable, I've been caving in lava tubes with them, they are very durable. But I don’t like that they don’t look like shoes and they also don’t have much protection on the top part of the foot, so if I'm riding on the subway, people can step on my feet and I go, “Ouch.” But Vivo Barefoot is part of a brand called Terra Plana, and they have shoes that have the same sort of barefoot action as the FiveFinger’s, but they look like regular shoes. And I've been wearing them for coming on two years now, and my feet have actually relaxed and changed shape and out and I have much stronger feet. I can walk around all day in this shoes and my feet still feels great at the end of the day. If I come home from work, I walk in the house, I don’t bother to take my shoes off because they feel great. And they are very comfortable shoes, they look nice. The one thing I´ll say is that it is not a perfect shoe, and they do have occasional quality problems, but the customer service is pretty decent and they have a good exchange program. The only place you can buy them in the United States at a store is in New York City. Otherwise, you have to order them online. I love them. They are great.
DAVID: So in a podcast about beautiful code, Josh’s pick is deceptive footwear. I love it.
JOSH: Yes. [Chuckles]
CHUCK: [Chuckles] So I would also like if there's a link to a post somewhere about the cast of characters pattern. I think that’s interesting, but I don’t think we have the time to go into it right now.
JOSH: I don’t think it’s ever been written up, but it's probably worth doing.
CHUCK: All right. Avdi, what picks do you have for us?
AVDI: Well, I've got a tool and a paper. The tool, it's not that new, but I've been getting into it lately and it's been really nice. It’s called Guard. And if you are familiar with auto test and Rspec or various attempts over the years to auto run tests in the background as you change your files, it's sort of in that vein, but it's a lot more generalized. So it has this amazing array of plugins where you can plug in your tests so that it will run your test for you so you edit your code. You can plugin so spork, so that you can restart your spork server every time you change something that has changes the overall application environment. It will restart passenger for you with the appropriate plugin. And I've even learned about like some new tools that I didn’t know about, just because they had guard plugins. So like, the live reload tool. So I've been getting into the habit of just throwing a guard file into all the projects that I work on, so that it will just start things up… start all the services up that I want to be running, while I'm working on that project. As a matter of fact, I'm recently I wrote a little inline plugin that would start up the Redis server for a project that I was using that required Redis. So guard is the tool. And the paper I wanna recommend is called Object-Oriented Programming: An Objective Sense of Style. It’s from 1988. It’s from the Uppsala 1988 proceedings. I read this because I had gotten into some conversations as a result of a blog post that I wrote about the law of Demeter, which is kind of a rule or a guideline for object oriented programming. And I wanted to kind of make sure that I understood it as well as I thought I did. So I went back and I read, this is the original paper where the Law of Demeter was introduced. And it's a fascinating read. I think everything in it is completely applicable to the stuff that we are doing today. And there's just some good insight there into… I think it's really appropriate; it’s an apropos of the conversation that we had today, because basically the origin of the paper and the origin of the law was a group of people with a large object-oriented programing program saying we know that certain values seem to be good in object oriented programing, is very simple heuristic that we can apply to our code. That when we evaluate it for that heuristic, if that heuristic matches, then the code will have all these other good qualities, like loose coupling and information hiding and stuff like that. And the heuristic that they came up with is what came to be the Law of Demeter. I'm not sure how its pronounced.
DAVID: I recently had the principle of, “Tell, don’t ask,” drilled into my head hard because of Smalltalk. And I was trying to explain it to someone, it means this, it means this, it means this. Basically what it means is you can't ever call an accessor; you have to actually just send the message. And somebody said, “Oh, it’s the Law of Demeter!” And I said, “No, it is exactly the Law of Demeter.” You cannot say my framework.getwindow.drawafunction because that middle function is an accessor. You are pulling something back to send the message to that.
AVDI: And the great thing about papers from before the 90s is they were working with Smalltalk, you know the common Lisp object system. And so it was in that period before everyone’s brain had been broken by Java.
DAVID: They hadn’t been corrupted by formalist philosophy, but that’s a rant for my other podcast. JOSH: I think it was C++ that broke people’s brain first, but yeah.
CHUCK: [Chuckles] JOSH: And as an almost classics major, in Greek it’s pronounced ‘De-meter’. But it may have been the Demeter system that the love of what I pronounce ‘De-meter’ comes from.
AVDI: Yes. It was the Demeter system. And I don’t know how they pronounced it.
CHUCK: All right, well this is a quickly devolving. So I'm going to high jack the conversation.
DAVID: Actually Chuck, before you do; for people listening to the podcast but not actually checking the show notes, the gem that I suggested before is called Metrical, not Metricality. It’s just metrical. Gem install metrical.
CHUCK: All right, sounds like a magical metrical gem…
CHUCK: All right, well I wanna thank you all for coming and joining in the Ruby Rogues podcast. We have once again, in no particular order, David Brady.
DAVID: Totally awesome! Oh wait, that’s Peter.
CHUCK: [Chuckles] Avdi Grimm.
AVDI: Thank you very much.
CHUCK: James Edward Gray.
JAMES: Totally, awesome!
CHUCK: Josh Susser.
JOSH: Hey, it’s been great.
CHUCK: Peter Cooper.
PETER: Y’all stole my catch phrase!
CHUCK: [Chuckles] And I'm Charles Max Wood. We will catch you next week. In the meantime, you can get the show notes at rubyrogues.com. I have people trying to spell it Ruby “roads” it’s not. I would also appreciate anyone leaving comments on the blog, and leaving a review in iTunes.
DAVID: Ruby roads is Ozzy’s guitarist. You are so dumb.
JAMES: Wait, did you forget Avdi in the sign off?
AVDI: No, he got me.
JAMES: Okay, I must have not paid attention.
CHUCK: Give me some credit here.
AVDI: Drugs are kicking in.
JAMES: Drugs are acting, yes.
CHUCK: [Chuckles] Yeah, if we hear some major keyboard mash and then James is silent, we'll know what happened. All right, so thank you again for listening. We will catch you next week, where we will talk about something else interesting and involved. If you do wanna hear about something, go to rubyrogues.com, click on “request a topic”, type in what you want us to talk about. And if it gets enough votes, we'll give it an episode. And that’s it. Thank you again for listening.
DAVID: Thanks everybody!