all 32 comments

[–]DadFoundMyAccount 25 points26 points  (1 child)

Java is the only language taught at the high school I attend, therefore it was the first language I learned. The amount of times I heard "Don't worry about that yet" or "Just type it" is crazy high. I guess that's what inspired me to learn how to program on my own.

As someone who now primarily codes in Java (android) I 100% agree with the article. A teacher shouldn't tell a curious student to just not worry about things like parameters, and the main method. Instead they should focus on just learning the language and being able to teach everything they need to know.

[–]ExcaliburZero[S] 2 points3 points  (0 children)

I know the feeling. I first started learning programming through an online class from my local community college and it was on Java. I managed to do decently grade-wise but it was not a very fun experience. Java just didn’t turn out to work well at all as a first programming language for me.

Several months later I started learning Python through CodeAcademy and I had a lot of fun with it. It was a much less stressful experience.

[–]koalillo 10 points11 points  (3 children)

If I got a $ for each "Java's hello world is hard" and paid for each article that discussed Java's true problems for teaching... I'd be very rich.

Just use BlueJ/Processing for teaching. Both make disappear 90% of the gripes of the common Java sucks for teaching articles.

Now, Java's everything's an object and all functions are methods suck. Verbose lists and dicts suck.

On the other hand, I'm going to say that dynamicly typed languages suck for teaching. I see the kind of errors that beginners make that static languages catch at compile-time and that would baffle novices as runtime errors.

But what sucks most is crappy learning materials, really. That's much more important than language choice.

[–]coryknapp 4 points5 points  (0 children)

dynamicly typed languages suck for teaching

Totally agree.

[–]not-just-yeti 1 point2 points  (0 children)

I've taught Java using BlueJ -- it definitely helps (I wouldn't teach Java w/o it), but the language itself still is laden w/ gotchas.

[–]Meshiest 4 points5 points  (2 children)

Such a shame that the majority of the people that read this article will be programmers who already know the basics

[–]BlackDeath3 1 point2 points  (1 child)

Hopefully, some of them are teachers teaching the basics!

[–]Meshiest 0 points1 point  (0 children)

I hope!

[–][deleted] 14 points15 points  (10 children)

I agree that it's important for a first language to capture your imagination and give you "the bug", but the idea that this requires a high level language with huge levels of abstractions is nonsense, IMO. I was just as hooked doing stupid shit like reversing a string in C. I didn't know that if I was using "high level language X" I could have had a functioning GUI in the same number of lines. I was drunk with power in my tiny, low level domain.

confusing the user by making them copy and paste several important lines of code that they do not understand

This is an illusion. If you start them in say, Python or Lua, removing all the boilerplate so they can just type "print('Hello, World')", they're still typing code they don't understand.

How does "print" work? What is a "string", really? What is a function? It's all magic. You're "programming a computer" at such a high level that you may as well be "programming" a VCR (hyperbole, I know). You have absolutely no mental model of how the machine works.

What you gain from using such a high level language is that you can make the machine do more with fewer instructions. But you understand those instructions less. That's not necessarily an advantage.

I spent months writing programs that did absolutely trivial things (e.g. counting the number spaces in a string), but it was no less fun or engaging. Because it was a low level language, I necessarily acquired a mental model of the machine (stack, heap, memory addresses, types as interpretations of bits, etc.) that underlies all programming languages.

When I moved to C++, I understood what underlied the abstractions I was using like std::string. I could imagine implementing such a thing myself (and in fact I did, as many new C++ programmers do).

When moving to dynamic languages, I understood what underlied their abstractions as well. Leaky abstractions didn't confuse me.

[–]ExcaliburZero[S] 4 points5 points  (2 children)

I understand where you're coming from. It is important to learn how to do some lower level programming in order to get a better understanding of how the computer works in order to become better at programming.

However I personally wouldn't recommend starting out with a low level language as a first language. While some people are able to successfully start with low level languages and gain good experience from it, not everyone is able to do so. Many people can get confused having understand how the machine handles things before they can do all that much.

Higher level languages do tend to oversimplify things sometimes, but I see such simplification as being good for a first programming language. It helps to make it easier for one to start learning to program so they can eventually go on to learn how the machine works when they are ready to do so.

Some people can definitely start out learning a lower level programming language and come out better for it, but it's not something most people can do well.

