Wednesday, March 3, 2010

Adventures in junior programming, episode 1

In my last post I mentioned that I had been writing an instructional applet for my son to learn some math concepts. I received this half-joking reply:

If you truly loved your son, you would have made HIM program that applet! He's seven - that's old enough for Java, at the very least.

I actually think seven is a little young to get started, but as I thought about it, I decided, heck, why not? I picked up some extra money in college tutoring a thirteen year old in C++, and later taught classes for half a year in Fort Worth. It's been over ten years since I taught any actual classes, but is it all that unreasonable to try and give the essential concepts of Java across to a seven year old?

I was already six when my dad bought our first computer, and it wasn't for a few more years that I started reading and understanding the BASIC programs that were in vogue back then. But Ben, like many kids of his generation, was introduced to computers at an early age, and has been comfortable using them for most of his life. He's already seen what the inside of a computer looks like when I swapped out components, and I've even gone over some explanations of binary numbers with him, including the "counting on your fingers" trick.

I have done two lessons so far, first on paper and last night on a laptop. Since I've done only sporadic posts on this blog recently, I think it's not a bad idea to chronicle some of this effort. One thing I discovered while teaching classes is that there is no better way for you to solidify fundamental concepts in your own mind than to try to explain it to somebody else. There is nothing like having to break down assumptions that are second nature to you but completely foreign to another person.

So the first thing I've discovered is: Java is kind of hard.

Programmers traditionally write "Hello world" as their first program, so let's take a look at some ways that this is handled in various languages.

BASIC:

10 print "Hello world"

Nobody learns BASIC anymore, but it was a standard on those old PC 8086's I had as a kid. In fact, if you booted up the computer without inserting a floppy disk, the computer (which lacked a hard drive, and hence lacked a useful operating system in memory) would just load up a BASIC compiler environment directly from the BIOS. It was designed to be a beginner language.

Next let's look at Perl, which is known as a scripting language that is powerful at handling string manipulation:

print "Hello world";

Even simpler, superficially, because Perl is a procedural language which does not use line numbers. Once you start getting into program flow, BASIC starts looking simpler through heavy use of the "goto" statement to control program flow. But as everyone should know, "goto" sucks.

Next we'll look at C, which is what I initially taught in the semester before teaching my classes C++.

#include <stdio.h>

main() {
printf("Hello world");
}

Slightly trickier. In C, nothing runs unless it is directly or indirectly invoked by a "main" function. Thus, unlike the other two languages, in order to become proficient enough to run the most trivial of programs, you have to have some trivial understanding of what a function is about.

There's also the rather cryptic line "#include <stdio.h>", which contains additional wacky symbols that have to be either explained or hand-waved away. When I introduced students to this language, I initially just gave them a complete "hello world" program and said "Focus on what's inside the braces, you'll understand what they mean later." Students love to complain about this sort of thing, as they tend to view unexplained stuff as unnecessary and annoying.

Now here's the java program.

class Hello {
public static void main(String[] args) {
System.out.println("Hello world");
}
}

