Tapestry Training -- From The Source

Let me help you get your team up to speed in Tapestry ... fast. Visit howardlewisship.com for details on training, mentoring and support!

Friday, August 31, 2007

The Blindness of James Gosling: Java as A First Language

I think Java is an excellent all-around-language. It is truly ubiqitous, well specified, highly performant and well accepted by the industry.

But there's a big difference between those credentials, and the credentials of the first language a developer learns. Regardless, James Gosling feels obligated to recommend Java as the first language anyone learns.

Java as a first language? Please! Yes, Java is simpler than C++, C, Lisp, assembler and all the languages that seasoned veterans, such as James Gosling, are familiar with. But the fact that Java shields you from pointers, malloc() and zero-terminated strings does not make it a good first language!

Java is extremely monolithic: in order to understand how to run a simple Hello World program, you'll be exposed to:

  • Classes
  • Java packages
  • Static vs. instance methods
  • Source files vs. compiled classes
  • Editing vs. Execution
  • Using a compiler or an IDE
  • Method return types and method parameter types
  • The magic (for newbies) that is "System.out.println()"

... in fact, this list is far from exhaustive. A lot of that has fallen off our collective radar ... we're blind to it from seeing it so much over the last ten years or more.

What's important to understand is that people new to programming don't really have a way of understanding the difference between a document and a program, between source code and an application. Certainly the web (with HTML and JavaScript all mixed together) hasn't helped people understand the division intuitively. It's very hard for any of us to think like someone new to our entire world.

I'm rarely in a position to teach people how to program, but when I think about it, only two languages make sense to me: Ruby and Inform.

Ruby, because it is interactive yet fully object oriented. You can start with an interactive puts "Hello World" and quickly work up from there. You get to interact with the Ruby world as objects before you have to define your own objects. There's a nice clean slope from one-off quickies to eventual discipline as a true developer, without any huge leaps in the middle.

Inform, used to create interactive text adventures, is also intriguing. It's specifically designed for non-programmers, and has a laser-focused UI. It is interactive: you type a little bit about your world and hit Run to play it. Again, you experience an object oriented environment in an incredibly intuitive way long before you have to define to yourself, or to the language, what an object is.

Inform is truly some amazing software, given that advanced Inform games will make use of not just object oriented features, but also aspect oriented. Here's a little example I brewed up about a room built on top of a powerful magnet:

"Magnet Room" by Howard Lewis Ship

A thing is either magnetic or non-ferrous. Things are normally non-ferrous.

The Test Lab is a room. "A great circular space with lit by a vast array of ugly
flourescent lights.  In the center of the room is a white circular pedestal with a
great red switch on top. Your feet echo against the cold steel floor."

The red switch is a device in the test lab. It is scenery.

The double-sided coin is in the test lab. "Your lucky double sided half dollar rests
on the floor." The coin is magnetic.  Understand "dollar" as the coin.

A rabbits foot is in the test lab. "Your moth-eaten rabbits foot lies nearby."

Magnet Active is a scene.

Magnet Active begins when the red switch is switched on. 

When Magnet Active begins: say "A menacing hum begins to surge from beneath the
floor."

Magnet Active ends when the red switch is switched off.

When Magnet Active ends: say "The menacing hum fades off to nothing."

Instead of taking a thing that is magnetic during Magnet Active: say "[The noun]
is firmly fixed to the floor."

That's not a description of my program; that's the actual program. It's literate; meaning equally readable, more or less, by the compiler and the author. It's still a formal language with all that wonderful lexical and BNF stuff, it's just a bit richer than a typical programming language.

What I like about Inform is that you get a complete little game from this:

Magnet Room
An Interactive Fiction by Howard Lewis Ship
Release 1 / Serial number 070831 / Inform 7 build 4W37 (I6/v6.31 lib 6/11N) SD

Test Lab
A great circular space with lit by a vast array of ugly flourescent lights.  In the
center of the room is a white circular pedestal with a great red switch on top. Your
feet echo against the cold steel floor.

Your lucky double sided half dollar rests on the floor.

Your moth-eaten rabbits foot lies nearby.

>take dollar
Taken.

>drop it
Dropped.

>turn switch on
You switch the red switch on.

A menacing hum begins to surge from beneath the floor.

>take dollar
The double-sided coin is firmly fixed to the floor.

