
Follow up to "The Unreasonable Effectiveness of C" - DanielRibeiro
http://damienkatz.net/2013/01/follow_up_to_the_unreasonable.html
======
haberman
> I used C++ inheritance, templates, exceptions, custom memory allocation and
> a bunch of other features I thought were very cool at the time. Now I feel
> bad for the people who have to maintain it.

I think this is right on the money. There are a lot of things you _can_ do
with C++ (and other languages -- even C probably) that feel good at the time,
only to learn later that they don't age well.

I've never seen it analyzed deeply why this is, but I suspect it has something
do with how "fungible" the code is when you're done. Will your design let you
make small design changes with relatively small and localized code changes, or
has your complicated template/inheritance-based design "locked up" your code
into a particular pattern, where changing any of the design assumptions
requires "unwinding" a highly intertwined structure?

I don't know the rigorous answer to this question, so I design with various
heuristics, which mostly boil down to some version of "this is getting a bit
too complex or too highly leveraged." What I mean by "leveraged" is that some
significant guarantee or invariant is achieved through a complicated contract
between two different objects. I try to keep the design of every individual
type/object as "flat" and unsubtle as possible; again vague terms, but I know
it when I see it.

~~~
cageface
This is like insisting on driving around in a horse-drawn buggy because a car
can crash at higher speeds. At this point I just ignore anybody trashing C++
that isn't offering any real alternatives. And no, C isn't an alternative for
large scale app development.

~~~
betterunix
Who gets to decide what qualifies as a "real alternative?" I have seen much
larger applications written in Java than in C++; does that make Java a "real
alternative?" C++ does not really have any technical advantages over "true"
high-level languages (i.e. languages that don't force the programmer to deal
with low-level details and whose support for low-level operations does not
constrain high-level features), but it has plenty of disadvantages. Meanwhile,
I cannot think of anything people do in C++ that I am unable to do in Lisp,
although I can think of plenty of things people do in C++ that are unnecessary
in Lisp and that only serve to make code more complex and more error-prone.

