"The Unreasonable Effectiveness of C" by Damien Katz

J

JohnF

Lynn McGuire said:
"The Unreasonable Effectiveness of C" by Damien Katz
http://damienkatz.net/2013/01/the_unreasonable_effectiveness_of_c.html

" It's because C is so damn successful as an
abstraction over the underlying machine and making
that high level, it's made most low level languages
irrelevant. C is that good at what it does."
Lynn

C is often called a "portable assembly language" (google that
phrase for lots of relevant hits). So this is all pretty
well-known stuff already.
 
L

Lynn McGuire

The author would probably disagree with the implications of such a
description.

That we have a hard time thinking of lower level languages we'd use
instead of C isn't because C is low level. It's because C is so damn
successful as an abstraction over the underlying machine and making
that high level, it's made most low level languages irrelevant. C is
that good at what it does.

I totally agree. C is an awesome abstraction
of all machine languages. C is awesome at
what it does.

Lynn
 
J

Jorgen Grahn

On 1/15/2013 12:44 AM, William Ahern wrote: ....

I totally agree. C is an awesome abstraction
of all machine languages.

Either that, or there's little chance of success if you create a
machine, no matter how good, if it cannot run C efficiently.

/Jorgen
 
G

glen herrmannsfeldt

(snip)
Either that, or there's little chance of success if you create a
machine, no matter how good, if it cannot run C efficiently.

For many years, that was true for Fortran. Maybe it still is.

For one, C allowed either of two possibilities when dividing
with negative numbers. Fortran allowed only one.

If any hardware generated the result that Fortran didn't allow,
it would have been less efficient for Fortran, and might not
have sold as well.

Also, my always favorite example is segment selector zero for protected
mode on the 80286 and later intel processors.

-- glen
 
E

Edward A. Falk

C is often called a "portable assembly language" (google that
phrase for lots of relevant hits). So this is all pretty
well-known stuff already.

That's how it was described to me when I first heard of it --
a high-level language with the power of assembly language. I
was pretty skeptical at first.
 
B

BartC

Lynn McGuire said:
"The Unreasonable Effectiveness of C" by Damien Katz
http://damienkatz.net/2013/01/the_unreasonable_effectiveness_of_c.html

" It's because C is so damn successful as an
abstraction over the underlying machine and making
that high level, it's made most low level languages
irrelevant. C is that good at what it does."

"Callable from Anywhere

C has a standardized application binary interface (ABI) that is supported by
every OS, language and platform in existence."

Been carried away a bit by his own enthusiasm I think..
 
L

Lynn McGuire

(snip)

For many years, that was true for Fortran. Maybe it still is.

For one, C allowed either of two possibilities when dividing
with negative numbers. Fortran allowed only one.

If any hardware generated the result that Fortran didn't allow,
it would have been less efficient for Fortran, and might not
have sold as well.

Also, my always favorite example is segment selector zero for protected
mode on the 80286 and later intel processors.

-- glen

Many of the PLC machines do not have a fortran
(4, 77, 90, 95, 2003, etc) compiler. You have
to translate your code to c using f2c (crap) or
for_c (a purchase tool).

Lynn
 
L

Lynn McGuire

The author would probably disagree with the implications of such a
description.

That we have a hard time thinking of lower level languages we'd use
instead of C isn't because C is low level. It's because C is so damn
successful as an abstraction over the underlying machine and making
that high level, it's made most low level languages irrelevant. C is
that good at what it does.

I find it amazing that C works well on both
non-stack and stack machines. OF course, so
does Fortran but it has it's own many
peculiarities and failings.

Lynn
 
M

Mel Smith

Damien Katz replied to me:

"Thanks for the feedback. Languages that compile down to C are very
portable. Cool! "

(in response to my email to him several days ago about the Harbour language
(or Hi-C) )

-Mel Smith
 
A

Andrey Tarasevich

