Hacker News new | ask | show | jobs
A Very Quick Comparison of Popular Languages for Teaching Computer Programming (ariel.com.au)
12 points by djangonian 5221 days ago
10 comments

I used to think: C is a horrible language for beginners, they should learn python due to its simplicity. This will allow them to learn about control structures and program flow in a simple and easy to read environment. But the more I think about it, the more I like C. It gives you the best understanding of what computations are actually being done by your processor; the mental exercises involved with fulling understanding pointers is valuable at the collegiate level (much less so if your learning to program on your own, I believe college is a time to increase your analytical abilities rather than just learn raw facts); It also has the simplest syntax to learn (for a procedural language).

You dont have to explain argv, argc or the details of scanf to beginners. Thats like saying python is complex because you need to explain iterators and generators. You don't need to dig that deep into the language as a beginner, you just need to be able to understand the structure, control flow and be able to get your programs working.

But do we really need to submit beginners to things like segmentation faults, arrays without bound checks and the lack of a reasonable string datatype?

There is no reason to use C as a first language when you can just as well teach all the basic ideas in a more friendly environment and then go through all of K&R in 2 weeks or so.

The problem with OOP is that its really not something that should be taught to people who are first learning to program. It is extra complexity and doesn't add any value for beginners. That is my problem with Python.

C has its disadvantages, but you get: 1-a simple syntax 2-good mental exercises in learning, implementing and debugging pointer based data structures 3-a good idea of what is happening at the processor level when a computer program is being run.

You simply don't get that combination in any other language.

There are caveats of course: theres the functional vs procedural argument (which is a higher level argument than this). There could also be a good point that OOP should be the very first thing a student should learn, but only if you teach them a smalltalk based language, not python, java, C++ etc.

For the context of my argument, I chose: 'for teaching first year CS majors their first procedural programming language, what is the best choice?'

Where did you get the idea that I was supporting OOP-first? Its a terrible idea too.

In any case, I think Python is a great procedural language out there for a beginner - you can use the classes as if they were just structs and go a long way with that.

I started learning programming in January using K & R. C is great. Doing so many things manually really teaches you what is going on. It's definitely challenging, but I think I'm learning faster this way.
> But the more I think about it, the more I like C. It gives you the best understanding of what computations are actually being done by your processor

Yes, because C is exactly how computers work inside! SO CLOSE TO THE METAL

> the mental exercises involved with fulling understanding pointers is valuable at the collegiate level

I have learnt about mappings in mathematics in kindergarten. Literally. Then in university we have had exactly one sentence to flesh out the idea in ZFC. You really think C is so mind bending?

And at the same time we have a whole generation of people that don't know what a tail call is. C might be closer to the metal then most languages but it still is a leaky abstraction in some places.

And anyway, the real problem is not C being complicated. Its that the other alternatives are also perfectly reasonable while also being simpler.

I believe it is quite close to the metal. When I had my Systems Programming course in first year of college we started with C, and then continued with x86 assembly. One of interesting parts was, when we compiled our C code to assembly and then compared with our hand-written assembly code. Was fun :)
Do you realize that with pipelining, preemptive computation, multiple levels of caching, opcode optimization, NUMA, massive parallelism, and all that other stuff x86 is to hardware what Java is to hardware interrupts?

Answer: you don't because otherwise you would not have posted the above.

You're over exaggerating. You can teach students about processor theory, assembly language and C without getting into all the extra stuff.

All the extra stuff is built on that foundation, and learning C helps you understand that foundation better than any other language.

This is not "extra stuff". It is how it works. x86 was made to be simple to hand-code, not to in any way reflect the hardware. And then, decades later, new developments to it are so that it's easy to compile to. The language went through two major paradigms without either having the point of x86 reflecting the hardware it abstracts. SIMD, NUMA, pipelining and caching is exactly how processors work right now. And they're radically different to what happened before the Intel Core family of processors. This is in turn radically different to what happened before the Pentium Pro family of processors. Yet all support the same x86 instruction set. The corollary is that x86 is an abstraction. You're being ignorant if you think x86 is like the opcodes being executed after the whole caching stage has happened.
I never said it was mind bending. I said it was a good mental exercise for young engineers to go through to fully understand pointers.

It's one thing to read about pointers, it's another to actually implement a linked list in C.

