On Jun 11, 2006, at 22:24, James Britt wrote:

> Matthew Smillie wrote:
>
>> Basically, there are many ways to accomplish a given task, which   
>> makes it comparatively easy to write a program that - while it   
>> produces the desired output - completely misses the point of the   
>> learning exercise.
>
> If accomplishing a given task is *not* the point of the  learning  
> exercise, then what is, and why might students be unclear on what  
> is expected of them?

For introductory assignments, the results of the assignment are  
invariably already known, because otherwise how will the students  
know they're on the right track?  So how could the results be the  
point of the exercise?  The instructor knows them, the students know  
them, everyone knows them.  What the students don't know is how to  
get from the input to the output, and it's *that* process that you're  
trying to teach, not as a recipe, but as a skill.

This is the same in most forms of introductory-level teaching; the  
precise nature of your opinions about feminist imagery in Margaret  
Atwood's work aren't the point of writing a paper for English 101.   
The point of writing that paper is to learn the process of writing  
any English paper: develop and describe a particular thesis.

As a trivial (and somewhat absurd) example, let's say the exercise is  
to write an array-sorting routine.  In teaching terms, this has the  
practical value of getting them familiar with arrays and fundamental  
operations (setting, accessing, comparing), and demonstrates  
theoretical points about efficiency (bubble sort, anyone?),  
algorithms, and depending on exactly what the algorithm is, recursion  
or notions of combining small local operations to effect a global  
result.  On the other hand, a student could write "arr.sort" and have  
accomplished the same task having learned nothing more than how the  
docs are organised.

There are two less-trivial examples that I've seen a few times that  
are worth mentioning in this context.

Some of the students in the course I taught had only ever programmed  
in Prolog before - and a couple of them were extremely proficient at  
it.  They tended (in Java) to end up finding ways to make everything  
effectively global.  They accomplished the task, more or less, but  
did they learn anything valuable about encapsulation or OO design?   
Not really.

Similarly, a few students have come in having done some shell  
scripting or website PHP or Perl hacking, and the fundamental mistake  
they made was to do everything statically (in Java, so as class  
methods).  So, they had classes, which were pretty decent, but missed  
out objects and had to do some really odd fiddling to manage state at  
the class level.  Again accomplishing the task, but missing out on  
some pretty fundamental aspects of object orientation.

So no, the point of a programming exercise is not simply for a  
student to produce the desired output, but rather to teach students  
something more fundamental about programming in a practical way.   
Philosophically, it's not just where you end up, it's how you get there.

> I'm skeptical that Tim Toady is the culprit here.  If you, as the  
> teacher, don't want students diddling arounf with every syntax for  
> a conditional, then tell them the one form they are allowed to use  
> for the exercise and leave it at that.

Well, isn't that equivalent to giving them a language in which the  
expression of conditionals is more restricted?  What's the effective  
difference of the instructor saying "always write your conditionals  
this way" and the language requiring it, from the student's perspective?

In any case, conditionals are just one example, and the larger  
problem boils down to the fact that the students must learn, and  
learn on their own (in the sense that they might work together, but  
noone can copy understanding of their lab partners).  Specifying the  
style or allowed syntax for an assignment specifically enough that  
noone gets side-tracked is a fruitless task: you end up just giving  
them pseudo-code and a set of formatting guidelines.

That's pretty obviously undesirable, for one thing, you want students  
to get side-tracked every so often.  What you don't want them to do  
is get so caught up in the subtleties of the *syntax* that they miss  
the larger point of the assignment - not seeing the forest for the  
trees.

Think of it as similar to why we advise people not to optimise  
prematurely, because premature optimisation amounts to almost the  
same thing: a programmer becoming too focused on the specific  
implementation of one small piece of code, ignoring the larger task.   
For experienced people, this might be "how can I cache my search  
results?", but for beginning programmers, this very often is "what's  
the smallest number of lines I can use to write this conditional" or  
"that ternary operator looks clever, how can I use it to do this?".

I will admit, though, that it is a tricky argument, because the best  
students are the ones who experiment on their own and are smart  
enough to read their textbook or look up online docs, and  
discouraging them from this does them an enormous disservice.  But  
equally, you want to make sure that you're not setting traps for  
them; it's just as much a disservice if they spend all their time  
working on a one-line #inject implementation of a method, and don't  
learn how inheritance works.


>> Another difficulty is that while the syntax might *look* straight-  
>> forward, but in part that's because a lot of Ruby relies on   
>> programmers having an understanding of how programming works in   
>> general, and a lot of the generic terms can be elided or  
>> condensed.   When you're learning programming, you need to know  
>> about those  implicit bits, and having to write them out  
>> explicitly helps with that.
>> To give a concrete example, think of the 'return' statement -  
>> it's  *required* in Java for the method to return anything, and is  
>> optional  (but generally not used) in Ruby.  For someone learning  
>> Ruby, this  means they have to remember that the last statement  
>> evaluated is the  return value, which is just one more thing to  
>> put on their stack of  not-quite-understood concepts (and they  
>> have LOTS of those concepts  when they're learning).
>
> Actually, this is fundamental to understanding Ruby; expressions  
> return values; methods are a series of expressions.
>
> The "must remember to type a gratuitous 'return'" seems like the  
> extra work.

You're assuming that they're completely understood and internalised  
the concept of 'all expressions return values', which I will  
guarantee that not all of them have.  When you're learning  
programming, that is still something that you have to *think* about.

Again, a practical example: the 'expressions return values' thing is  
pretty simple at first glance, a = 3 + 2 seems pretty easy to  
understand.  For some reason, though, the majority seem to consider  
variable assignment as some sort of a special case.  Of course, it's  
what lets you do things like "a = b = c = 1" and "if (a = a + 5)".   
The latter example never fails to draw slightly confused looks from  
people the first time they see it.

So, it *is* extra work, but it's valuable extra work because it helps  
students internalise that particular concept.  It makes it absolutely  
explicit to the student that methods return values.  If they're  
reading code, it gives them an anchor for their analysis and  
understanding.

Again, though, 'return' is just an example of a more general idea:  
Ruby syntax is concise, which is great for when I'm using it.  But  
that same property can make it a headache (literally) for beginners -  
there's just more that they have to actively think about and remember  
in order to grasp what's going on.

> Students will learn the Ruby you teach them.  Don't throw a lot of  
> syntax at them before explaining basic principles.    Otherwise the  
> syntax just seems arbitrary (or more arbitrary than it is), and the  
> principles will not make much sense after they've been blindly  
> coding with random expressions in search of code that simply runs  
> without errors.

Striking the balance between introducing concepts and introducing  
syntax is difficult, since they have a somewhat circular relation:  
this syntax expresses this concept, which is implemented using this  
syntax.

So, while "don't throw a lot of syntax at them before explaining  
basic principles" is correct advice, it's not very useful advice,  
since all it does is rephrase the problem.  In fact, it's about the  
biggest problem in teaching programming, and it has no correct  
answer; some students will do better if you just give them a link to  
the language docs and turn them loose, some do better with formal  
definitions of the syntax, some need a simple, plain-english  
explanation, and some always need some hand-holding.

A more subtle point is that the instructor isn't teaching you Ruby, s/ 
he's teaching you how to program.  Ruby does have a lot going for it  
in this regard: first-order functions, object-orientation, and so  
on.  But my point is that Ruby's concise nature is an argument  
against using it to teach general principles, because the syntax  
takes many of those general principles as already understood, and  
tucks them out of the way.

matthew smillie