>take foot
Taken.

>turn switch off
You switch the red switch off.

The menacing hum fades off to nothing.

>take dollar
Taken.

>

The way rules work, especially in the context of scenes, is very much an aspect oriented approach. It is a pattern-based way to apply similar rules to a variety of objects. I've seen this kind of thing with aspect oriented programming in Java, but also with pattern based languages such as Haskell and Erlang.

The point is, using Ruby or Inform, you can learn the practices of a programmer ... dividing a complex problem into small manageable pieces, without being faced with a huge amount of a-priori knowledge and experience in order to get started. Both Ruby and Inform are self-contained environments designed for quick and easy adoption. That's something Java missed the boat on long, long ago!

28 comments:

Anthony said...

I wonder if Inform could be used to write user stories in an agile development environment?

Anjan said...

hi there,

I've seen Bjarne Stroustrup (don't have a link right now) doing the same.

I think if we create something big, it is NOT too difficult to convince ourselves that it is very easy.

I'm sure a lot of College students these days get introduced to Java first, atleast in practice.

Ruby does LOOK promising like a beginners' first language.

If ruby is the 1st, what would be the 2nd language and why ?

BR,
~A

Howard said...

I've wondered if the technology behind Inform could be adapted to fill the role of the meta-programming that is today done with XML. Stuff like workflows, business process management, etc.

tug said...

Kenneth Barclay and John Savage at Napier University, Edinburgh have been teaching Groovy as a first language to students for same time now. Their paper "Groovy in the Curriculum" is available here http://www.dcs.napier.ac.uk/~kab/groovy/groovy.html (Word format I'm afraid).

They report a very good response from their students with the slight drawback that the students don't want to "move on" to Java:)

zooplah said...

I don't think Java's good for a first language just because OOP is a pretty complicated concept. I think you should learn what functions, variables, records/structures separately before learning OOP. OOP pretty much requires you to learn all those basic concepts at once. Even writing a simple "Hello World" program in Java requires way too much simultaneous knowledge of programming concepts (classes, data hiding, functions, etc.).

Personally, I'd recommend Pascal. Pascal allows you to take it a step at a time; Pascal has pointers; and any half-way decent compiler has OOP.

Bill Holloway said...

I think smalltalk's not a bad first language. Open a Transcript and execute

Transcript show: 'Hello, world'

Easily understood and it also introduces classes, objects, message sends, literals, code, and execution, at least. A rich one-line platform for teaching. I was showing a non-programmer friend HTML one day and she's smart and got it. Then I showed a line of smalltalk in Seaside. html paragraph: 'Hello, Tanya.'. She looked at me and said "Oh! Here you just *say* it!"

Howard said...

I think its definitely a case of whatever you're familiar with seems like a good candidate. I'd always say to learn Tapestry as a way to learn web applications in general and I too have anecdotal evidence of new developers (new to web development, new to Java) taking to Tapestry. It's a slippery slope.

I like Inform because it immediately creates an interactive environment. You type, it responds. It's doing something almost magical with syntax, semantics, and a very clever built in library to create something more than the sum of its parts.

Francois said...

I begin to program with OCaml, and you know that ? It was great. the fact that I begin with a functional programming language give me the opportunity to well understand algorithmic, types, recursion, higher functions, closure, lazy evaluation, etc.

OK, the "programs" were really maths oriented, but it gives me the bases.
Unfortunately, the second programming language, used to actually do programs and not just algorithmic and toy programs was C, and I think that Ruby would have been a really better candidate. Not that C should not be taught, in my point of view it is mandatory to understand how things work. But latter, when the base of programming are mastered.

So, my list of choices for teaching would be :
- a ml functional language to learn algorithmic (recursion, evaluation, complexity, types, higher order functions, etc), say Haskell ;
- a really simple to come to grips with language to show that programming actually does something and that has a clean OO design, say Ruby ;
- and then C and ASM to show how things work under the hood.

Ho, Java never appears in this list :)

José said...

Well, I've been teaching java for 6 years now, taking students from the basis of the language to advanced topics in XML, EJB, JDO and Struts.
6 years ago most of my students were coming from C/C++. Now, about half of them never wrote any code in any language, some of them wrote C++, and a about quarter wrote C (funny to see how C++ is declining faster than C...).
After a full 20 hours course, it's hard to tell the one that never programmed before from the others.