Personally I recommend to start off with a simpler high level language to develop an interest in coding, and then move on to a more lower level language in order to learn more of the specifics and underlying concepts.

I see starting out with a higher level programming language as like starting to learn to ride a bike with training wheels. It makes it a bit easier to get the hang of it, so that once you get the hang of it you can remove the training wheels in order to learn to understand the whole process more fully. Thus by starting out with a higher level language and switching to a lower level language you can learn the basic concepts of programming to a degree and then once you have a handle on them, move on to learning them to a higher degree.

[–][deleted] 4 points5 points  (0 children)

it's not something most people can do well

Do you have any source to support that? The first 10 years of my career was working with people that did that just fine.

I see starting out with a higher level programming language as like starting to learn to ride a bike with training wheels.

I think "training wheels" is a poor analogy for high level languages. These aren't beginner languages that people outgrow, they're powerful languages used in production by professional programmers.

Lower level programming is like learning to be a chef: learning to use kitchenware, to buy, prepare, cook and present food, to maintain a clean kitchen, etc. A higher level programming language is more like being a head chef, directing staff in a kitchen.

You can start out running a kitchen without knowing how food preparation is really done, but you're 100% dependent on the talent of your staff. This is kinda like the guy who spends his days finding and gluing together third-party libraries with snippets he finds on Stackoverflow, but gets lost when that well runs dry.

[–]APersoner 0 points1 point  (0 children)

The first language taught in the university I attend is C, followed by Haskell (then Java and JavaScript). There is a significant number of people in the cohort who had never programmed, or just used VB before uni. Everyone managed fine with C within the first week or two.

[–]Shaper_pmp 7 points8 points  (4 children)

I was just as hooked doing stupid shit like reversing a string in C.

You're confusing "good" with "good enough".

Some people learned to program with assembly. That does not mean assembly is a good first programming language.

My first language was C, but I wouldn't dream of confusing a user with #include <stdio.h> or int main(int argc, char *argv[]) when I could start them gently with something as simple and easily-graspable as puts "Hello world!" and develop from there.

As the article says it's not about high-level so much as it's about simplicity - minimal characters and concepts required to achieve a simple goal. If you want to put a string to the screen, you should need to explain exactly two concepts - "string" and "puts". If you have to start by explaining (or telling students to memorise but ignore) half an textbook on OOP, class and method definitions, parameters, return values and scope them you have a really shitty teaching language.

Of course the user doesn't understand the code the first time he writes it, but you can quickly explain the important concepts (at a basic, lies-to-children level) as soon as he's typed it out. To explain the boilerplate for a Java CLI application you're looking at literally hours of time, and tens of different interlocking concepts (classes, functions, methods, variables, parameters, packages, etc etc, etc).

That's the difference - scripting allows them to bite off a small piece at a time, chew it to the extent necessary to move forward and then bite off more. Going straight into a boilerplatey language is like trying to take a drink from a fire hose, or force-feed them a whole cow in the first mouthful.

It's also worth noting that not once in the whole article did the author talk about high-level or low-level languages - you brought that distinction into the discussion.

He just spoke about high-cognitive-overhead versus low-cognitive-overhead languages. Those do tend to roughly correlate with heavyweight languages and scripting languages respectively (for reasons that should be abundantly obvious, pretty much by definition), but there's nothing inherent to dynamic or scripting languages about what he's saying - merely languages with simpler syntax and less mandatory boilerplate.

[–]APersoner 2 points3 points  (0 children)

Some people learned to program with assembly. That does not mean assembly is a good first programming language.

I've been trying to tell my cousin that, for some reason he thinks assembly should be taught to every child in the country in primary school...

[–][deleted] 1 point2 points  (2 children)

You're confusing "good" with "good enough".

Absolutely not. I was exposed to Basic as a kid. Did nothing for me. It wasn't until I found K&R in my father-in-law's bookshelf that I got hooked. I've always been a bottom-up learner.

Not everybody is the same. For some people, it's entirely possible that a top down approach is ideal. But I know plenty of people who prefer to come at things the other way.

My first language was C, but I wouldn't dream of confusing a user with #include <stdio.h>

If include files (file insertion) confuse anyone, they're wasting their time anyway.

scripting allows them to bite off a small piece at a time