Seriously now, those are a LOT of details to expect a pure novice to absorb, even if he were older. Let me count the unfamiliar concepts:

  1. "class Hello": Right from the get-go, all Java programs enforce object-oriented structure. Objects and classes are a beast to understand -- I first heard the concept as a senior in high school, failed to self-teach it, and then didn't really get it until my first college course in C++. Now let's explain the difference between a class and an instantiating object to kid who's going on eight.
  2. "main": Just like in the C example, you're not going to get anywhere until you understand methods (aka functions inside a class). I had to make an analogy to nouns and verbs in sentences, since Ben has played Mad Libs before. Even so, it's all pretty abstract, and the word "main" does not suggest an action word at all.
  3. "(...)": Now that we know that "main" is a verb, it's time to learn that all verbs in Java must be followed up with parentheses, which may or may not contain some arguments.
  4. "void": Some methods return an object type and others don't... you know what? I'll tell you later.
  5. "public": So here we encounter the notion of public and private methods, which is intended to separate interface from implementation. Simple, right?
  6. "static": So yeah, this function can be called generically through the class itself, and does not need to be applied to a particular instance of the class. And by the way, all methods called directly from "main" must also be called "static," and the only way to simplify your calls is if you declare a second class and make an instance object.
  7. "String ... args": It's an object declaration. A string is a sequence of characters. Your program won't recognize the "main" method unless that String argument is in there, even though we have no intention of reading the command line arguments yet...
  8. "[]": ...but this string is not just any old single string, it's actually an array of strings, which means there can be any number of them sequentially, see?
  9. "System.out.println": These are not even a proper part of the language definition. They are objects that are accessed by loading in the standard Java libraries, and they actually have a bunch of additional code written to accomplish their task somehow, but you will never see that code. You just have to accept that it will work as a "black box" that does what you expect. And then there's the idea that "System" contains an object called "out" which has a method called "println", where even the last word is not as easy to understand as plain old "print".
  10. All the syntax: This is probably second nature to every programmer by now, but just try to think about how you would explain and reinforce the idea of all the funny characters and when to use them. Quotation marks must signify string literals. Parentheses are required for both declaring and calling methods. Semicolons must end all statements, but NOT the method declaration (I don't know for sure if he ever saw a semicolon before). And, again, what the dots mean in between "System", "out", and "println".

That's quite a lot to bite off just to write two words. And by the way, when I try to get into inputting text, the proper format will be something like this:

String name = "";
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(input);
try {
name = reader.readLine();
} catch (Exception e){};

Compare that to

INPUT "Input name: ", name$

in BASIC, and

$name = <>;

in Perl.

Nevertheless, we heroically slogged through that stuff, discussing some parts in detail and skipping over other parts. Then we finally got to String variables.

No input yet, and no kind of string manipulation or concatenate. Just
String name = "Ben";

followed by

System.out.print("Hello ");
System.out.print(name);

Had a tough time getting him to see that the second print statement would print "Ben" rather than "name," and why.

As far as I can tell, I still have his attention and he wants to keep at it. He would like to write a graphical game, but I told him he has a lot to learn about text-only programs first before we can start to cover that. I know a lot of graphics, but much of it requires knowledge of not only Cartesian coordinates but also trigonometry. Believe me, I'm not touching trig.

A couple of open questions for readers:

  1. Was it a mistake to start in Java?
  2. If not, why not?
  3. If you were being introduced to programming for the very first time, which language would you want to be taught first?
  4. Crazy thought: Ben has a bunch of favorite sites stuffed with Flash games. He even said that he wished he could make one someday, which prompted me to say that it's too advanced for now. I have never learned Flash myself. Is it easy? Is it free? Would it be better or worse than Java as a "first time" language?

18 comments:

  1. I would say yes, it was a mistake to start in Java. I struggled for sometime with the initial Java syntax (and this coming from a C background) just because of all the overheard compared to the relative simplicity of C (... well, aside from the funky things you can do with pointers).

    My suggestion? Python. It seems well suited for a beginner with it's syntax, type system, and such. You can focus on the concepts of programming (input, output, flow control) without worrying about the ugly details.

    There's also Microsoft Small BASIC, which is a .NET language targeted specifically at beginners.

    ReplyDelete
  2. Pascal. It was originally designed as a teaching language. There's a free implementation for every significant platform at http://www.freepascal.org/

    ReplyDelete
  3. I second the recommendation for Python. Purely procedural samples are much cleaner (no need to create classes) and when you get to OOP Python has that too.

    ReplyDelete
  4. Recently at my old university they started using Scratch in the 100-level interactive computer science courses. I haven't actually used it much, but it looks pretty neat. It is very visual, introduces basic computer science ideas, and allows easy reuse of Scratch objects (probably the most important aspect of computer science) which can be recombined in different ways for new projects. It was designed specifically for teaching children programming concepts, it is completely free for Windows, Linux, and Mac, and I believe the source code is even available if you want to modify it.

    I would definitely recommend giving it a try.

    ReplyDelete
  5. I would also recommend Scratch: http://scratch.mit.edu/

    I'm currently using Scratch to teach a college level Intro to Programming Logic course. The Scratch website is like a youtube for programs. Learner can explore the works of others and are encouraged to "remix" each-other's code.

    After Scratch we move on to Processing, which is Java simplified and enhanced with easy to use graphics libraries.

    http://processing.org

    I put together a Processing overview for my fellow instructors. In it I come to some of the same conclusions as you concerning Java. You can read my overview here:

    http://stungeye.com/school/processing/

    Feel free to drop me an email if you have any questions.

    stungeye
    at
    gmail

    ReplyDelete
  6. John Zelle wrote a paper arguing that Python is an ideal first language.

    It's a Very High Level Language. Simple things are simple -- "Hello world" is the one-liner it should be, unencumbered by mysterious boilerplates. Dynamically typed so you don't need variable declarations all over the place. Type checked and array bounds checked, so it won't run amok. So syntax light, it uses indentation instead of curly braces. Sets and perl-like hashes are easily expressed built-in types. You can use it in both functional and object-oriented paradigms, so you can explore the world of objects and methods when you're ready; it doesn't have to come up on day one.

    And you can run it like a command shell, entering statements and seeing what they do immediately, like the BASIC interpreters when you were starting out.

    All in all, a good language to just dive in and use.


    Flash's ActionScript is based on JavaScript, and no, only the player is free. I wouldn't recommend it as a first time computer language. However, you don't need programming ability to make simple animations in Flash. You can just click to different parts of a timeline and say this object is here (or this color, or this shape...) at this frame, and there (or that color, or that shape...) at that frame... and have Flash handle the transition in between. All the buttons and menus could be a little overwhelming to a computer neophyte, though.

    ReplyDelete
  7. Yes. Java is a bit heavy for a beginner. For a programming language, I'd suggest Python, like others here have.

    If you want to teach just the basic concepts, a program like Alice would teach that: http://www.alice.org

    Still, for a full language, go with python.

    ReplyDelete
  8. I taught myself C++ in 9th grade by Google searching, and I am so glad I did seeing how others have such a hard time going from super high level languages down to C++. I basically learned the C concepts and put off the object oriented parts of C++ off till later. If he learns C/C++, future languages like Java will be a sinch.

    Also, if he learns C, he will gain an understanding of how an underlying program works. Java doesn't teach you underlying architecture, like c-strings, pointers, etc. Java doesn't use any of that, so the concepts he will learn in Java will be arbitrary high level blobs, as what programs are to non-programmers or high level programmers. Better to illuminate that magic black box.

    ReplyDelete
  9. I taught myself C++ in 9th grade by Google searching

    Yoiks! Preparing to be embarrassed...

    I basically learned the C concepts and put off the object oriented parts of C++ off till later.

    ...Embarrassment averted. :) It's the OO stuff that is the hard part.

    Better to illuminate that magic black box.

    I sort of agree, I think memory issues and how the computer works as a Turing machine need to be illuminated, and I'm a little bit concerned about current students not starting at that step. On the other hand, I bet older developers are concerned about students not starting with assembly language (which I did, but only for one class), and even older developers think kids should input machine code with punch cards.

    While agreeing that these are all important concepts to grasp eventually, I'm not totally convinced that your choice of first programming language necessarily has to be the delivery system. Pointers still mystified me for a long time even AFTER I had learned to use them correctly in my programs.

    ReplyDelete
  10. Well, I got five votes for Python and two for Scratch. I've decided to accept majority rule and learn some Python. Maybe I'll try out Scratch later.

    Python is, indeed, pretty easy. I'm up to sorting stuff now, gonna try writing a quicksort next.

    ReplyDelete
  11. David Brin (whose son is also named Ben) wrote an article lamenting the lost of BASIC. http://www.salon.com/tech/feature/2006/09/14/basic/

    ReplyDelete
  12. Ya know, I've seen that article before... and it doesn't really make a lot of sense. Brin specifically rejects using a language like Python because it's somehow not as pure as BASIC. BASIC is *not* a low level language, and the major differences I can see between using BASIC and Python are that Python doesn't use line numbers or gotos; and Python HAS certain (optional) tools available like OO that basic doesn't have.

    Like I said, really old school programmers probably lamented the loss of kids' ability to learn assembly language when BASIC became common.

    ReplyDelete
  13. I see you've already capitulated, but I also wanted to throw my recommendation for Python into the ring. I think exposing someone that young to Java could be considered a form of child abuse.

    Shawn

    ReplyDelete
  14. I started out with JavaScript of all things, which has its positives and negatives (moreso negatives). The first formal class I had was in high school using Holt Software's Turing, which I think is excellent and would have to be my top choice for starting out. It has easy to use graphics libraries, compiles and outputs in a really simple way. It has auto-indenting and stresses key points in syntax.

    In terms of Java, I like the syntax for learning, but for my own learning particularly early on, it was driven by accomplishment. Java really doesn't lend itself to immediate gratification.

    Maybe JSP, but that's a little ugly, too. For a first language that's actually a production language, I'd lean towards C#, which I find Java-like without the stuff I hate about Java.

    Oh, and for clarity, I'm currently an undergraduate University student in computer science, and have a college diploma in web development.

    ReplyDelete
  15. Add another +1 for Python. Why encumber your kid's brain with all the syntactical baggage that Java demands? Imagine if you were teaching him how to draw, and you first insisted that he measure and cut the paper into a precise 12cm x 19cm rectangle, lay it out in 1cm grid squares, fold it in half, dog-ear one corner, and sharpen three pencils with 200-grit aluminum oxide sandpaper before starting to draw anything. I wouldn't recommend Java to anyone, much less to a 7-year old :-)

    ReplyDelete
  16. I'd recommend Actionscript (flash) for the graphical stuff over Java simply because the integration between the API and the actual graphical objects is so close.

    The syntax is based on Java, C# and Javascript so anyone who knows any of those languages can figure out what's going on.

    But the most useful thing is that you can treat it as a scripting language on the timeline and work your way up to OO programming concepts later.

    e.g. Timeline scripting:

    trace("Hello, World!");


    // e.g. Classes
    // Timeline code:
    var main:Main = new Main();

    // Class definition in Main.as:
    package
    {
    public class Main
    {
    public function Main()
    {
    trace("Hello, World!");
    }
    }
    }


    The only downside is having to buy Flash to have that super-tight graphics/code integration. The Flex SDK and FlashDevelop give you a full, free development environment but without the ability to draw your assets.

    I'd recommend it over Python because it uses the standard C-style syntax (which, despite possible flak, really is the standard for code syntax at the moment) and has the tight graphical integration - it's easier to engage children if they can see graphical things changing because of their code and not just outputting text.

    (Disclosure: I'm a Flash/Flex developer :)

    ReplyDelete
  17. Gaah! Java is a terrible idea! That being said, I'm from the old-school as well, and learned BASIC, first on my Atari 600XT (age 9), then GWBASIC on an old IBM AT with a lovely amber monochrome monitor.

    Python seems to be very much the flavour of the month for beginning coding, though I still think good ol' Pascal is a great place to start. Firstly because I believe 'real-world' languages should be saved for later in life so you can learn and use them without carrying across all of the bad-habits of youth, and second because knowing an old-school language has a certain geek-chic attached to it... well, at least I like to think so.

    If you really want to freak out the kids, teach them PROLOG!

    :-)

    ReplyDelete
  18. Only eight instructions: Brainfuck :P

    Personally, I think the Web is a good domain to focus on. Unfortunately, this requires first learning some HTML and CSS before you really get started with a scripting language. However, getting a local web server set up isn't a big deal.

    Once you *do* progress to server-side scripting, it's a lot easier to quickly get started with interesting stuff, IMO.

    Obviously, YMMV. This is how I really got going in computer science. My very first experience was with QBASIC, on my dad's old 8086 as a kid. However, computers were mainly his toys, and I didn't often get the chance to freely tinker.

    ReplyDelete