The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Abstract vs Concrete Approaches to Learning

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Rick DeNatale

Posts: 269
Nickname: rdenatale
Registered: Sep, 2007

Rick DeNatale is a consultant with over three decades of experience in OO technology.
Abstract vs Concrete Approaches to Learning Posted: Jan 16, 2011 12:59 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Rick DeNatale.
Original Post: Abstract vs Concrete Approaches to Learning
Feed Title: Talk Like A Duck
Feed URL: http://talklikeaduck.denhaven2.com/articles.atom
Feed Description: Musings on Ruby, Rails, and other topics by an experienced object technologist.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Rick DeNatale
Latest Posts From Talk Like A Duck

Advertisement

Once again discussion on the internets have prompted me to write an article.

Last weekend, someone posed a question to the ruby language forum about whether Rails was suitable for a Ruby beginner.

Shortly thereafter Xavier Noria opined:

"I have the feeling that Rails is not for beginners. It abstracts web programming in a way that I think makes more sense for someone that already knows web programming. In that situation you get a Ferrari to run. It is just an opinion, it could be the case that you are presented first with the framework and work fine... I've seen that with Java people. But I doubt you'll understand what you are doing."

"I think that learning web programming passes through HTTP and bare CGI, where you're naked, you value as gold even being able to have the query string parsed for you. There you understand what's all about, and can build from that. Then the abstractions make sense and act as shortcuts."

"Other than that, I would not say Rails is complicated. Rails is rather big, you need to invest time to master it."

While I understand Xavier's stance, and I've heard similar things from many people over the years about needing to master the "low-level" basics first. I'd like to offer a second opinion.

Levels of Abstraction

To be a good programmer, or as I prefer software craftsman, one needs to be able to work at a range of levels of abstraction. To get to this level requires a formidable amount of learning. It's not a question of whether one needs to learn low-level abstractions, it's a question of when.

Teaching Programming "Bottom up"

As someone who has been learning programming for more than 40 years, I've seen a variety of pedagogical approaches to teaching people how to program.

In my early days, there were lots of books about programming specific computers using one or a small set of languages for that computer. For example, the first computer I ever worked with was an IBM 1620, and one of the oldest books in my library is "Programmng the IBM 1620, 2nd ed." by Clarence B. Germain. That book starts with the following chapters:

  1. Computing Fundamentals - covering things like flow charts, magnetic core memory, punch cards and paper tapes. By the way the contents of the dedication page is in the form of picture of the holes in a paper tape, which when you decode them read "TO THE COMPUTER PROGRAMMERS OF TOMORROW"
  2. 1620 Instructions - which covers the basic machine level instruction set at the machine code level.
  3. Operation of the 1620 - which covers how to read the lights and flip the switches on the machine console, and work the IO devices like the console typewriter, and the card reader punch.
  4. Programming - Back to flowcharts, and then a simple program in machine code.
  5. Introduction to FORTRAN
  6. Additional FORTRAN statements
  7. The Symbolic Programming System - which is what the Assembler language and tools for the 1620 was called.

Note that the approach is to start with the bare metal, then raise the abstraction level up to FORTRAN and then lower it to symbolic assembly language.

Later, the trend in programming education was to start with a language roughly at the level of abstraction of FORTRAN, maybe Algol, or BASIC, or PL/I, or C. suitable for implementing operating sytems, something which had previously required assembly language.

At the assembly language level of abstraction we have to deal with things like register loading and storing, arithmetic operations, perhaps memory to memory operations if the machine support them, conditional and unconditional branch instructions, and the peculiarities of how the particular machine does I/O, or at least the peculiarities of the low-level I/O subroutine library.

At the next level up, machine registers tend to be abstracted away, we think in terms of assignments to variables with the compiler abstracting the location of those variables (including when and whether they are held in a register or 'memory'), and the compiler turns algebraic expressions into sequences of machine instructions. The compiler also abstracts the notion of conditional and unconditional branches into IF and looping statements, and before the structured programming revolution, GOTO statements.

C is actually at an abstraction level which ranges from FORTRAN down to being a 'portable assembly language' its raison d'être was to be a portable language

Programmers who start this way build up a mass of low level knowledge and, if they are to achieve the ability to work at higher level of abstraction. must learn to suppress always thinking of the details when the details aren't really important.

In my case I was fortunate in that, beside my formal Computer Science courses, I had an enormous thirst to learn lots of languages from the very beginning, so I forged out my own to learn or at least dabble in a wide variety of languages, including SNOBOL4, LISP 1.5, APL, and a number of other, smaller languages, while my programming synapses were still forming.

