
Learn C programming and the rest will come - majikarp
https://www.zeroequalsfalse.press/2017/11/29/c/
======
maxxxxx
I agree that learning C gives you a great foundation to understanding a
computer. I notice that a lot of people who have only learned languages like
Java or JavaScript often have a fundamental lack of understanding of what's
going on under the hood. Some assembly would be helpful too.

~~~
megaman22
The best class I ever took was a computer architecture course where we built
up an 8-bit minicomputer from individual gates onward in a logic simulator. It
was based on the Tanenbaum _Structured Computer Organization_ and the Patt and
Patel "Introduction to Computing Systems* books. By the end we were
programming it in a limited dialect of assembly and also with a minimal
version of C that compiled down to that assembly dialect. Very cool, and I've
never been mystified by pointers since then.

~~~
monaghanboy
I almost think a better post would be "Learn Computer Architecture and the
rest will come". For that, I can't recommend
[http://nand2tetris.org/](http://nand2tetris.org/) enough.

------
nayuki
I largely disagree with this article. C has too many pitfalls that a beginner
can either be discouraged by a non-working program, or not understanding the
subtle gotchas.

Avoiding undefined behavior in C is difficult, even for experts. Failing to
understand UB leads to very inconsistent, often latent, hard-to-debug
situations long after the bug has occurred. Other languages - including
assembly language - don't have this extremely hostile concept of UB. C
encourages bad habits like ignoring error codes from I/O functions. Also,
doing concurrency correctly in C (or Java for that matter) is a grand effort,
but is easier in languages like Go and Rust.

Managing language minutiae in C, like function prototypes and header files, is
something not found in newer languages. Another problem is having a global
namespace instead of a more structured, modularized one (C++, Java, Python,
etc.). And finally, manual memory management means that a lot of extra code is
written (contrary to the author's claims about conciseness), and it especially
makes string processing hard.

Personally, I only use C to implement cryptographic primitives (ciphers and
hash functions) and some numerical kernels. These are straightforward
calculations that don't require memory management or tricky pointer
arithmetic.

~~~
ramzyo
> C has too many pitfalls that a beginner can either be discouraged by a non-
> working program, or not understanding the subtle gotchas.

Totally agree with you - personally C would have been a very difficult first
language for me. Java and Ruby were tough enough at the outset when I started
down the programming path. Now I work primarily in C and have been doing so
for the last four years or so. Still get hung up on subtle gotchas, especially
when interfacing with hardware!

------
alew1
Meh. Learn any language and “the rest will come” if you then learn other
languages. Some of these points don’t lead to C’s being a better first
language or pedagogical language — like, why should a learner care that C is
so fast? I teach HS computer science and we do use C, in our Data Structures
course, after students have used Racket, Python, and Go. Using those other
languages lets us cover interesting and important topics like recursion, data
abstraction, concurrency, and more, all while doing projects that hold kids’
attention (sometimes using outside libraries for image or sound processing,
e.g.). C is well-suited to the data structures course where students have to
think carefully about memory and efficiency.

I can certainly imagine a different sequence, where students learn logic
gates, hardware, assembly, then C, working their way up to higher levels of
abstraction. Even in this case though, the goal isn’t to jump in and start
writing big programs in C right away.

~~~
maxxxxx
I think people should understand pointers, heap vs. stack and other things.
even in higher level languages a lot of performance problems can easily be
explained if you understand how memory works. I often see people allocating
and copying huge arrays back and forth and then thinking they need bigger
machines.

~~~
pjmlp
I learned all those concepts in Pascal, BASIC and Z80, about 4 years before
seeing C for the first time.

C isn't the only language with such features.

~~~
mcguire
Anyone seen Pascal, BASIC, or Z80s in the wild recently?

~~~
pjmlp
Pascal:

[https://www.freepascal.org/](https://www.freepascal.org/)

[https://www.embarcadero.com/products/delphi](https://www.embarcadero.com/products/delphi)

[https://shop.mikroe.com/compilers?programming-
language*=pasc...](https://shop.mikroe.com/compilers?programming-
language*=pascal)

Basic:

[https://www.visualstudio.com/vs/universal-windows-
platform/](https://www.visualstudio.com/vs/universal-windows-platform/)

[http://gambas.sourceforge.net/en/main.html](http://gambas.sourceforge.net/en/main.html)

[https://shop.mikroe.com/compilers?programming-
language*=basi...](https://shop.mikroe.com/compilers?programming-
language*=basic)

Z80:

Any Assembly will do, pick ARM, RISC-V, AVR, PIC, ....

------
0xfeba
> With C code, there’s no going into a program without fully knowing what it’s
> going to do at every step of the way...

This guy seems to be putting C on a pedestal. It's OK, for certain jobs. Like
kernels, CLI utilities, C/C++ for games, etc. But even there Rust and Go and
other tools are invading that space and doing well.

When I want to make something, I usually use whatever I think can get me to
something usable fast. C is rarely the answer. I think the same holds for
someone trying to learn programming. Python or Go removes a lot of cruft that
new programmers shouldn't have to deal with, at first. They are good intros to
"you want X? Well import X, then start using X.foo" instead of "You want X,
well first let's start a Makefile so we can get our libs linked in properly
depending on if this is debug or release, and then maybe CMake so we can use
it on other systems, and so on and so forth..."

------
djstein
I will state that the article itself was a fluff piece. However by posting the
title it will bring interesting discussion on hn. I do agree with the title,
very much so.

I think the Java then C then whatever else you fancy is the best way to start
programmers/software engineers out. Put them in a structured environment
(strong typing, little room for catastrophic errors), then learn why the
structure is there with C, then let them free roam to
Python/JavaScript/Rust/Go with the experiences gained by the planning at the C
level

~~~
uiuiuxuxux
I think learning java first would be very very detrimental to someone's coding
skills. They would spend the rest of their careers trying to deprogram
themselves from that useless way of structurng problems. For me the best would
be first c, then assembly, then lisp. In my experience people That started
with java and then learned python or js or something else tend to write
horrible convoluted code.

~~~
orwin
I don't think anyone should go with a language that allow him to do bad OOP.
In my experience, this lead to poor code in the beginning, even when this
person is one of the most brilliant you ever met.

People that learned with C (Pascal too) piss more straightforward code on
average, and have better debugging skills. And they are more "aware" of the
computer.

PS: I did go C, assembly (had to rewrite some libc functions) then emacs lisp
(before trying to write stuff in Common Lisp). I don't think going assembly
will help a webdev much (even if he work mostly on backend), but lisp is
definitly helpfull for anyone. Assembly is great if you like having some fun,
but beside CTF and "that one time" (i had a really nasty C bug), the stuff i
learned while writing assembly were not really usefull to me.

~~~
uiuiuxuxux
You are right about assembly. I was thinking c, then a little bit of assembly
just enough to demystify it. I think learning just a little bit assembly makes
you a braver programer hahaha. In any case if ound a lot of people really
damaged by java. Its horrible what that language can do to some people's
coding style and framework when thinking about problems.

~~~
khedoros1
> In any case if ound a lot of people really damaged by java. Its horrible
> what that language can do to some people's coding style and framework when
> thinking about problems.

What problems are you thinking of, specifically? In high school, I had a
semester each of BASIC and C++, but my first serious programming was with Java
in college. That is, beyond things like a "guess the number" game, getting
into actual study of algorithms and data structures.

I'm mostly a C++ dev now, and I've never had complaints about my coding style.
Then again, I never bought into the WidgetFactoryFactoryImpl kind of crap.

------
jventura
In my opinion, and assuming the author is talking about learning C as first
language, my answer is that it depends. It depends on what you're trying to do
with what you're learning, and what you will do after.

Basically, if you're studying to be an electronics engineer, I say that C is a
good first language to learn the constraints of electronic devices. But if
you're studying to be a mechanical engineer, I guess you want to learn
programming to solve "data" problems (equations, graphical plots, etc). For
the latter ones, something like Python with packages like numpy, matplotlib,
etc., is probably more adequate.

In a nutshell, I think of learning C first as the bottom-up approach, and
learning something like Python the top-down approach. Choosing one or another
depends on how down or up you want to go..

------
flavio81
> _What’s so good about it? Well.. C is fast._

Agreed! I also agree that K&R "The C Programming Language" is a classic book
that everybody should read, at least to admire how well written is it. And of
course C is a good language to learn. Not as a "first language" but as one of
the "languages to know".

> _Also, C is flexible. You can do more with C than you can do with newer
> languages._

What?! Yes, you can do anything with it, only if your time doesn't cost. The
same is true of Assembly code.

There are many languages that are more expressive and powerful than C, and
some of them aren't really that slow.

~~~
Tobba_
I feel like in the end most of it just comes down to how memory is managed and
the type system, at least if you consider C++ instead of C.

Personally I just wish for something like C# without the garbage collector
(and some good options for static compilation). Right now it just seems like
the only two choices are C(++)/Rust, where your only option is to deal with
everything manually even if the compiler or optimizer would know better, and
most dynamic GCd languages, where your only option is summoning Cthulhu to do
it for you.

~~~
fileeditview
I have slight hopes for Zig. Maybe there will finally be a real C replacement.
I never understood why C has not been brought into modern context. Go is
probably nearest but it has GC and C interop seems cumbersome.

~~~
Tobba_
Looks like a mash-up between C and Rust, though with somewhat funky syntax.
Still, C(++) with no preprocessor and non-nullable pointers is a huge
improvement on it's own, but is that full-blown CTFE with first-class types I
see? Hot damn. I could definitely see myself using that if it evolves further.

------
Philipp__
Bigger question for me was when does one truly learn C?

Finishing C course on college didn't felt like I learned C. Nor implementing
some common algorithms and data structures. [Lets mark my experience until
this moment as `phase 1`] This attitude made me stay in C for a bit longer,
getting my self interested in systems programming and that is when I got to
see truly what programming and debugging C really is. I was learning and
experimenting for 2 years with that, and I felt recently like I was ready to
move on, (Python and Clojure taking over for the most part) and the conclusion
was rather strange:

Everything after phase 1 didn't brought me that much, considering cost/benefit
factor I was not impressed by the end results. While whole first few years and
college in C were significant and I recommend it to everyone to learn C even
up to a point where you write basic CRUD program that read some data from
txt/bin and create linked list with that data and represent it, my venture
into systems and lower level programming didn't bring me as much of "general"
knowledge. Sure it was good, and I learned C++, and combining those two now I
do some other things that are related to the things I learned during that
period (like GPGPU), it wasn't that mindblowing as I expected initially.

------
danaliv
I will never understand this trope of "pointers are hard to understand." Yes,
they can get you in trouble if used without care. But hard to understand?
What's so hard to understand about an address?

~~~
camus2
> I will never understand this trope of "pointers are hard to understand."
> Yes, they can get you in trouble if used without care. But hard to
> understand? What's so hard to understand about an address?

I don't think anybody ever said that pointers are hard to understand, they
aren't. Go is a proof of this as even people coming from Python or Javascript
can easily pick pointers up even if they have never heard about the heap and
the stack before.

~~~
ashark
There are posters in this very discussion claiming that pointers were
remarkably difficult to learn.

I'm firmly in the "WTF is the big deal?" crowd. Every time I see posts like
that I think, "maybe I've thought I understood pointers just fine, and even
used them without issue, for _years and years_ , but somehow I actually _don
't_ understand them?"

I had a harder time with OO when I first encountered it than pointers, because
I kept running into terrible "Sally wants to buy some lemonade from
Tommy"-type introductions in crappy, cheap '90s C++/Java programming books and
bouncing off it.

~~~
khedoros1
> I had a harder time with OO when I first encountered it than pointers

Pointers weren't too hard to learn (although, the deeper they're nested, the
harder they are to think about, for me). OO felt immediately intuitive, using
the "shape class, rectangle class, square class" examples. Recursion is the
concept that I understood the general idea of, but had to do immense amounts
of work to be able to visualize.

I think that everyone has their own areas that they learn easily, that others
have a hard time with.

------
srcmap
For me, C programming is kind of like Calculus, Physics to modern day
Engineering.

If you don't know Calculus, Physics, you can be a very good construction
workers but hard to know the fundamental behind why/how the Buildings, Cars,
Airplanes, are designed that ways.

Same for C, if you don't know C. You can certainly a very good program Python,
java script, web developers, but might not have deep understand of Kernel,
Browser, Database, Network, nor why Java, Go and Rust need all those new
language features.

Know how the tools are different will help you to choose the best tool for the
jobs.

------
ralmidani
Having learned Python, then C++, then JavaScript, then C, then Java, I have to
say Java is probably at the sweet spot; it strikes a good balance between
providing enough conveniences over C and C++ to help avoid frustrating a
programmer (garbage collection, no need to use pointers explicitly) without
encouraging total carelessness like Python and JS do (inadvertently) with
their lack of built-in static typing.

With that said, if you want to provide instant gratification and therefore
encourage a beginning programmer to keep learning, Python and JS may be the
best for introductory classes.

MIT's approach of using Python to do a one-semester survey of CS and Data
Science, then using Java to teach serious Software Engineering, appears to be
an effective compromise (I did three of their CS courses on edX).

------
jokoon
Agree with it, but it's an unpopular opinion.

I often advocate python as a first language, but when you discover that python
uses references most of the time, it can get confusing.

Ideally, you would teach the basics of assembly, learn the basics of a
compiler, and go forward.

~~~
monaghanboy
I agree with the last statement. I think it's best to learn basic computer
architecture before learning C, which assumes a close relationship.

I took [http://nand2tetris.org/](http://nand2tetris.org/) before learning C;
starting from a single logic gate, you build memory, CPU, assembler, and a
compiler for small language (you implement malloc and free yourself). [0]

Though some folks say it sacrifices depth for breadth, I feel very comfortable
learning C now.

[0] HN thread for part 2 of the course:
[https://news.ycombinator.com/item?id=14526344](https://news.ycombinator.com/item?id=14526344)

[1] HN thread for part 1 of the course:
[https://news.ycombinator.com/item?id=13209452](https://news.ycombinator.com/item?id=13209452)

------
GFischer
Counter-anecdata: My stepfather tried to introduce me to programming via C as
a kid (with the very same Kernighan & Ritchie book), and it didn't help at
all.

An environment with a better REPL and which can do more "fun" programs is
better to start out.

Motivation to build fun stuff is important - I ended up starting my learning
on GWBASIC of all things :) and there were some cool BASIC games.

I absolutely agree that C is very important to learn when formalizing a
programming education.

------
howard941
As one who's working to get to a productive place with functional programming
I disagree: Decades of embedded c preceded by asm hasn't helped out at all.

------
jononor
Most should choose a more pleasant and productive language, so that the road
to make something working and interesting is not uneccesarily long. Starting
with C increases the chances of getting stuck and never getting a good feeling
about programming - which is sorely needed to stick to it.

------
djmetzle
I agree.

With C, you are in control of everything your program does. That means you're
also _responsible_ for everything your program does. C requires a very
different mindset than dynamic languages.

------
yotamoron
C for s/w eng is like classic ballet for dancing.

------
currymj
i could not disagree with this more, holy cow. C has so many weird and painful
quirks, and is missing a lot of things that a novice programmer will need to
know (like object-orientation, especially).

it's a great second or third programming language to learn though.

~~~
orwin
From what a saw, exceptionnal people aside, those who learned to code with a
language favorising bad OOP (most OOP languages, maybe with the exception of
Lisp) write nasty code. Especially when they work with a language like
javascript, but even with c++ or Rust you can easely find abominations.

Everybody should learn proper data structure before learning OOP. I don't like
Go, but i'd much rather work with an intern who was first taught Go than any
OOP language, even one i like. OOP is a great tool, but people that learned
with it have the tendancy to use it poorly and everywhere, and to use
abstractions of abstraction when this is not needed. Maybe for you, it was not
an issue, because you were brilliant enough, but for average devs like myself,
it is.

