
C, The Beautiful Language - pprov
http://tenaciousc.com/?p=1787
======
dkarl
All it means is that he understands C better than other languages. Even Java
(yes, Java) has these rhythms that he speaks of. You look at code and you feel
the logic, even the necessity of it. That's just the feeling of being in tune
with code and with the person who created it, thanks to a shared understanding
of the language. Master any language and you'll get the same feeling when you
read well-written code. Actually, though, the less boilerplate a language
forces you to write, the less you'll feel that "inevitability," since much of
the "inevitable" structure of the code -- the predictable patterns in the
design of code, or, one might say, "design patterns" -- is code you shouldn't
have to write in the first place.

~~~
codexon
+1 C is ugly.

\- Why do I need to typedef a struct to make it look like any other type?

\- Why do function pointers look so bad?

\- Error handling in C? Those goto exception; if(0){exception:} sure look
fantastic.

\- int* var1, var2; var2 is an int, not an int* ... The language lets you
stick the * right next to the type as though it modifies the type. Which it
does in casts. (how do I escape asterisks on here?)

\- A system language where int can be 32 bits or more.

And probably more from people more experienced in C than me.

~~~
ComputerGuru
\- You don't. C99 treats structs like classes.

\- Typedef them.

\- If done right, it can be quite unobtrusive.

\- That's not how it should be written. This is a 100 times clearer:

int *var1, var2;

\- Not really. And don't use int, int32_t is where it's at.

~~~
sid0

        int *var1, var2;
    

is not clear at all. var1 has type "int pointer", and for each type T, its
pointer type is represented as the type T*. It's just one of the many ways the
C user interface is broken beyond reason.

The point is not that you can't do good things in C. The point is that it is
very easy to do bad things in C. A good UI makes good things the natural way
to do things, and actively discourages bad things. C's UI is the opposite.

~~~
geoka9
_It's just one of the many ways the C user interface is broken beyond reason._

I'd say this one is just a question of preference. I happen to like to be able
to declare my variables together with my ponters.

 _A good UI makes good things the natural way to do things, and actively
discourages bad things. C's UI is the opposite._

In my opinion, that's the beauty of C: unlike Java (and, to a little extent,
C++) it doesn't dictate how you write your programs. You are free to shoot
yourself in the foot, but you also get to decide exactly how you want your
code to look and feel.

~~~
sid0
The small cost of not being able to declare your variables together with your
pointers is nothing compared to the confusion it avoids.

    
    
        int* var1;
    

is the way I (and I suspect anyone who's studied theoretical algebraic data
types) _think_ about my variables and types. It sucks that C forces me to
mentally translate it to a much less satisfying form.

I'm not sure what being ridiculously easy to make errors in has to do with
dictating how to write your programs.

------
Groxx
> _In other languages, the abstractions and sweet (if helpful) syntactic sugar
> that attend the code conceal the heartbeat._

IMO, that means they're failed abstractions and syntactic sugar. Proper ones
should result in _better_ understanding due to simplification - you can learn
it in levels, easily encapsulating the knowledge at each level so you know you
can "trust" what it's doing without having to remember all of it.

~~~
rbanffy
As such, any abstraction or syntactic sugar that distances you from the _flow_
of the program fail.

Bu that's for programs that are procedural. Functional programming has no
flow. Truth neither moves nor changes.

To use an analogy, a procedural program is like music, where rhythm and motion
of the instrument are the essence of what you are representing. Functional
programming is more like sculpture, where you create an elaborate piece that
has no rhythm or movement of itself, but guides the flow and transformation of
the data around it.

~~~
Groxx
I haven't done functional programming really, I didn't think of that case.

Interesting that it still seems to apply, though. If your abstractions in
functional programs obscure that flow, they still strike me as a failure.
Though I'd be interested in if functional programmers would disagree, I
obviously don't know functional design patterns.

~~~
silentbicycle
If you reason about functional code with appropriate assumptions: they don't
lie. A big part of functional programming is making code easier to reason
about in isolation.

If you want good procedural C code, read Lua. That shit is _polished_.

------
TillE
> we watch Ronaldo doing things on the pitch

Hmmm...

Lionel Messi does crazy things you never thought were possible. He's Lisp.

Gareth Bale has few fancy tricks, but does what he does very well, and often
relies on pure speed - C.

Joey Barton is good, but has a bad reputation and a sordid history - Fortran?

Etc :-)

~~~
trustfundbaby
You know your soccer my friend ... but you left out Java.

I'd say that's like Miroslav Klose ... big, strong, not particularly fast or
lovely to watch but damned good at putting away goals when it matters.
surprisingly so.

~~~
rahoulb
I like that about Klose :-)

I disagree about Barton - which language consistently repeats past mistakes
and is liable to stab you in the eye?

------
ssp
C is more a description of a Harvard machine than a von Neumann machine. In
fact, a useful new language feature would be dynamic generation of machine
code.

~~~
cdellin
Of course this isn't a feature of the language -- but most implementations
(e.g. gcc) technically allow this, if you really, really know what you're
doing. For example:

[http://www.cesarbs.org/blog/2010/07/19/run-time-machine-
code...](http://www.cesarbs.org/blog/2010/07/19/run-time-machine-code-
generation-and-execution/)

~~~
ssp
Yes, you can generate machine code yourself, but then you have to write
machine code ...

I'm suggesting a JIT compiler as a built-in language feature so that you could
write code in a high-level language and have machine code generated that was
specialized based on the program's dynamic state.

It could be done as a library, but it would benefit from language integration
so that you wouldn't have to write the code as strings or ASTs.

~~~
defrost
Language integration would be nice, however dynamic code generation from a
library has been about for some time now:

"With libtcc, you can use TCC as a backend for dynamic code generation." from
<http://bellard.org/tcc/>

------
angusgr
This is a nicely written tribute, but there are two generalisations that I
feel are worth pointing out.

Many parts of Linux kernel are really, really nice C code. Sadly, in my
experience most C code is not especially nice. I don't know how this extends
to the football metaphor, but certainly I wish most of the C code I have
encountered (not to mention written) in my career to date was one tenth as
neat.

On balance, I'd say there are other languages (Erlang, Python) where I've
personally found the median quality, and level of expression, to be
substantially higher (for the random subset of code I've read and my own
standards, clearly YMMV.)

The other generalisation is "other languages". Which "other languages" are
they? What other projects (despite the Linux kernel) are they reading, and in
what contexts?

You can find beautiful or precise code is almost any language if you try hard
enough. You can find ugly or obfusticated code in nearly every language
without barely trying at all.

~~~
paulsmith
What are some specific examples of beautiful C code in your view? Asking for a
friend.

~~~
dxq
After finding the documentation and guides for writing nginx modules woefully
inadequate, I did a lot of poking around in the nginx internals to better
understand how things worked.

The code is very readable, follows good style guidelines, and has its fair
share of brilliant workings. I found that the source code served as much
better documentation than a lot of _actual_ documentation that I've read.

~~~
cpeterso
You beat me to it! I was just about to suggest the nginx internals. :)

------
zyb09
In my experience it is more 'fun' to write C code then to lay down yet another
line of boiler-plate high level code. However, it seems to take longer to get
things done and the resulting code is also much more error-prone (at least my
code that is).

~~~
_sh
I feel C has more boiler-plate code than any other language I've used,
including Java--especially when you consider header files, malloc/free,
function call error code inspection, etc.

------
stevetjoa
C was my second love after QBasic. I still admire its simplicity, yet also
admire the abstraction, readability, and community of Python.

As anyone on Stack Overflow would tell you, it's a matter of using the right
tool for the job. I like to imagine programming language selection as an
optimization problem: given a job, over the set of tools, maximize the
appropriateness of tools for the job while minimizing the number of tools.
Without a tool number constraint, you could call from an infinite number of
tools, and one would be best, but that incurs overhead, obviously. The tool
number constraint keeps the problem feasible.

For numerical computing, {C, Python} solves my optimization problem.

------
j_baker
While we're making silly analogies, let me make one of my own. C is a bit like
a horse. It's fun to ride a horse from time to time, and there are still
plenty of valid, practical reasons to ride horses. However, you're kidding
yourself if you think you're going to talk me into giving up my car (well,
ok... my public transportation) for a horse.

~~~
burgerbrain
C is more like trucks or trains than horses. Backbone of the modern society,
but using them for all, or even just day to day, transportation needs could be
called misguided.

Fortran is more horsey.

------
KirinDave
These rhythms reflect a greater underlying symmetry. All languages have them,
and some of them reflect these symmetries more easily than others.

When you start to get familiar enough with a language that you see past it to
the underlying structure, that's when you really start to appreciate a
language. This process is not unique to C, or any other language.

------
waynecolvin
It was a cute sales pitch for the company's C IDE. I especially like how they
use "soccer", a word that resembles "sorcery". Talking about how one (only?)
gets the gist of things and is not a kernel hacker was great to speak to the
less-than-competent. Yes yes few of us write kernel modules but still.
Encouraging coders to be comfortable with C when they sell a product to help,
brilliant!

------
starpilot
Stupid question: what do you do when you're working in C and want OOP?

~~~
burgerbrain
Use OOP. :)

But seriously, you don't need a language to smack you in the face with OOP
syntax to use OOP, and with anything in programming, if you try to do it just
like you do in other languages, you're going to be disappointed.

------
sid0
This sort of idiocy is what holds computer science back. C, because of how
close to the metal it is, is pretty much the ugliest language in wide use, and
the fact that we know a lot more about programming languages and user
interfaces now than when C was designed doesn't help. It should only be used
as a last resort, when you really need the speed, and even then one should
keep an eye out for alternatives.

~~~
varjag
Which language would you suggest as replacement for writing of sched.c and
page_alloc.c?

~~~
waynecolvin
Oberon or Modula-2 maybe?

------
hacker-gene
Nice!

