Great idea on the 12 vs. ‘12’ problem, Mark!
I was thinking about it last night, and came up with something similar:
RUBY AS CALCULATOR
For a number of reasons, I don’t think irb is a good tool to start with, so
I’m only talking about ruby in .rb files. One of these reasons is that one
thing is easier to learn than two (or three, if you use the ‘-e’ switch as a
third was of running Ruby code), so I picked what I think is the simplest
and present it only.
So after they get Ruby installed, and assuming they know how to run commands
on the commandline and create/edit text files (not large assumptions)…
Type the following into a text file, and save it as “calc.rb”
print (1+2)
That’s it! Now run it like this (enter this into your commandline):
ruby calc.rb
You should see a ‘3’ printed on the screen for you. If you don’t, you seem
to have something wrong with your installation, or maybe you typed something
in wrong.
Then I would try to find all of the possible error messages I could and tell
them what probably went wrong and how they might be able to fix it.
So that’s how it starts. I would tell them to experiment with it some,
typing in whatever numbers they want. I’d describe the arithmetic
operations +, -, , /, and **. (That '’ means ‘multiply’ is not
necessarily obvious to a non-programmer.) Then I would say that a computer
treats numbers with a decimal point different from those without, and tell
them the names Integer and Float. Calculators like they are used to only
use numbers with decimal points, so if they want their program ‘calc.rb’ to
work exactly like a calculator, they should only use Floats. Usually,
though, people don’t use them very often, so we won’t talk much about them.
If you try something like (10 / 3), you will get 3 because the computer
rounds down to the next integer. This means that (-10 / 3) gives -4,
because -4 is less than -3.
So that’s numbers… but what about letters? Words? Text?
The word we use for groups of letters is String. Here are some strings:
‘Hello.’
‘Ruby rocks.’
‘5 is my favorite number… what’s yours?’
‘Snoopy says #%^?&*@!’
’ ‘
’’
(No double-quoted strings yet: One thing is easier to learn than two, so
stick with the simpler one.)
Instead of printing a number, let’s print a String…
Then talk about things like
’Hello’ + ‘Betty’
‘Hello ’ * 5
’1’ + ‘2’
‘1’ * 5
The punch-line: Ruby is a Calculator for numbers and letters, for Integers,
Floats, and Strings… and many other things, too.
So… that’s a pretty good start. Look at how we secretly introduced a
number of neat concepts without even talking about variables yet! We
introduced a few Classes without ever saying ‘Class’ or ‘Object’.
Personally, I think the more we can push off concepts like those (but
secretly slip them in), the easier it will be to learn. The reason for this
is that DOING OO programming is natural! This is simply how we tend to
think. However, LEARNING (and talking about) OO programming is unnatural!
So we should allow them to do it without having to “learn” about it. You
certainly don’t need to understand what objects are, and how the Fixnum
class derives from the Integer class, and the ‘+’ method, to understand that
(1+2) should be 3.
I think that a good tutorial, like a good program, follows certain rules:
- DRY (Don’t Repeat Yourself)
Well, you will want to repeat some things, surely. In a tutorial, I take
DRY to mean “One thing is easier to learn than two things.” If you can use
single or double quotes to create a String literal, so what? You aren’t
giving the learner more freedom; you are doubling the amount of work they
have to do to remember what’s going on.
- Orthogonality (Law of Demeter)
Keep lessons uncoupled. Understanding a concept can depend upon
understanding more fundamental concepts. However, we often confuse just
what those concepts are. Do you need to understand objects and methods to
concatenate String objects? Nope. Do you need to know what a variable is
to teach simple iterators?
5.times
print 'Hi!'
end
…or…
(1 + 2**2).times
print 'Hi!'
end
No, you don’t. I think this sort of ‘uncoupling’ of concepts is crucial to
making programming easy to learn.
- Motivate Each Lesson
Simply, make sure you have a compelling reason for introducing a new concept
before you actually do so. If this rule is followed, concepts just flow
together, because they make sense in relation to the whole.
The idea is certainly not to teach them “bad” (or procedural) Ruby
programming; the idea is to introduce them to the concepts of good Ruby
programming without introducing new and confusing terminology, and without
exposing them to too many things at once.
Here’s an interesting test for would-be tutors: try writing a few programs
using no variables. Literals (Integer, Float, String, Array, Hash) are
allowed. See how much you can do! After a while, you will be desperate for
variables.
The idea is to get to a point where the learner is writing relatively
complex (for having no variables) programs, and then to introduce
variables. Look how lovely they make the program, how simple everything
becomes, and how much more powerful. At this point you have a student who
already implicitly understands a fair amount of OO already, and variables
come easily. (Why introduce variables at the same time as you introduce
what you put in them??)
Here are things I would teach before variables:
- The true and false objects.
- Comparison methods: <, <=, ==, >=, >
- Branching: if; else; end (case comes later)
- The while loop and break.
- The methods ‘puts’, ‘gets’, and ‘chomp’ (but not ‘chomp!’)
At this point a fairly complex program could be written, with an
input-handling loop and everything… but without a variable to catch what
’gets’ returns, it would be hard to do much with it. Now we introduce
variables and assignment. (This is the first time they see assignment.)
And so on…
BTW, I think the reason this whole approach works in Ruby and wouldn’t in
most languages is that Ruby is so clean and consistent; OO was built-in from
the start, so it doesn’t need to be ‘taught’ so much as ‘noticed’.
So, what do y’all think?
Chris