So there, you have two "real alternatives:" Java and Lisp. I'll also throw in
Scala (basically it's what Java should have been to begin with) and OCaml. So
what are you doing in C++ that could not be done in any of these languages?

~~~
bcoates
> I cannot think of anything people do in C++ that I am unable to do in Lisp

The biggest technical advantage I've noticed C++ having over other languages
is that library performance characteristics are documented as part of the
portable language spec. I really miss that when I switch to other languages
and have no idea if the builtin list class acts like a linked list or a vector
or a deque or what.

Knowing that the algorithm you just built out of library components doesn't
have a n^3 blowup on some platform is a correctness issue, not a premature
optimization. I'm more comfortable that's not going to happen working in C++,
and the culture and libraries around it than anywhere else.

Does CL specify that, as part of the specification and not just by convention?
I'm having a hard time finding docs to that effect but I don't use Lisp enough
to know where to look.

~~~
MichaelSalib
When I was doing heavy common lisp work, this was just a non-issue. If I
wanted to understand how a library call would perform, I'd just press the
magic button in SLIME to jump to the source code of the library routine and
look.

This was much easier than manually tracing through the layers of template and
preprocessor indirection underlying even simple STL constructs.

It is possible that this sort of standardization was vitally important given
the incredibly poor quality of C++ implementations traditionally available,
but in languages with better communities with higher standards for
implementations and documentation, this really seems like a solution in search
of a problem.

~~~
Someone
_"If I wanted to understand how a library call would perform, I'd just press
the magic button in SLIME to jump to the source code of the library routine
and look."_

That tells you how your implementation works. It tells you nothing about how
other implementations (or the next version of your compiler) do things. The
point is that, with C++, the standard proscribes the O(...) of algorithms.

Yes, implementations can and will be broken, but given that writing a C++
compiler requires planning, I think it is unlikely that 'wrong choice of
algorithm' will make it into any deliverable (counterexamples welcome)

------
anigbrowl
I hated and feared C for years. Then I finally learned it and fell in love
with it. Now other languages seem like too much work. I'm only a hobby
programmer so that devalues my opinion somewhat (insofar as I don't have to
support large production systems or please committees), but one of the things
I love about C is that once you have something working in C, you're likely
done - if you need to go faster or better, then either your understanding of
the problem or the algorithm you're employing is flawed, or maybe you need to
do some bits of it assembler (DSP for example).

The other thing is that even though C is old it still work great. I don't know
how you web guys keep up with so many 'frameworks of the month' and so forth.
I took up C mainly because I was tired of things becoming obsolete before I
had got around to learning them properly.

~~~
tptacek
One of the greatest things about coming back to C from years of Ruby is that
you can constantly tell yourself "I don't need to worry about performance
because there's no way what I'm doing here could be worse than what Ruby was
doing for me". It's hard to fully articulate the feeling but it's great; it's
like a cure for premature optimization.

~~~
euroclydon
Is it possible to need C and not know it, or if I need it will I know it?
Because I can't think of anything I'd use it for. You guys speak of it and
other higher level languages as if you use them interchangably for the same
tasks.

~~~
tptacek
I use Ruby for things that deal with the web, for utility programs, and (most
often) for software I'm not going to need to support long term, such as
clients for bizarro network protocols I encounter on penetration tests.

I used to use C for everything else; I'd reach for Go first now, but I still
love C.

One way to think about C vs. (say) Python is that it's like the relationship
between an FPGA and an ASIC: you prototype in a high level language and you
write C when you _really_ know _exactly_ what you need your program to do. C
is not a great exploratory programming environment, but it is excellent when
you have a specific plan.

~~~
yuushi
And this is what I don't really understand. Python or Ruby are excellent in
the domain you talk about, but I would always, always reach for C++ over C if
given the choice. The C++ standard library for me alone makes this such a
simple choice. A lot of C code to me just looks horribly ugly these days -
stuff like:

    
    
      int compare(const void *a, const void *b)
      {
          return *((int*)a) < *((int*)b);
      }
    

Yuck.

~~~
tptacek
On the other hand, the mechanism by which that code works is simple to
understand and keep in your head at all times, and isn't inelegant. I find
that very valuable.

~~~
yuushi
Except it has absolutely no type safety whatsoever. With modern-style C++, you
can do the same thing in exactly 1 line:

    
    
      std::sort(begin(array), end(array), [](int a, int b) { return a < b; });
    

Versus:

    
    
        qsort(array, MAX_VAL, sizeof(int), compare);
    

With compare as defined before. I mean, sure, it's just sorting and it's a
tiny example, but to me it shows a lot about why I prefer C++ over C:
typesafety, readability, reduced possibility of buffer overflows, reduced
possibility of segfaults based on incorrect element access, speed thanks to
code inlining vs function pointers...

~~~
tptacek
I've coded in C since 1993, shipped commercial systems C code from 1996
through ~2004 (with an 3-year C++ interlude in there), and continued to write
C code on projects from then today. In that time, the number of bugs I've
dealt with due to the lack of type safety on a void* is: zero.

Lest you think I'm being cavalier about this, I've been writing professional
Ruby since ~2006, and have since then been routinely aggravated by bugs that
would have been mitigated by type safety. I buy type safety. But it's a
continuum of value, not a core principle of development.

In idiomatic C code, void* is a way of dropping in and out of static typing,
usually to pass values of arbitrary types to a generic container library or
through a callback. The use of void* doesn't surrender type safety throughout
the program. Idiomatic C code casts a specific type to void* at the call site
of the function that handles generic types, and casts it back to that specific
type the moment that library hands it back.

Of the arguments C++ devotees marshall against C, I find this one among the
fudliest.

~~~
yuushi
I guess we'll just have to agree to disagree then. Perhaps you are a far more
conscientious programmer than many out there; the number of buffer overflow
exploits would suggest so. C++ doesn't make you immune to such things, but it
does give you the tools to make such things less likely to occur. Further, I
like compiler-enforced type safety. For when C was created, utilization of
void* was a brilliant idea. Language design has moved on since then, and as
much as many people really hate template-based C++ code, I honestly welcome it
in comparison.

------
tikhonj
I've recently realized that--at least to me--C is actually very much like
Prolog. How? Well: Prolog is a fairly simple, Turing-complete language. For
the things it's good for, it's _great_. But those things are few and
relatively specialized. I _could_ use Prolog for general-purpose programming,
but I wouldn't want to. With Prolog, the question is always "why Prolog?"
rather than "why not Prolog?". Sometimes there is a good answer to this, but
usually there isn't. I can also get some of the benefit by using a DSL
embedded inside a more general-purpose high-level language.

I've thought this for a while, almost ever since I learned Prolog. Make no
mistake: I actually rather like Prolog. But I haven't been using it very much.
The recent revelation is that C has all the same characteristics. And in a
similar way, while I still like C to whatever extent, I'm going to avoid using
it unless I really have to.

On a mostly unrelated note, I agree that Rust looks very promising. It's the
new language that I'm the most excited about, especially after being let down
by Go. Also, I'm not quite sure why he thinks the Rust syntax is odd: to me it
seems extremely C-like, with some nice improvements (like implicit returns).

~~~
bcoates
Out of curiosity, what are you hoping to get out of Rust that Go let you down
on?

~~~
tikhonj
The best summary would be that I want a language to replace C++ but more sane
and functional. Go is more like a language to replace Java and is most
definitely _not_ functional.

Essentially, I don't see why I would ever use Go over Haskell or OCaml. The
main areas where Haskell and OCaml are ill-suited are the lower-level ones
currently dominated by C/C++ and Go does not seem to address those very well.
The main areas Go is doing well, like server-side code, are _very_ well suited
to Haskell and OCaml and so I have no reason to drop down to a less
declarative language like Go.

Rust, on the other hand, seems to be targeting C++ directly. It also doesn't
hate functional programming. So it perfectly fills the C/C++ shaped void in my
current toolbox.

~~~
jlgreco
Go is a language for young programmers who were perhaps brought up on Java or
Python, but have discovered the "cat -v" mentality and are drawn toward it.

Or alternatively, for old C programmers who are well versed in the 'cat -v'
mentality who have tasted a bit of Java and Python but simply cannot buy into
those.

~~~
krmboya
Correction. The "cat-v considered harmful" mentality.

------
DannoHung
Okay, say I'm gonna start using C more seriously: What library do I use for
strings? Not fucking arrays of 8 bit characters. Real Unicode compatible
strings with concatenation and comparison operations and all that good stuff.
And if it works with a regex engine, that's nice too.

~~~
geoka9
<http://site.icu-project.org/>

~~~
DannoHung
Hmmm....

> Strings are the most common and fundamental form of handling text in
> software. Logically, and often physically, they contain contiguous arrays
> (vectors) of basic units. Most of the ICU API functions work directly with
> simple strings, _and where possible, this is preferred_.

Nope.

Though the UText API was promising... unfortunately, it is totally incomplete.

------
robomartin
I remember what scared me to death with C++ when I was using it with frequency
was the potential to end-up with these horrible inheritance trees that could
really bungle a project in so many ways. If you didn't take the time to
really, really, really think through your class hierarchy you could really
shaft yourself in a big way. Bacause of this, as life went on I started to
really appreciate the idea of composition vs. inheritance.

For me C has always been an easy no-brainer go-to language to get things done,
particularly so when performance was at stake. I've always thought that
learning programming should start at the lowest possible level (yes,
assembly), then move on to Forth, C and from there ideally Lisp before hitting
Java for some OO love. With that kind of a foundation it's easy to learn and
absorb just-about anything that comes your way.

~~~
Someone
_"I remember what scared me to death with C++ when I was using it with
frequency was the potential to end-up with these horrible inheritance trees"_

I don't think you can blaim C++ for that. The time when 'we' hadn't learned
the "composition over inheritance" lesson yet just happened to coincide with
that of "let's write our framework in C++".

~~~
robomartin
Maybe so.

------
chj
My thoughts on why C is effective:

Simple. An average C programmer can easily learn 90% of the language and use
80% on a daily basis. So C programmers can understand each other generally
well. Although different projects usually have different styles, they are very
minor differences.

Assembler friendly. You can link C code and assembler together with negligible
overhead. Almost every performance demanding project has its busiest part
written in assembler. Even though sometimes C is lack of a certain construct
that you require, you can always implement it in assembler and connect it with
C code (longjmp as a good example). Using assembler may seem to be
contradictory to the first point, but remember only a handful of people need
to work at such a low level, other people just use the C interfaces.

Reusable. C has a huge set of robust and portable libraries. Their authors are
proven to be surprisingly disciplined.

However, we have to admit writing good C code is very hard. And I can see that
less and less people will use it going forward. Steve Jobs' "trucks and cars"
metaphor applies here too.

------
nnq
If they would keep putting the extra effort in debugging the Erlang VM C code,
the benefits of this debugging would be available to the entire community of
developers using Erlang. Now they are in their small corner of the world and
every bug they squash is just a bug of their project.

Overall it's worse for "the world" and better for them. This makes sense for
commercial software but it's weird when you think about an open-source
project. Just imagine if all the effort in porting Ruby/Lisp to Java/C++ or
similar translations for big projects would have been invested in improving
the VMs for these dynamic languages (yeah, most of these rewritten projects
didn't have experienced C guys, but the OP certainly has and is one). _Is bug-
fixing and hacking on compilers and VMs really that hard?_ (I never approached
these problems in practice because I've never had to scale something that hard
and squeeze that last drop of performance, so I'm really asking the question,
it's not rhetorical).

------
znmeb
I'm with you 1000% percent here. The only language I ever encountered that
could possibly have supplanted C was FORTH, and it was doomed by legions of
Unix-trained C programmers once the hardware got good enough to support C.

~~~
gnuvince
What about Pascal? Seems like a simple, block-based language with the same
functionality as C. Apparently, the only complaint against it is that its
users like to eat quiche.

~~~
sampo
_"What about Pascal?"_

The type system, and control flow structures, were more strict and allowed
less "abuse" (flexibility) than C. Strings were fixed-length arrays of chars,
which was also less flexible than strings in C. Also people felt the begin-end
block syntax less fashionable than C's {}.

Take a look at: <http://www.lysator.liu.se/c/bwk-on-pascal.html>

~~~
barrkel
BWK's rant on Pascal is about as relevant today as a critique of original C
(no prototypes, types defaulting to int, etc.).

In other respects (e.g. strong type safety) Pascal's approach "won", depending
on your perspective.

------
ufo
I noticed that he didn't mention using some higher level scripting language on
top of C. Is this an intentional omission?

~~~
ay
I think it is covered by this part:

"If a big problem was C code in Erlang, why would using more C be good?

Because it's easier to debug when you don't lose context between the
"application" layer and the lower level code. The big problem we've seen is
when C code is getting called from higher level code in the same process, we
lose all the debugging context between the higher level code and the
underlying C code."

OT: My personal best experience with interfacing a higher level language with
C from the debugging standpoint was a C+Lua combo, and even then it was far
from optimal.

~~~
sramsay
It's never optimal, and often, it's the source of truly infuriating bugs. Yet
for all that, people don't say, "Hey, let's skip the middle man and just call
libcurl or libxml or whatever _from C_. Because you know, these are _C
libraries._ "

I think they don't do that because they've been told a hundred thousand times
that C is for low-level bit fiddling, that manual memory management is
impossible, that it's tedious and difficult to write, that it's a "systems
language."

Honestly, if you haven't programmed in C since college, you should give it a
try -- especially if you're on Linux. The tooling and library ecosystem of C
is absolutely second to none, and there's an enormous community out there that
consists of some of the smartest programmers you will ever meet.

I agree with you about C+Lua. I also notice that people who seriously do that
are serious C hackers -- which, I suspect, is seldom the case with most users
of Python and Ruby.

~~~
betterunix
"The tooling and library ecosystem of C is absolutely second to none, and
there's an enormous community out there that consists of some of the smartest
programmers you will ever meet."

Conspicuously absent from this statement is, "the language features make you
more productive," or, "smart programmers using this language are doing things
people thought were impossible." The issue with C (and even more so with C++)
is that the language features almost always work against you.

~~~
sramsay
"smart programmers using this language are doing things people thought were
impossible."

I think the fact that a great number of new, hip, who'd-have-thought-it-was-
possible languages are written in C answers this one rather nicely. Not to
mention hip new databases, hip new web servers . . .

"the language features make you more productive"

I think it's precisely this claim that is being called into question. I daily
see new language features that strike me as literally marvelous. But when it
comes to those features actually leading to increased productivity -- well,
"ls /usr/bin" tells a different story about the productivity of people working
in this language.

~~~
betterunix
"I think the fact that a great number of new, hip, who'd-have-thought-it-was-
possible languages are written in C answers this one rather nicely"

It's worth noting that writing a new language is not really something people
think is "impossible." On the other hand, people take the languages that were
implemented in C, and do things that nobody else thinks is possible -- things
like logistics systems that save the military enough money in a few years to
pay for the decades of research leading up to those systems. Sure, C is hiding
underneath, but to claim that that means people are "doing things with C" is
kind of silly (especially since there is no particular advantage to writing
compilers or interpreters in C).

For what it's worth, this situation has been inverted: on Open Genera, there
was a C compiler written in Lisp, and what it really did was to generate Lisp
code from C code (i.e. it was "C-in-Lisp"). This had some interesting benefits
e.g. C programs had a garbage collector in that system (the same as the Lisp
garbage collector).

"when it comes to those features actually leading to increased productivity"

It is a matter of what you are doing. For example, I do a lot of work with
boolean circuits (related to secure two-party computation, i.e. "theoretical
crypto stuff"), and it is nice to be able to write something like the "x*y +
z" and have that become this:

    
    
      (lambda (x y z) (or (and x y) z))
    

In C, what do I get? The macro system is not powerful enough to write a simple
expression parser, I cannot overload operators, and there is no support for
lambda expressions anyway. So instead of just worrying about the expression
itself, what would happen in C (and I know this because at one time I was
trying to write this code in C) is that I would have to implement a C function
for each expression, spreading the code out and introducing new ways for
things to go wrong (a second issue is that the values are not actually simple
values; in C, this turns into a mess of pointers etc.). It is not that it is
impossible, but I can say this: I am doing more now than I would have been
doing in C, and I am not exactly new to writing C code (although the languages
I programmed the longest in was actually C++; I am still perfectly comfortable
with C, and to be honest I like C++ even less).

To be fair, this same argument applies to other high-level languages; Lisp is
not exactly unique anymore in being very expressive, and other languages have
things that Lisp is missing (like pattern matching, dependent types, etc.). My
point is not that Lisp will change everything, though there seems to be a
renewed interest in Lisp thanks to Clojure, but rather that high level
languages absolutely do have a benefit. I suppose for most people, the easiest
example is SQL: think about how you would write something as simple as an
inner-join query if you could only use C (and then compare that to SQL).

~~~
sramsay
_(especially since there is no particular advantage to writing compilers or
interpreters in C)._

Do you _really_ believe there's no particular advantage to writing a compiler
or an interpreter in C? Like, you could write it in Tcl or Perl or Ruby and it
wouldn't matter?

~~~
betterunix
I would not particularly want to write a compiler in Tcl, Perl, or Ruby; on
the other hand, if I were free to choose, I would pick Lisp, ML, or Haskell
over C for compiler writing any day. For what it is worth, I have written a
compiler in C and I have written one in Lisp, and doing it in Lisp was far
more pleasant.

------
StephenFalken
I like the way Alexander Stepanov, primary designer and implementer of the
_C++ Standard Template Library_ (STL), decribed the _C Programming Language_
in an interview:

"Let's consider now why C is a great language. It is commonly believed that C
is a hack which was successful because Unix was written in it. I disagree.
Over a long period of time computer architectures evolved, not because of some
clever people figuring how to evolve architectures---as a matter of fact,
clever people were pushing tagged architectures during that period of time---
but because of the demands of different programmers to solve real problems.
Computers that were able to deal just with numbers evolved into computers with
byte-addressable memory, flat address spaces, and pointers. This was a natural
evolution reflecting the growing set of problems that people were solving. C,
reflecting the genius of Dennis Ritchie, provided a minimal model of the
computer that had evolved over 30 years. C was not a quick hack. As computers
evolved to handle all kinds of problems, C, being the minimal model of such a
computer, became a very powerful language to solve all kinds of problems in
different domains very effectively. This is the secret of C's portability: it
is the best representation of an abstract computer that we have. Of course,
the abstraction is done over the set of real computers, not some imaginary
computational devices. Moreover, people could understand the machine model
behind C. It is much easier for an average engineer to understand the machine
model behind C than the machine model behind Ada or even Scheme. C succeeded
because it was doing the right thing, not because of AT&T promoting it or Unix
being written with it."

------
larsmak
I started out with Visual Basic about 10 years ago, as an introduction to
programming it did it's job well. I then moved on to C/C++ as I started my
MSCS. It was great for doing implementation of algorithms and image
processing. Working relatively low level, optimizing for speed and handling
garbage collection yourself.

As I started my professional carrer I went on to Java, and I've never looked
back. The environment is great - I know how to implement algoritms and
persistence-framework myself, but that's not what I'm getting paid for.
There's always some high quality open source library/framework I can use. And
sometimes when I need the "unreasonable effetiveness of C" I will interface
with one of it's applications via JNI, I've done this several times:
ImageMagick, ffmpeg, OpenCV, etc. I also onload a lot of the performance
critical tasks to systems written in C/C++ like MongoDB, Redis etc. But Java
can be fast as well, just ask Cassandra and Solr/Lucene.

Java allows me to get my job done, quickly and effectly. And to write well
structured, understandable code that most likely will be understandable in
decades to come.

------
mrb
Of course the C language and compilers are so simple, and C sits at such a low
level (right above assembly) that few things can go wrong in it (compiler bug)
or under it (cpu bug). As people jokingly say, C is just a high level assembly
language. If one tried to re-invent a language with C's properties, one would
come up with C, again.

For these reasons, I too expect C to remain the most performant and reliable
_high-level_ language baring any major change in computer architectures.

Debating this fact would be the same as debating whether assembly is the most
performant and reliable _low-level_ language or not. Of course it is.
(Preemptive reply to the doubter: as an example my 64-bit assembly
implementation of MD5 is 75% faster that a 64-bit C implementation:
<http://www.zorinaq.com/papers/md5-amd64.html> )

And of course, performance and reliability don't always need to be #1
priorities, therefore, as the author says, "most every popular language has
uses where it's a better choice."

~~~
jzwinck
Computer architecture has already changed, with today's PCs having many
logical processors. And indeed C lacks any direct affordance for parallelism.
Good old pthreads are hardly adequate for many tasks compared to facilities in
other languages. Yes, you can implement most of the needed features in C, but
often without the grace or safety available elsewhere.

~~~
pbsd
C11 adds thread and atomic op support:
<https://en.wikipedia.org/wiki/C11_%28C_standard_revision%29>

------
sutro
That is one hell of a résumé.

~~~
megrimlock
Definitely! Of course, argument from authority is still relatively weak in
situations where experts disagree, and that's definitely the case with
programming languages. We can each find our gurus -- Damien Katz, Rich Hickey,
Rob Pike, John Carmack, Mike Acton, Slava Pestov are some of mine -- but
there's no absolute truth in programming debates. The best we can hope for is
to share interesting insights, motivate them as clearly as we can, and then
agree to disagree, each biased by our distinct experience.

------
randomsearch
In academic circles, many struggle to understand why people are still using C
for large projects, other than the special cases of operating systems,
embedded systems, and code that must execute very quickly - e.g. within the
gaming industry.

The main argument against using C seems to be that C is at too low a level of
abstraction, which leads to low productivity and buggy code.

For example, pointer arithmetic might sometimes be useful, but it doesn't seem
like something most developers should be exposed to anymore.

I have some sympathy for this argument, but wonder what others think?

\- The right tool for the job?

RS

------
kenko
Interesting that among the other languages he mentioned one did not find
Fortran or ML, which, I believe, were the go-to examples of C-beating
languages in the discussion of the initial piece.

------
mimog
His argument now seems to be that you have to use C for speed. In my
experience that doesn't necessarily hold true anymore, given modern computer
architectures and what JIT compilers are capable of. I have several times
written something in a modern language and then convinced myself that I could
get a large speedup if I instead wrote it in C, only to discover that the
speed benefits were minimal at best and would require an exorbinant amount of
exquisite hand optimization to increase further.

------
dougk16
Can't really argue with anything specific here, but this and the last
article's general premise seems like, "if you have a choice, you might want to
go with C for these reasons...". The problem is, I can't remember the last
time I had any practical choice between C and a higher level language. I'd
love to use C more, but the decision is almost always made for me by a client,
or a useful framework/library that only exists in language X, or a platform,
or a boss.

------
marze
>I don't know a lot of what's out there on the horizon, and there are some
efforts to create a better C.

Are there any efforts to extend C to add very simple/light objects, and
perhaps string handling?

~~~
ripter
C++ and Objective-C started with this goal.

Objective-C started as a pre-processor for C.

~~~
npsimons
So did C++.

------
pjmlp
It is so funny in these debates to see people always mixing languages with
their default implementations, as if they were the only one available for the
language.