The Car Analogy

Xavier brought up an analogy with cars in the form of a Ferrari, so I'd like to talk a bit about how the driver's view of the interface to a car has evolved.

When I learned to drive, there were still cars which had manual chokes. A manual choke consisted of a valve in the carburetor controlled by a lever or pull knob in the cabin, which when activated made the air-gas mixture richer. You would pull it before starting the engine, depending on the temperature, and gradually adjust it as the engine warmed up.

Besides manual chokes, earlier cars had things like manual spark advance levers. The driver would need to manually adjust the small details of the timing between the pistons and spark plug firing to keep the engine running smooth over a range of speeds and loads.

Of course this is all of the past, unless you are an antique car collector. Manual spark advance got replaced by automatic regulation via a combination of mechanical governors and vacuum hoses. Automatic chokes used the same kind of bi-metal strips found in thermostats to adjust the choke. These days, cars don't have carburetors anymore, and a computer implements much finer control over spark timing, and fuel mixture.

So although those matters are important to the engine, they're no longer important, or at least visible, to the driver, and the low-level knowledge needed by a mechanic when things go wrong is much different than it was back in the day.

Is there another way?

Must programming be taught from the bottom up? Clearly not. There are many proficient programmers who learned following the lead set by MIT whose introductory programming course was based on Ableson and Sussman's seminal text book "Structure and Interpretation of Computer Programs", or as it is known SICP.

SICP doesn't start with assignments and GOTOs. Instead it approaches programming from a more mathematical approach, based on Alonzo Church's Lambda Calculus, and using the Scheme programming language, a variant of LISP, which had been developed by Jay Sussman and Guy Steele at the M.I.T. A.I. lab. During the development of Scheme Sussman and Steel wrote a series of A.I. Lab memos collectively known as the lambda papers, which explored the implementation of Scheme and various programming features such as assignment, and control flow branching using lambda calculus. In many ways SICP is a distillation of the Lambda Papers into an introductory programming text.

For old codgers, like me, who started out 'the old way' encountering SICP can be a mind-distorting and altering experience, much like entering Dr Who's TARDIS for the first time and realizing it's bigger on the inside than it is on the outside.

In it's first chapter (70 out of 500 pages in the first edition) SICP covers building abstractions with procedures, and in so doing manages to broadly introduce a got bit of what I learned in a whole semester course on Numerical Analysis. The second chapter (around 100 pages in the first edition) talks about data abstraction, but still manages to wrap data in procedural abstractions. A few pages into chapter two is where we find the interesting idea of defining a LISP cons cell as the closure of a function call, which reminds me of the message dispatching and data encapsulation in languages like Smalltalk and Ruby, something I built my recent RubyConf talk on.

And it's not until the third chapter that SICP introduces the notion of assignment, which apparently gave "Uncle" Bob Martin his TARDIS moment.

In chapter four, SICP starts to introduce the notion of language into programming, talking about how scheme programs are represented and how that representation is evaluated.

It's only at the end of the text, in chapter 5. that SICP mentions hardware, and introduces the concept of a machine with registers and memory. The chapter finishes the book by describing the implementation of a compiler for Scheme, and a garbage collector.

Bottom up or Top down?

So what's better? Should one first learn the low level basics and then turn the collection into abstractions or go from abstraction to detail? It's clear that there are competent programmers who have learned both ways. The best of those who learned 'the old way' managed to gain a large experience base by 'playing' with a wide range of programming languages and approaches to programming, whether that was part of their formal education or not.

If I were to start over again, I think I would prefer to start the SICP way, but that's just me

Bringing it back to the initial question, personally I think learning how to write web applications starting with Rails, and learning Ruby, HTTP, REST etc. along the way is perfectly reasonable given such an attack fits your own mode of learning.

If you go that route, reading the code you are using when you need to drill down is a valuable way to learn the details. There's a lot to be learned about Ruby and the 'plumbing' level of web application implementation by reading the Rails code. This is particularly true with Rails 3, which represents a major refactoring and distillation of the experience gained as Rails has matured in the five years of its existence.


Original article writen by Rick DeNatale and published on Talk Like A Duck | direct link to this article | If you are reading this article elsewhere than Talk Like A Duck, it has been illegally reproduced and without proper authorization.

Read: Abstract vs Concrete Approaches to Learning

Topic: Abstract vs Concrete Approaches to Learning Previous Topic   Next Topic Topic: I Don't Know

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use