Compendious Thunks: Intro
Video transcript & code
Happy new year! And welcome to the 2017 season of RubyTapas!
Let’s talk about software design patterns.
You know design patterns, right?
I mean, you’ve read this book. Well, you’ve flipped through this book. Okay, you have this book on your shelf, and you’re going get around to reading it someday.
Now, I’ll be the first to tell you that this book is not the be-all and end-all of design patterns.
It may have introduced the subject to the world, but the patterns literature is much, much deeper and richer than just this one book. If you’ve been watching for a while you’ve seen some of the episodes that were drawn from this wider literature.
But here’s the thing.
In my experience, most programmers don’t have a solid grasp on even the foundational patterns in this book.
And look, I’m guilty of this too. I mean, I don’t know about you, but if you asked me to explain the difference between the adapter pattern and the proxy pattern off the top of my head, I would have some trouble.
But this stuff matters! Design patterns are one of the best methods we have for learning from the experience of other programmers. They help us to understand and communicate about code at a higher level of abstraction.
And most of the patterns in this book are still really, really useful.
But I’m not going to tell you to go back and read the gang of four book from cover to cover. Frankly, it’s kinda dry. The examples are in C++. And to be honest, it doesn’t give you a very good feel for how the patterns look in practice.
Fortunately, there’s a better way.
Chris has created a new video series that goes in depth into the foundational design patterns.
It’s called Compendious Thunks.
And it’s fantastic.
It’s fun. It’s full of live code examples. And it doesn’t just stop with laying out the basics of the patterns.
Chris goes into variations on the patterns. He talks about how to choose between similar patterns. And he goes into the cases where the patterns fall down, and a different approach is needed.
Why am I telling you this?
Well, I am super excited to say that Chris is letting me show you some compendious thunks episodes on this show.
There’s just one tiny catch.
The Compendious Thunks examples are in the Dart programming language.
But don’t panic! Because it turns out, you pretty much already know Dart; you just don’t realize it yet.
In the video you’re about to see, Chris Strom is going to teach you everything you need to know about the dart programming language in 5 minutes.
It’ll get you ready for the compendious thunks episodes that are coming up. And as a bonus, you’ll know a new programming language!
For the next few weeks after this episode, you’re going to be seeing a small selection of videos from the compendious thunks collection. But don’t worry, this isn’t going to become DartTapas or PatternTapas. I’m busily cooking up more traditional RubyTapas dishes that will be ready in the weeks and months to come. I just felt that you would get the most benefit out of these design pattern videos if you saw them back to back, rather than scattered among other, unrelated RubyTapas episodes.
So now without further ado, here’s Chris Strom with the introduction to Compendious Thunks. Enjoy!
Dart is the absolute best language for exploring design patterns. In fact, Dart may be the greatest language that you've never used.
You know Dart. It's designed for familiarity. So even if you've never seen it before, you know Dart. It's got the fundamental ingredients for classic design patterns: types, inheritance, interfaces and more. But what makes Dart special for learning patterns is that it is the most compendious, thunkiest language ever created.
So that's the claim. Let's see if I can back it up...
[embed_dartpad title="Code in this episode starts here…" id="ee3e3a37e46e42b38c1ab12dec52948d"][/embed_dartpad]
Consider a Robot class. It needs x and y integer coordinates. Dart constructors are the name of the class (
Robot), arguments declared in parentheses (x and y), and a body (which assigns the x-y arguments to the x and y instance variables).
We'll need a getLocation method that reports the x-y coordinate pair. Open-quote, paren, close quote, plus, the x-coordinate, plus, open quote, comma, close quote, plus, the y-coordinate, plus, open quote, paren, close quote, and semi-colon. It's a little ugly, but show me one language that's actually got beautiful strings.
Whoops! Well, here's a benefit of types. I can't combine strings with integers like x and y. Well,
toString() to the rescue. Thanks to type warnings, I can fix silly mistakes like this immediately.
Dart runs code from a main entry point. In there, I declare a new robot variable,
r, and assign it to a new instance of Robot, starting at 0,0. Some print statements to demonstrate functionality of the robot and... the robot starts at 0,0. Working code: always nice!
So great, it's familiar. The typing was nice, but, admittedly, the rest might not feel like that big a win. Certainly not compendious or thunky. Let's keep playing...
So why types? For humans! Types found my mistake with
getLocation before I got too far astray. Plus, there's code completion, if you go for that sort of thing, and nice doc generators. But really, it helps make code easier to read for people.
Next, note "this". You almost never need it. Dart just knows that you're talking about instance variables. Oh, and Dart is a language with beautiful strings -- thanks to dollar-sign interpolation.
Dart also has nice affordances for common coding practices. Hash-rocket return makes for nice, small methods. Getter methods eliminate the need for silly method names like getLocation -- the location getter looks just like a property. Nice!
Dart constructors are nothing short of glorious. Instead of passing variables only to perform a simple assignment, just declare the assignment in constructor arguments -- no body needed. Optional parameters with default values -- deceptively hard in languages that force you to roll your own -- are also easy in Dart.
The end result, friends, is some compendious code.
So what about thunkiness? For that, let's add some methods to move the robot right, left, up and down, adjusting the x and y coordinates accordingly.
If we move the robot right, the robot ends at (1,0) -- x of 1 and y of 0. Move up instead and the robot ends at (0,1). No surprise there. But what's really cool is that we can assign the method to a variable, invoke that variable and... still move the robot.
These are tear-off methods. We tore them off the object, but they retain awareness of the object. And, when we invoke the method, thunk! There we are right back in the original object's context. That is super helpful in so many of the functional patterns that we use.
And, it turns out that this is our first pattern. As we'll see in the first screencast of season 1, the
move variable is a Command Object. It's the combination of a receiver, the robot, and an action,
[embed_dartpad title="Compendious, thunky, command code…" id="886ea294dc0ec6e923881a0345f4c40d"][/embed_dartpad]
Look, Dart's not perfect and maybe it's just not for you or your current projects. And, as with any language or tool, there are gonna be annoyances. But I think they're far outweighed by its features.
While nice, that's not what make Dart a wonderful learning language. It's the thoughtful, programmer-friendly design. In four minutes, we went from nothing to introducing our first design pattern -- thanks to Dart's compendious and thunky nature.