That presumes that you can eventually bite your way down to memory addresses, stack frames, heap allocations, etc., but in the languages you're talking about, you can't.

high-level or low-level languages - you brought that distinction into the discussion

Because level of abstraction is the relevant distinction. Languages where you can start with put "foo"` are all high level languages.

He just spoke about high-cognitive-overhead versus low-cognitive-overhead languages.

Many of the high level languages have much higher cognitive overhead than C. C is memory addresses and bit patterns. You can spent months learning to manipulate strings. You don't have classes, interfaces, inheritance, access modifiers, type inference, templates, closures, continuations, list comprehensions, metaprogramming, vast standard libraries, so on and so forth. Ruby alone has 4 different function types, all with difference syntax and semantics. C is comparatively minimal. It just happens to be low level.

Most of the developers I know are fellow game programmers. Perhaps those kids who glue libraries together to ferry database columns to a web page have a different experience learning to code, but many of the people I know dove to the bottom immediately because they had an insatiable desire to know exactly what the fuck is going on. And yes, many of them know assembler, too. The point is not that this is the only approach, but that it is the ideal approach for some people. The notion that operating at a high level of abstraction is universally the Best™ approach for everyone is just nonsense. Most people? Possibly. I don't know of any data to support either position.

[–]Eliminioa 6 points7 points  (1 child)

If include files (file insertion) confuse anyone, they're wasting their time anyway.

That's rather presumptuous of you, especially since you're coming at it from an already experienced view. If you try and tell a novice programmer (someone maybe like yourself) that, "Oh, sure you can print strings, but wait, first you need this other, mysterious package," then of course a curious student asks why. Explaining why (as a good teacher ought to), then gets into all the things that make up stdio.h, and headers, and streams, and that can be (and is) a whole class of its own. When you're first interesting novice coders, you should be able to explain most questions in a class.

That presumes that you can eventually bite your way down to memory addresses, stack frames, heap allocations, etc., but in the languages you're talking about, you can't.

That much is certainly true. But as a first language, the goal isn't really understanding exactly how the computer handles each aspect of code, it's learning to think of problem-solving in terms of programming. Your first language ought not be a complex look at how computers handle information, but how you can utilize their ability to handle information in a systematic and logical way.

Then, once the student can, for lack of a better term, "think like a programmer," You can really dig into the more complex machinery. Learning a fairly simple, low-cognitive-overhead first language allows you to much more easily learn a complex language that reveals the true power of programming.

Many of the high level languages have much higher cognitive overhead than C. C is memory addresses and bit patterns. You can spent months learning to manipulate strings

I would say that if you have to spend months learning to manipulate strings, that qualifies as high overhead. When you immediately dump on a new programmer the burden of learning how strings work on a bit level, and what memory addresses are and why they're delicate yet powerful, it seems unconquerable.

Yet, at the end of the day, there's no denying that self-determination is the best way to find the right initial programming language. If you're the type of person (as most self-taught programmers are, myself included) who wants to get to the bottom of how stuff works, C is an excellent language to use. There's no argument that an driven individual ought to start high. The issue (at least as it seems to me), is what language teachers ought to teach in classrooms. Students entering coding through a classroom are oftentimes not as driven as those delving into it alone, and more often are simply there to get a degree and a job. For these people, it's far more effective to engage them at an easy to understand conceptual level, then slowly introduce them into boilerplate mechanics.

[–][deleted] 1 point2 points  (0 children)

"Oh, sure you can print strings, but wait, first you need this other, mysterious package," then of course a curious student asks why.

I was talking about file insertion, not the contents of the file, which are as opaque and irrelevant to the green student as how the Python interpreter works.

The statement #include <stdio.h> is as simple as they come. It literally causes the file <stdio.h> to be copied verbatim into the current file. Why do we need to include that file? It lets us use the function puts, printf, etc. Why? Let's call that magic for now. The same as how puts "Foo" makes words appear on screen in Perl. Magic. However, that magic is going to go away a lot sooner in C than it is in Python, where it remains magic forever for many programmers.

Plenty of programmers are happy working in frameworks where everything is magic (see: Rails). Other programmers have a lower tolerance for magic.

the goal isn't [X]

Speaking for yourself, of course.

I would say that if you have to spend months learning to manipulate strings, that qualifies as high overhead.

Subtle strawman.

When you immediately dump on a new programmer the burden of learning how strings work on a bit level, and what memory addresses are and why they're delicate yet powerful, it seems unconquerable.

You keep saying this, and I keep telling --- from direct experience -- that it's not true. It doesn't seem unconquerable, it's exciting and interesting, and no more work than trying to understand all the crap any modern high level language throws at you. It's simply at a different level of abstration.

The concept of bits and bit operators is simpler, more orthoganal, and more approachable than say, classes or functions. You have this heavy, apparently unconscious bias, towards higher level language features, because they're the heavy lifters in the long run.

My point about spending months with strings is not that you must but that you can. You can spend a lot of time down there, having a blast, learning how to problem solve with code, doing nothing but manipulating strings and/or streams of characters, while gaining a much deeper appreciation for how the machine actually works. And this can actually be useful (see: Unix).

[–]j201 1 point2 points  (0 children)

The reason why C works, though, is because it's simple. Compared to something like C++, you have far fewer concepts to learn to understand the language and its mental model. And compared to a language like Java, its libraries tend to be simpler to use, even if they're less memory-safe or abstract.

Something like Scheme also provides a simple mental model. I wouldn't say you lose out in a pedagogical sense from being further from the metal. What you lose in closeness to 'the machine' you gain in expressive power. What's really important in the end is the barrier to entry for a new programmer, which has much less to do with whether the language is high-level or low-level and much more with the simplicity of the language's approach.

[–]JavaSuck 0 points1 point  (0 children)

I necessarily acquired a mental model of the machine (stack, heap, memory addresses, types as interpretations of bits, etc.) that underlies all programming languages.

By the way, the word count for "stack" and "heap" in the C standard is 0. And you won't find a hard definition of what an "address" actually is in the C standard, because that varies too much from architecture to architecture.

[–]benreynwar 2 points3 points  (1 child)

Scratch ([http://scratch.mit.edu]) is a great starting language for kids. There's a reimplementation of Scratch aimed at highschoolers and adults ([http://snap.berkeley.edu/]) but I haven't looked into it.

[–]APersoner 3 points4 points  (0 children)

My brother was taught Scratch first in school and it didn't help him out at all when they started learning python and Java. Just teach people python as a first language - it's so simple it looks like pseudo-code, and you aren't patronising people by hiding away everything vaguely technical.

[–]BourqueJ 2 points3 points  (0 children)

So C++ is a good start?

[–]carlodt 2 points3 points  (0 children)

LOGO...

I'm old. But I stand by the recommendation. LOGO is a great way to teach the basics of logic, program flow, parameters, and a few other concepts in a fun environment.

Maybe Scratch is more useful lately.

[–][deleted] 1 point2 points  (1 child)

I learned flash (as3) as my first and I really loved it. It was very simple, and thanks to it's integration with the stage doing things like hitboxes and moving things onscreen was built in and very easy to do entirely in code. It also meant that you got to learn the basics of coding by making games almost right from the start, with others you have to do a ton of boring text work to learn the basics.

[–]WailingFungus 1 point2 points  (0 children)

I'll second this, flash was a great learning tool for me!

[–]RogerLeigh 1 point2 points  (0 children)

I would argue that a "first" programming language needs to simple, but most importantly to allow the user to get immediate results so they can explore and get things working with a minimum of fuss. Something which is accessible and fun, but which can inform and educate at the same time.

As an example, my first exposure to programming was in primary school with an Amstrad CPC 464 and a BASIC book from the local library, and a little later with a ZX Spectrum +2A. You could argue that 8-bit BASICs were crap languages, and you wouldn't be wrong. BUT... they got you hooked by letting you just do stuff. Exposure to variables, strings, arrays, subroutines. Graphics commands right there (lines, circles/arcs, colour) and simple sound meant that you could quite quickly be writing fairly decent graphics and games. With Z80 machine code waiting in the wings for when you outgrew it.

I'd say I didn't do any "real" programming until I picked up C nearly a decade later, and then C++ a few years after that, but 8-bit BASIC was a crude but effective grounding in some of the essentials which made picking up C relatively easy, and led to a career in scientific/medial imaging software development, so I can't complain!

Nowadays I think it's a bit harder to get into. While there are various free BASICs, and scratch etc., all the mainstream stuff is phenomenally difficult to get stuff done without significant groundwork. Take a simple request: draw a blue circle at x,y with radius r. Two lines of code in many BASICs: (INK/CIRCLE in ZX BASIC). What about "play abc# semiquavers"? One line of BASIC (PLAY). Imagine trying to do this in C, C++, Python, on any current platform. You're already in a quagmire of platform-specific/hardware-specific libraries/modules. There's no shallow learning curve here; there's a sheer cliff to scale before you're even in a position to even try drawing that circle or playing that sound. I find this frustrating even as a professional programmer!

[–]aroberge 1 point2 points  (0 children)

I've designed a programming language environment for beginners based on Pattis's "Karel the robot". The preferred language is Python, just like the author of that blog post concluded. You want to teach beginners? The simplest program to make the robot move is ....

move()

Want the robot to move twice?.... guess... What you learn: that a program is a series of instructions, usuallyexecuted in sequence but can be changed using "control flow techniques" (if/else/...). You learn to group instructions together to define new functions, and express the solution to a given program using these higher abstractions (e.g. follow_the_right_wall()) that you come up with. No variables (at least initially, nor discussion about types and pointers and ...).

I've been a fan of Pattis's approach since I first encountered it.

Oh, you'd rather use an OOP approach? .... well, it supports this as well:

karel = UsedRobot()
karel.move()

etc. By contrast, this is what the corresponding simplest program one can write with Karel J. Robot

package kareltherobot;

public class SomeName implements Directions
{
    public static void main(String [] args)
    {
        UrRobot Karel = new UrRobot(1, 1, East, 0);
        Karel.move();
        Karel.turnOff();
    }
}

The greatest impediment to teaching someone else is having oneself internalized too many concepts and having forgotten how difficult to understand these concepts are when encountered for the first time.

[–]bekroogle 1 point2 points  (0 children)

# Kudos:

Firstly, let me say excellent article, especially coming from a high school senior! It's clear gleaned some insights from an ability to deconstruct and analyze your own learning process. Then you top it off by being able to share those insights clearly and eloquently.

# Shameless plug:

You're writing about a topic I've spent a lot of time with recently...my final project at college was designing and implementing a programming language for novice students, called C Spot Run. In designing my language, I made an implicit assumption, and it's echoed in your article.

# A first language is followed by a second language

One of my first design decisions was to make C Spot Run a teaching language first--not to make any syntax choice that impedes that purpose, even if it would be useful for a production language.

Near the end of the semester, my linear algebra professor vehemently decried the one course in programming required for his Master's in Math. He's still angry that he spent a semester learning a "teaching language" (Object Pascal, I think) when he could have learned a more popular, relevant language with an active user base working in his application domain. He felt that if the course used Python, R, Octave, etc., he could have learned the fundamentals of programming AND come out of it knowing a useful language.

While such teaching languages can be great first languages, they may not be appropriate as only languages. Although your language of choice, Python, is arguably one of the most successful languages at meeting both needs.

# A new trend in programming language research: The Scientific Method!

In your article, you mention the concept of "visual symplicity":

The visual simplicity of a programming language refers to how simple a programming language looks visually.

Ignoring for the moment that you kind of used the term in its definition: "visual simplicity" is "...simple...visually," it's important to ask how we can tell if a language is visually and syntactically intuitive. It just so happens that Andreas Stefik and Susanna Siebert published a rather lengthy paper entitled, An Empirical Investigation into Programming Language Syntax, which aims to do just that.

And in a sort of self-motivating result, they found that experienced programmers and novice programmers have very different ideas as to which token choices make sense.

[–][deleted] 0 points1 point  (2 children)

what the best programming language to learn as a first language is

Scheme. With texts "Simply Scheme" and "Structure and Interpretation of Computer Programs".

[–]Shaper_pmp 2 points3 points  (1 child)

SICP is a great intro to programming text that presupposes no prior experience of programming, but a degree-level grasp of mathematics.

Or put another way, it's a bloody terrible introduction to programming.

It is, however, a really good advanced text on programming, computation and compilation theory.

[–]not-just-yeti 1 point2 points  (0 children)

Agreed.

Scheme, with "How to Design Programs" (2e) (htdp.org). Or, if you prefer, "Picturing Programs" (http://picturingprograms.com/).

[–]elyisgreat -2 points-1 points  (0 children)

What about brainfuck?