So to make a short statement : yes you can learn Java/Eclipse to people that never wrote code before, well it ... just works...

bruce said...

Check out MOO. It's a very cool prototype-based language used to write multi-user text adventures. Some guy at Xerox Parc came up with it about fifteen years ago or so. It's more powerful than Inform, easy enough to teach programming concepts, and more fun and interesting in a classroom environment since users can all login to the same server and interact with each other's objects.

http://en.wikipedia.org/wiki/MOO

http://en.wikipedia.org/wiki/MOO_programming_language

fgantt said...

How about Scala? A language that blends functional and OO. Also static typing.

Howard said...

Scala is a language I might use, but with its complex syntax and vertical cliff of concepts (lambda calculus, anyone?) it's not a language I'd teach my wife or my friend's kids.

MOO I'm not familiar with, I'm sure it's nice and probably closer to the point: simple, graduated in complexity, but gears towards early rewards.

Howard said...

Hm. Moo looks like Inform 6. Inform 6 is to Inform 7 as assembly code is to Java (or something).

fgantt said...

Admittedly, some of Scala's syntax can be a little daunting. But the nice thing is you don't have to use those features. Using the same language, you can create simple top to bottom scripts, OO style programs, or functional style programs, or a blend. The singleton object is what most of our first programs really are without the need to explicitly create an object in main. As a first language, I think this is a great concept. You don't have to invest totally into OO or functional and then switch to another language to see the other style.

There are benefits to both static and dynamic typing depending on the situation. I think that static typing might be better suited for someone learning their first language as any failure will be found sooner rather than later.

But perhaps the biggest advantage for the new developer is that ultimately they have the entire Java platform behind what they are learning.

yaxu said...

Java is an excellent first language, if you hide all the difficult and annoying parts of it that you list.

Luckily, some people have done just that, and done it extremely well. Take a look at http://processing.org/

Lionel said...

I would propose Python instead of Ruby.
it has the same advantage : command-line interpreter, simple synthax and the opportunity to manipulate object without having to design one.

But Python has a big edge over ruby in the library department. This offer a lot of space for learning (for example : openGL, pygame).

Ruby could be the second one : it has slighly more complex/powerful constructs.

J.V. Toups said...

Java is simpler than Lisp only in the same way that a madman is simpler than a sane one because he has idee fixe. Java's insane reliance on the Object as the model of every computation may appear simple but it leads to a tremendous amount of overhead for the simplest tasks - tasks that people learning a language will likely be tackling.

Andrew said...

Wow I can hardly believe you said that java is simpler than lisp. Please tell me you are not that ignorant.

Bob said...

Python would be better. Ruby has too much magic going on and wouldn't be much better than Java. If Java was the main focus of the CS course then maybe Groovy would be a good choice. MIT just started with Python as the first language and I think it is an excellent choice (and I don't use Python, I use the other magical language Perl).

Doug Holton said...

The answer's not so simple. And there is actual research & data on this. Do a search for "computer science education" for example. There are research conferences and journals with a lot of previous thought on this.

I assume you mean best first programming language FOR ADULTS (and high schoolers perhaps). But then the question is, why would an adult want to learn a programming language. One reason is to get a job or get a degree. In that case java is not a bad choice, and in fact, java and vb.net are the only choice if you are in high school and doing the computer science AP exam.

The other reason is to be able to develop or customize your own desktop or web applications. For web applications, yes, ruby on rails is currently one of the easiest and most powerful web frameworks (see also grails & groovy, or castle for .net and mono).

For desktop applications or interactive applets, there are 2 main choices of platforms: flash and java. Flash is easier to learn than java, but costs hundreds of dollars. Not really worth it unless, again, you are looking to do it professionally for money also.

A best first language for children is something like scratch from MIT or perhaps squeak etoys.

Steven Hansen said...

I'm having a hard time understanding how Java is simpler than LISP. To me, LISP is one of the easiest languages to learn--way easier than ruby--because it has extremely simple syntax. If you've programed in another language, learning LISP can be a little tricky because you have to learn to think differently, but for a beginner, I'd say LISP is the best language to start with. Another language I'd recommend starting with is LOGO.

Yoni Samlan said...

