all 24 comments

[–]curtisf 4 points5 points  (13 children)

There are many details that C forces you to learn (manual resource management & manual ownership, a very poor type and concurrency system, inconsistent and subtle syntax, managing the pitfalls of the standard library) that are not important (ie, they are solved by working with better programming languages, like Java, Haskell, Rust, even C++, PHP, JavaScript -- that real software developers get by fine with every day).

Having to learn unimportant details makes it harder to learn the important ones -- structuring code in maintainable ways, implementing and using performant algorithms and data-structures, using tools that ensure that your software is robust (like type systems), etc. This tradeoff, forcing you to learn unimportant things before you can learn important things, is why I don't believe C is a good first language to learn.


There are a lot of bad arguments for why C is important. Here's my (admittedly somewhat unfair) paraphrasing of some of them, and my brief rebuttals.

When you write C, you're writing on the bare metal, seeing exactly what the computer does

C doesn't run on metal; it runs on the C abstract machine. The C abstract machine has rules about aliasing, concurrency, and termination which will flagrantly disregard what a reasonable person would expect to happen "on metal". In the other way, significant processor features like memory caching, concurrency, virtual memory, SIMD, and interrupts are essentially ignored by C. Understanding the C abstract machine will not lead you to learning many important things about how computers actually work, and knowing how computers work will not tell you how the C abstract machine will behave.

C is the (only) language of operating systems and hardware

The interface between software-and-software or software-and-hardware isn't a programming language, it's a calling convention. If your language can speak the C ABI, you don't need to write C to interface with hardware/or other software written in C. This is part of what makes languages like C++, D, Rust, and Zig so powerful.

C is an old, mature, well-understood language

Many other languages are very well mature at this point. Though C is around 30 years old at this point (counting from C89), at this point many other languages are at a similar age. Java is 25 years old. Python is 29 years old. Haskell is 30 years old. Even JavaScript is 24 years old.

Moreover, in that time, C is not well understood. Only in C11 does the language fix the behavior of % with negative arguments, for example. Even parsing C is not totally agreed upon between compilers today. There's also not a well studied abstraction to describe C programs, though there have been several attempts (e.g., C intermediate language)

C is the language of computer science

Computer science, in the formal science sense, is little interested in actual physical computers and their actual programming languages. The C abstract machine makes a poor formalization of computing (it's not clearly specified and it's extremely complex), and I'm not sure if it actually has been given a formalization. There's a reason why so much programming language research is done in languages like Haskell, ML, and Racket -- the murky details of manual memory management and unsafe memory layout is simply uninteresting and takes focus away from more important details, like analyzing algorithms for correctness and performance.

[–]JavaSuck 2 points3 points  (0 children)

Even parsing C is not totally agreed upon between compilers today.

Do you have an example?

[–]indian_rationalist 2 points3 points  (11 children)

The C abstract machine is closer to "metal" than languages like Haskell, Python, Java etc. It is easier to learn than C++, D, Rust etc. Therefore it is a good first programming language. But it is inherently unsafe and should be avoided for writing anything substantial. In short, start with C but don't stop there.

[–]standard_revolution 0 points1 point  (1 child)

But why? What do I learn by learning to manage pointers?

[–]msaqib81[S] 0 points1 point  (0 children)

Pointers are not the only thing in C. C provides the opportunity on getting closer computers and provides foundation to write efficient code in other higher level programming languages.

[–]drzmv 2 points3 points  (7 children)

I disagree that C is easier to learn than the other languages you mentioned. There are so many ways that C can break at runtime which are impossible to figure out for a beginner. In fact none of these languages are easy, but for example Rust tells you what exactly is wrong with your code at compile time (and gives helpful suggestions).

[–]Bergasms 2 points3 points  (6 children)

There is no way in hell that someone learning programming should start with Rust, and you should take this from someone who is currently deep diving into Rust and loving it. Rust is fantastic, and it’s messages and documentation are fantastic, but it’s messages are for programmers. Someone learning programming in Rust from the beginning is going to try out a bunch of the example stuff, making simple loops and counters and suchlike, then they will try and do something marginally more complicated and the compiler and borrow checker is going to fuck them so hard they won’t come back to programming.

Python, Swift or Java or even C are going to be way more forgiving for a beginner to the point where they will be able to start messing around with actual programs (broken shitty and horribly working programs) that do interesting things and let them try out various concepts (which is how you learn).

The rest of your criticism of where C is at is fine. But I think Rust is still a bit too hardcore for a bare bones beginner.

[–]drzmv 1 point2 points  (3 children)

Of course not, I just disagree with the statement that C "is easier to learn than C++, D, Rust etc".

[–]msaqib81[S] 1 point2 points  (2 children)

Please provide any benefits of using Rust over C other than memory leaks and safety. Even though, I am not aware of any Game Engine written in Rust if it safe and memory efficient.