C is often called a "portable assembly language" (google that
phrase for lots of relevant hits). So this is all pretty
well-known stuff already.

While it is generally true, the actual meaning of that characterization
is not exactly unambiguous.

C language was true "portable assembler" - i.e. a tool for directly
expressing the programmer's intent in near-machine language - mostly in
its nascent stages, as described in "C Reference Manual" and the first
edition of "C Programming Language". That was indeed a true "assembler".

The standardized C was considerably reworked and became more abstracted
from the actual machines. In many cases when one refers to it as a
"portable assembler" in the above sense of the term, it usually means
that one simply lacks proper understanding of the true abstraction level
built into the language features.

Yet, standardized C retained the crown of "portable assembler" in a
different meaning of the term: it works rather well as a back end
representation for various higher-level language translators, i.e.
instead of translating the higher-level source into assembler it often
makes much more sense to translate them into C.
 
B

BartC

Andrey Tarasevich said:
On 1/14/2013 9:02 PM, JohnF wrote:
Yet, standardized C retained the crown of "portable assembler" in a
different meaning of the term: it works rather well as a back end
representation for various higher-level language translators, i.e. instead
of translating the higher-level source into assembler it often makes much
more sense to translate them into C.

I've never had much luck using C as a target language. Some aspects of C are
just not quite low-level enough and there can be many constructions, partly
depending on the source language, not easily expressible in C but trivial in
actual assembler.

There are advantages: the result is more portable, and you can take
advantage of a good optimising C compiler to make your job easier. But there
are some downsides too apart from the ones I've mentioned: having this extra
dependency on a C compiler system for example.

Directly programming in assembly is like setting things in concrete compared
with using any higher level language, so that is rarely the best approach.
But generating assembly code indirectly is not quite as bad as that.
 
G

glen herrmannsfeldt

Andrey Tarasevich said:
On 1/14/2013 9:02 PM, JohnF wrote:
(snip)
While it is generally true, the actual meaning of that
characterization is not exactly unambiguous.
C language was true "portable assembler" - i.e. a tool for directly
expressing the programmer's intent in near-machine language - mostly in
its nascent stages, as described in "C Reference Manual" and the first
edition of "C Programming Language". That was indeed a true "assembler".
The standardized C was considerably reworked and became more abstracted
from the actual machines. In many cases when one refers to it as a
"portable assembler" in the above sense of the term, it usually means
that one simply lacks proper understanding of the true abstraction level
built into the language features.

Yes it is more abstract, but if you are careful with what opeations
you use, then you are still pretty close.

But most good high-level langauges now include array operations.

You can say a=b+c; where a, b, and c are arrays (of any rank)
with appropriate dimensions, and it will add them element by element.

C still does not have array operations, and with the way C uses
pointers, it isn't so easy to see how to add them.
Yet, standardized C retained the crown of "portable assembler" in a
different meaning of the term: it works rather well as a back end
representation for various higher-level language translators, i.e.
instead of translating the higher-level source into assembler it often
makes much more sense to translate them into C.

Much of the time, you can figure out exactly, or close enough, what
assembler code would be generated. (And the register allocation
is probably better than most assembler programmers would do.)

-- glen
 
L

Lynn McGuire

Yes it is more abstract, but if you are careful with what opeations
you use, then you are still pretty close.

But most good high-level langauges now include array operations.

You can say a=b+c; where a, b, and c are arrays (of any rank)
with appropriate dimensions, and it will add them element by element.

C still does not have array operations, and with the way C uses
pointers, it isn't so easy to see how to add them.


Much of the time, you can figure out exactly, or close enough, what
assembler code would be generated. (And the register allocation
is probably better than most assembler programmers would do.)

-- glen

How about the third party array operations in
OpenCL and CUDA ?

Lynn
 
B

BGB

Either that, or there's little chance of success if you create a
machine, no matter how good, if it cannot run C efficiently.

yeah...