I think most of the arguments for python over Ruby for beginners are silly - the "magic" issue is overstated for the core language (Rails is really an issue, not Ruby itself) and no one should be learning PyGame/OpenGL/windowing until they have fundamentals down pat anyways. IMO, though, uniform coding style and indentation over braces are the big thing Python brings to new programming learners.

I think a lot of beginnning programmers run into issues with unbalanced or mismatched curly braces. At the same time, a lot of beginning programmers have terrible indentation and code formatting, and make their own lives more difficult by writing code that looks different than it runs (especially when they're not using a good editor). Python fixes both problems at the outset: your code "shape" *is* its semantic structure, no {} needed. Not only do you not form bad habits for code indentation, you *have* to write properly-indented code, and at the same time you're saved from nested-brace confusion. Usually indentation and code format is left up to teachers and TAs to mark off for style points on assignments -- with Python it's one less thing newbies can screw up, and one less thing graders need to look for.

Think about a simple if-then: In python, "if x is true do y" is just not done as anything other than

if x:
   y()

in java, that can be written with braces, indented correctly or totally incorrectly, or with no braces. But only if the then is only one line. And all those forms are pretty much "acceptable" and "ok Java" (even if everyone does hate the one-line no-brace then statement, it's still commonly used in a lot of production code I see). And that's confusing to students reading their own code, other students reading someone else's code (eg group projects), and to graders and teachers.

Jonathan Ellis said...

+1 to the Python comments. Don't be blinded by the current Ruby trendiness; regularity and consistency are important to beginners. (As they are to maintaining your own code or someone else's, but that's another subject. :)

(I taught C# to several groups of freshmen, so I have some practical experience in the problems that involved.)

P.S. I'm really baffled how you conclude that Java is simpler than Lisp. Can you explain?

rfun said...

The primary argument for Ruby is that it's just completely fun.

There's all kinds of entertainment to be had:

infinity = 1 / 0.0
range = -infinity..infinity
range.include? 1 #=> true
range.include? -100000 #=> true
range.include? 10**232 #=> true

Great fun. Also, the python libraries are great, no doubt. But Ruby is not shabby by any stretch! Not to mention the ability to (re)define methods on any object (standard library or not!) can really give students appreciation of what goes into libraries. Ie. rewrite Array::pop or String::reverse in Ruby.

Not only that but it encourages more heavy use of advanced language features as you get into it. Like regular expresions (PAINFUL in python), lambda (aka 'proc's), the 'block' in general.

Lastly. I find the introspection in Ruby much more useful than in python. Mainly this is because of the typically many more methods defined for objects in ruby but also because of python's silly __function__ syntax. (for example, compare 'Array' in ruby with 'list' in python.

Ruby:
Array.methods #=> massive list that can ALSO be introspected, or redefined or whatever

Python:
dir( list ) # short list of awkwardly named functions that really isn't very interesting (from a students perspective anyway).

Dont get me wrong, of course, I love python, I learned it before I learned Ruby. I would have just preferred it the other way around knowing what I know now that's all.

radix42 said...

I've taught adults with zero programming background (English majors, even!) to program in Forth. You just need to give them a copy of Leo Brodie's Starting Forth. They don't see it as low-level, they have no preconceived notion of what a programming language should look like.

Those with a totally "zen mind" regarding coding seem to find Forth's "every programing is an evolving domain specific language" philosophy quite natural. Note that the only time I've used Forth in years is to teach a newbie who wanted to know how to program just so they knew how the darned machines worked.

And then if they actually need to program something in the real world, higher level languages are very easy to teach them.

Kenn said...

I have just begun to teach Java in an AP Computer Science class. Since the AP Board requires Java, that is what I teach (even though the over all idea is to teach programming concepts). I ahve taught HTML, Visual Basic and C++ in the past. With my limited experience, I do not see a difference in languages for a beginner - especially a high school student.

Jesse Kuhnert said...

@kenn

The difference in languages is gigantic. Start someone off on some ruby / lisp / etc type languages and peoples brains will be wired correctly right from the beginning.

The OO languages seem to always put up too many barriers and are largely to blame for the fleets of non engineer "java programmers" that don't understand enough about the art of programming to break free from their shackles and conceive of a world not created in java.

nebi said...

How to design programs - http://www.htdp.org/ - and the Dr. Scheme development environment is a great way to introduce programming concepts (or refresh your understanding).