POSTS
Teaching Ruby over JavaScript
BlogLiteracy
Chris Granger recently published a post that asserts “Coding is not the new literacy.” He points out that “literacy” is defined as the “laying” of characters into units that bear meaning (letters to words, words to sentences, sentences to thoughts). But “literacy” is a proxy noun for something vastly more important: a technology for storing information such that it survives across people, ages, cultures.
I recall Ovid whose prophetic close to the “Metamorphoses” was:
And now the work is done, which neither Jupiter's wrath, nor fire, nor the
sword, nor greedy time can abolish....my better part[this work] will be
immortal...
(Translation mine)
Literacy was magic because the laying of letters yielded immortality. Ovid supposed that his work’s immortality would require mouths, ore legar populi (“recited in the mouths of the population,” recitation as mimetic preservation), but with the advent of cheap yet durable writing technology, immortality could be more cheaply gained by means of finding home in the books of the populus (publication as mimetic preservation).
But what if we could make the component pieces of abstract thinking similarly immortal?
That’s exactly what programming and its concomitant activity coding are.
Coding
“Programming” is the skill wherein we calm our distracted minds into expressing a sharable, abstract computation activity that solves a problem. “Coding,” similar to “literacy” is the mechano-visual skill whereby one expresses the solution. “Programming,” therefore is one: fungible, transcendent, and unbound to any particular language. “Coding,” by contrast, is necessarily bonded to an “implementation language.”
As a teacher my pedagogical approach privileges teaching “programming” over “coding.” Yet I must wrestle with this difficult conundrum: to teach “programming” I much teach students “coding,” and that means I have to choose a language of implementation.
Ruby
I recommend Ruby. If my goal is to teach “programming,” then I want a language that has a clear syntax, has very few surprises and allows the student to focus on the “Tao of Programming” and not the “WTF of function-level scope?” A friendly syntax allows students opportunity to work at understanding “programming” before understanding the multiform and delightful ways that different styles of “coding” can provide more or less expressive, concise, or clever ways of achieving crafting the same “programming” unit.
As my colleague, Anne, once pointed out: “It’s easier to explain to someone what a mansion is after they know what a hut is.” If they’ve never seen either, you’re in a check-and-egg situation. To me, Ruby provides the maximal perception of programming while keeping the syntax, surprises and tangles of “coding in Ruby” out of the way.
Also, experienced Ruby hands know that thanks to lambda
s, blocks, and
Proc
s, Ruby can be adapted to reach extremely sophisticated utterances while
its introductory interfaces remain friendly.
Why Not C?
One might suggest that C reveals the fundamentals of the machine in a small, approachable, logically consistent fashion. C also has the virtue of being like Plato: all further work is largely a response to the framework he / it established. I recall a conversation with Aaron Hillegass in Rome where he supposed that he would teach his (then!) young sons C as a first language.
I can’t disagree with the beauty of C as a first language: it invites engagement with the machine, invites understanding of memory, and can be understood, beautifully, as a series of markings-off of lengths on a single length of tape (no coincidence when one of its primary storage media was, uh, tape).
Nevertheless, to write a primitive CGI script in C a student will quickly step
into the challenge of string parsing in C, they will have to write separate
handlers for GET
and POST
, etc. Lacking experience with discipline around
modularity, managing complexity, and pointers, the “programming” lesson gets
lost in the “coding” ephemera.
The method I teach under tries to educate rapidly in a small unit of time. For such a program C seems unnecessarily clumsy. One of C’s many virtues is clarity for those who already know how to program, to presume that for a student is a disservice. I recall Larry Wall, creator of Perl, once saying that he learned the C language in a trivial amount of time, but learning its standard library took a non-trivial amount of time.
Why Not JavaScript?
JavaScript is a language whose growth seems to be on a hockey-stick of growth. That it is part and parcel of a widely-distributed development platform (the browser) with an integrated REPL (developer tools) would seem to make it seem preferable to Ruby whose dependency / version manager toolset options present a complicated hurdle to the beginner.
While JavaScript’s development environment bootstrapping is enviable, I feel
the language has a number of strong drawbacks. First, it’s rather verbose. If
I never have to type function
again, it will be too soon. But I consider
that con to be trivial compared to the following drawback: to accomplish simple
work (say map
ping over an array) a number of implicit mental models are
required to already be in place. Further there are some scary bugaboos lurking
in minds where those mental models are imperfectly present. Consider:
twice_as_large = [1,2,3].map{ |x| 2 * x } #=> [2,4,6]
versus:
var twice_as_large = [1,2,3].map(function(i) {
return i * 2;
}) //=> [2,4,6]
While an experienced programmer may see no significant shift, consider the implicit understanding in the JavaScript example:
- Anonymous functions
- Function as first class data i.e. is not executed
return i * 2
is not in the same context as[1,2,3]
was- Arity is not enforced and desired data may be present but not “captured” by a parameter
arguments
as a hidden construct (part and parcel of arity)- etc.
The Ruby example does the same work but has, in my view, far fewer punji pits laying in wait for the tyro. Based on its implicit assumptions around simple work, JavaScript strikes me as being a sub-optimal first. As an audience member at the first NodeConf, nothing was more humanizing and ego-salvaging as watching [Ryan Dahl][dahl] muttering over a livecoding bug disparage whoever decided to implement Node in Javascript.
Conclusion
Thus, for the moment, I recommend using Ruby as a primary teaching language. While Ruby is the coding language I recommend students start with, owing to it’s ability to get out of the way and help students learn programming, I believe it is the optimal choice. Having seen and felt the Tao of Programming, I’m positive that learning to code any other language is a vastly simpler task.