elsewhere on Usenet, there is an argument about machines using
fat-pointers and tagged memory (say, where pointers are 128 bits wide,
array accesses are bounds-checked, and every 64-bits of memory has 8
bits of tag-data, ...).

oddly enough, they never really caught on.
 
B

BGB

No true Scotsman? I use many high-level languages, and none of them have
native support for vector operations. I did use R a few years ago to
validate some C code, I suppose. GCC has built-in vector extensions for C,
but they're only for single dimensions.

I have seen hardly any languages which allow adding arrays in this way.

I have actually seen more which will interpret this as meaning you want
to append the arrays into a single bigger array.

others will just be like "what?...".

Some languages make it easier than others to compose vector libraries, of
course. C appears to be taking a different tack, which is tweaking the
language specification to make it easier for the compiler to auto-vectorize
loops.

it also depends some on what exactly one means by "vector".

for example, many of my languages include built-in vectors, in roughly
the same sense as GLSL, where they come in a variety of forms:
vec2, vec3, vec4, quat (vectors, float);
vec2d, vec3d, vec4d, quatd (vectors, double).

and generally support operations like add/subtract, dot-product,
cross-product, ... with quat/quatd being slightly special (being
quaternions and all), ...


but, some other people seem to use "vector" more in the sense of "array
of indeterminate size which you do math on", others, as a synonym for
"array" (holding pretty much anything, and dropping the sense of doing
math on it), or go as far to use the term "vector" to refer to a bunch
of copies of a program running in-parallel, in the sense of how shaders
are executed on the GPU, ...

it gets ambiguous sometimes...
 
B

BGB

The ABI isn't standardized across platforms, but on each platform the C ABI
is more-or-less the prototype for the ABI of other compiled languages. Even
JVMs usually have to grok the local platform's C ABI. Thus, most languages
have some sort of native mechanism for interoperating with C, with varying
degress of convenience but alwa well defined.

Often, of course, the C "ABI" interoperability is a side-effect of the fact
that the language is implemented in C. Example: Perl or PHP.

yeah, my own language also uses the C ABI in this sense, at least for
external calls.

my past (long-since dead) native code-generator also used a slightly
modified C ABI, mostly in that it was modified to sometimes behave more
like "thiscall" and with its own funky name mangling.


also on Linux x86-64, the ABI is also slightly modified in that I am too
lazy to bother to correctly implementing struct passing (because the
rules are IMO kind of absurd), so I am using a simplified set of rules:
if the struct can be passed in a single register (eg: RDX or XMM0) it
will do so;
otherwise, it will just pass/return it via a reference, and call it good
enough.

the difference is mostly regarding non-trivial structs which the ABI
specifies decomposing and passing in multiple registers, which I am just
not going to bother with.

nevermind if SysV/AMD64 is one of my more disliked ABIs.
it is almost like they set out to make it overly complicated and a pain
to implement support for or something...
 
B

BartC

BGB said:
But most good high-level langauges now include array operations.
[You can say a=b+c; where a, b, and c are arrays (of any rank)]
No true Scotsman? I use many high-level languages, and none of them have
native support for vector operations. I did use R a few years ago to
validate some C code, I suppose. GCC has built-in vector extensions for
C,
but they're only for single dimensions.

I have seen hardly any languages which allow adding arrays in this way.

It's not really that meaningful, except where you build a more specific type
based on 'array', designed for mathematical work.

But if the language allows it, then it would quite likely be to allow list
operations in general, so that in a = b op c, then 'op' is applied between
all corresponding elements (as in languages such as "K", but without quite
such an obvious syntax...)
I have actually seen more which will interpret this as meaning you want to
append the arrays into a single bigger array.

That's far more useful. But better to use a symbol other than "+" I think.
 
N

Nobody

APL and IDL are the only two I know of, though there are probably others.

C++ has std::valarray. Python has NumPy (although it's not actually part
of the standard library).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top