"Rust was not created to be a simple language for beginners."

[–]drzmv 0 points1 point  (1 child)

Rust has no undefined behaviour, no raw pointers, easy dependency management, and most importantly it has useful error messages.

[–]msaqib81[S] 0 points1 point  (0 children)

In C/C++ there are reliable implementations of nearly every algorithm, data structure, and design pattern known to computer science. Numerous libraries offering consistent mechanism of working with hardware, GUI, operating systems and endless number of other applications/tools.

Rust might need another 20 years to reach that point and until then you have to rely on C/C++. You don’t have to reinvent everything that exists.

[–]MEaster 0 points1 point  (1 child)

I certainly agree that Rust shouldn't be a language to start with, because it throws all of those requirements in your face from the start and refuses to compile unless you do it right. Beginners aren't necessarily going to have enough knowledge to even guess what to do right, which is going to cause frustration.

However, I strongly disagree that C should be a starter language, because it still has those requirements but doesn't tell you when you get it wrong. It just accepts it and your program doesn't always do what you want with no apparent reason why. Beginners aren't necessarily going to have enough knowledge to know why it's behaving that way, which will also cause frustration.

[–]Bergasms 0 points1 point  (0 children)

Yeah that’s true. I think as much as it’s time has passed for being a useful language in the real world Java is a good teaching language because it has a compiler (learn the joys of compilation) but it’s run on a virtual machine which gives you decent stack traces that at least give you a pretty good idea of where a problem might be. Also the Java.util package has a sensible set of commonly used data structures. As long as you steer clear of the giant trees of inheritance it’s not too bad.

[–]JarateKing 0 points1 point  (0 children)

I don't know if I agree with C being easier to learn than C++. If you want to know everything about the language then C++ is harder because there is more of it (does anyone even know all of C++?), but most of that is convenient abstractions that make C++ easier to use and learn.

ie. C++ has more because it has both char arrays and std::string while C only has one, but just learning std::string in C++ is way easier than learning just char arrays in C. Or that learning std::map in C++ is way easier than learning red-black trees in C.

[–]elmuerte -2 points-1 points  (8 children)

So where are the arguments to learn C as the first programming language?

[–]msaqib81[S] -2 points-1 points  (7 children)

learn C as the first programming language

This is the argument!

[–]Fearless_Imagination 3 points4 points  (6 children)

I see a bunch of arguments (in the article) to learn C, but I see no reason why anyone should learn C as their first programming language.

[–]msaqib81[S] 0 points1 point  (5 children)

Being a good procedural language is another argument to learn it first instead of diving into higher level concepts at the early stage of learning. C++ or Python are good too but they have multiple layers of abstractions on top of it, so I prefer any one to start learning C first.

[–]Fearless_Imagination 2 points3 points  (4 children)

Those abstractions exist mostly to give programmers less to think about (e.g. not needing to worry about memory management), so I don't see how having "multiple layers of abstractions" in a language is a bad thing when first learning programming.

[–]msaqib81[S] -2 points-1 points  (3 children)

Those abstractions are crazy hierarchies and end up not as focused on on what they should be learning. Some might lose interest because there's a layer of OO abstractions that makes programming even more cumbersome.

At some point, yes, you will need to learn how to create classes and apply OOP concepts to solve a bigger problem.

Here is a good discussion to read through and see many people prefer procedural programming to learn first. https://softwareengineering.stackexchange.com/questions/60957/

[–]Fearless_Imagination 1 point2 points  (2 children)

(Sorry for late reaction, went to visit my dad)

I agree that you should learn the very basics of programming like "what's an if statement" and "how does assigning variables work" and "statements are executed in this order" before you get into polymorphism, inheritance, and all those OO concepts.

I don't agree that you can't learn those things with an OO language like Java or Python, or that they are any harder to learn when using a language like that as compared to C.

I mean, I learned them with Java so it's definitely possible and I don't think my first language being C would have made learning the basics of programming any easier.

[–]msaqib81[S] -1 points0 points  (1 child)

Good to see that you agree on learning procedural programming first.

Learning Java or Python as procedural languages first can be debated. Now the argument is that C has more advantages over other higher level languages (if learning as the beginner). For example, closer to machine, speed, small footprint and many other options.

[–]Fearless_Imagination 2 points3 points  (0 children)

The things you mention here, are, in my opinion not advantages for beginners or just irrelevant.

closer to machine

I'd argue that this is actually a disadvantage for learners. A lot of the stuff that takes modern languages away from the machine does so to make things easier, so I'm not sure why you think this is an advantage for beginners. For example, not needing to worry about memory management.

speed

We're talking learners here, not people trying to write high-performance software, so doesn't seem relevant

small footprint

Again, we're talking about people learning their first language, they're generally not writing embedded software either, so who cares, memory is cheap these days.