Please. No exceptions is huge. No garbage collection is huge.
You have over-trimmed and lost context. The context here is that I
maintain that one of the reasons for inventing new languages is to
provide useful programming idioms and techniques in a convenient, clean
way, that is, with syntactic support and a minimum of needless
boilerplate. You have objected to this view, and (if I understand you
correctly) believe that there are certain idioms which are *impossible*
in C, hence the invention of new languages.
I agree with you that garbage collection and exceptions are useful,
powerful features. I agree with you that the difference between a
language which supports them natively (like Python) and one which does
not (like C) is huge. But beyond that I think you are mistaken.
C does not natively provide garbage collection, or exceptions, or many
other features. But that doesn't make it *impossible* to use these
features in C, it just makes them *inconvenient and difficult*. To get
the advantage of such features, you have to build a framework that
provides them, then exclusively use the framework, while avoiding
dropping down into the underlying low-level C features that bypass the
framework. This is inconvenient, error-prone, inelegant, and requires
discipline, but it is *possible*.
Take the framework to the next level: add custom syntax, a parser, and a
system for translating your custom syntax to (say) C, or machine code for
some (real or virtual) machine. We call this *a programming language*.
But that's just an incremental step beyond a framework, which in turn is
just an incremental step beyond a library, which in turn is just an
incremental step beyond an ad hoc system of useful wrapper functions and
conventions.
In a very real sense, Python is "just" a convenience wrapper around a
bunch of C functions to provide OOP idioms, garbage collection, dynamic
typing, runtime introspection, exceptions, and similar.
But you can do anything with a Turing machine. You can do anything in
assembly. The point is to pick the appropriate tool for the job.
I agree! And building those tools is one of the reasons why people create
new programming languages: to make useful techniques and idioms easier to
use.
I can build a house without a nail gun. I can probably even build a
house without a hammer. But it's a waste of time to build things with
the wrong tools.
I don't think the right analogy is with the nail gun versus hammer. Both
result in the same finished product: two pieces of timber joined together
with one or more pointy bits of steel. Sure, a nail gun is faster and
easier, but the idiom is the same.
A better analogy is to consider the various ways to assemble timber:
nails, screws, glue, dowels, biscuits, dovetail joints, etc. These are
all *idioms and techniques* for getting the same result (two pieces of
wood joined), rather than different tools for performing the same idiom
(drive a nail using a nail gun, a hammer or a rock). Each idiom has
different pros and cons: biscuits are good for joining chipwood edge-to-
edge, but lousy for load bearing structural timbers.
Like all analogies, it doesn't pay to take it too far, but essentially
you can think of a language like Python as being like a machine shop with
a dedicated biscuit joiner, while C is like one without such a device.
You can use the same technique in both, but the ease of use, convenience
and reliability is quite different:
* In Python, you use the biscuit joiner to quickly cut out a matching,
nicely machined slot in both pieces of chipboard.
* In C, you have to manually and carefully drill out many thin holes in
the chipboard, then laboriously cut through to make a slot, then file
smooth by hand. Not only is this much more work, but the end result is
likely to be less reliable.
For anyone who has no idea what I'm talking about when I talk about
biscuit joiners:
http://en.wikipedia.org/wiki/Biscuit_joiner