Again, I want to stress I don't think you should get awarded a PhD for it, but for first year CS majors: it is good practice to actually implement and debug pointer-based data structures.

Yeah, but you're obviously arguing about that it's notable that you can learn about pointers. It's a tiny block of knowledge, really minuscule in comparison to other things which you can learn in the first year, such as the notion of an isomorphism, with assorted examples. I'd say this one can easily fill up about 100x more lab time.
C is not CLOSE TO THE METAL. It lacks concept of SIMD instructions and barriers/fences. If you want to be CTM learn OpenCL / CUDA (unless you want to learn assembler for actual ISAs or SIMD extensions).
Thanks for spelling it out, I am surprised there are people in this year and age who would not get that "C is close to the metal" is a trite joke.
Erlang version (abc.erl):

    -module(abc).
    -export([main/0]).
    main() ->
        {ok,[A]} = io:fread("A=?","~f"),
        {ok,[B]} = io:fread("B=?","~f"),
        C = A + B,
        io:format("C=~f~n",[C]).
or

    -module(abc).
    -export([main/0]).
    main() ->
        {ok,[A,B]} = io:fread("A,B? ","~f ~f"),
        C = A + B,
        io:format("C=~f~n",[C]).
Compile and run from REPL:

    c(abc).
    abc:main().
Or just execute in REPL:

    {ok,[A]} = io:fread("A=?","~f").
    {ok,[B]} = io:fread("B=?","~f").
    C = A + B.
    io:format("C=~f~n",[C]).
Was anyone else initially confused by the 'Postscript' heading at the bottom? At first I thought it referred to the programming language (PostScript) but in fact it's just referring to the "writing after the writing" (P.S.).
His postscript is a debatable improvement, as input() in Python 2.x (which was what the article was written using) actually evaluates the input as a Python expression before storing it. It's equivalent to wrapping the input functions that the other languages use in eval(), which is (imo) a very, very bad practice to teach unless you're asking your students to write a REPL.
Yes, he should have been using raw_input().
This was a very interesting read, but the Python code sample was painfully out of date. It might be worth it to create a modernized version of this post, with updated code samples for all the languages included, and additionally adding newer languages like Ruby and JavaScript.
> I spent about 15 minutes, failed, then searched Google for an example.

It is understandable that Java can be verbose, but 15 minutes followed by failure, make the author seem almost clueless about Java.

yeah, the use of java.util.Scanner would make it much more succinct:

    import java.util.Scanner;
    
    public class Addup {
        public static void main(String args[]) {
            Scanner sc = new Scanner(System.in);
            int i1 = sc.nextInt();
            int i2 = sc.nextInt();
            System.out.println(i1 + i2);
        }
    }
Very interesting, although he does indeed say:

> The extensive class library is however quite daunting. It appears there's a class for almost everything, and much of "programming in Java" seems to consist of "searching for the right class". Even after two years I find I cannot do much in Java without constant reference to the documentation.

I think it's fairly reasonable to not remember how to deal with user input in java when you need to remember what combination of streams and readers and buffers and scanners you need to put together to do it.
I'm not sure I could write that code right without Eclipse, or at least not without quite a few runs through the compiler and looks to the docs.. I'm not a Java guru, but I have used it quite a lot.

It's not hard in itself, but it is overly long, with a lot of things to remember.

The author explained that:

I'm actually kind of embarassed I had so much trouble with this - I've been working on a commercial Java package for two years, but because it's GUI based I rarely have to deal with reading from the console. Real Java programmers will probably look down on me with a mixture of pity and disgust. Such is life.

This is old, and there are no mentions of Erlang, Haskell or Scheme.

Not even PHP which while it isn't perfect it's still pretty easy to learn.

In the Java example there is a ton of error checking that is not being done in the other examples. Not really a fair comparison. The author said the programs should complete the task of "reading two numbers from the user, adding them together and printing out the result." The Java program does more than that, so of course it looks more verbose.
I think it is a fair example: both NumberFormatException and IOException are checked exceptions, so the code will fail to compile if they're not caught.
Despite being checked, they do not necessarily have to be caught if you add a `throws` clause in the method declaration.
Surprised to see Scheme was not included.
To everyone who was interested by pg's idea of a simple language for parallelism, check out pi calculus: http://mainisusuallyafunction.blogspot.com/2011/09/lambda-to...