Live data from Hacker News

The Unreasonable Effectiveness of C

damienkatz.net

351–360 of 394 posts

Re: The Unreasonable Effectiveness of C

#351

Earlier quoted context omitted.

If you are using macros in C++, you are doing it wrong. They are a relic of a bygone age.

Thanks for letting me know, I try to use the macros as little as possible, but there are such things as platform-specific code, compiler differences, third-party libraries, standard libraries such as WinAPI and legacy code.

Platform-specific code is a very good use that precluded me at 1 o'clock this morning.

I tend to wrap legacy code in a C++ wrapper if I can; allowing me to code to a C++ idiomed API, rather than the choice of that particular developer. More often than not, it adds no overhead through the use of inlined functions...

Re: The Unreasonable Effectiveness of C

#353

Oh for heavens' sakes. Yet more ignorance. A more realistic view of C: - C is straightforward to compile into fast machine code...on a PDP-11. Its virtual machine does not match modern architectures very well, and its explicitness about details of its machine mean FORTRAN compilers typically produce faster code. The C virtual machine does not provide an accurate model of why your code is fast on a modern machine. The…

> - C is straightforward to compile into fast machine code...on a PDP-11. Its virtual machine does not match modern architectures very well, and its explicitness about details of its machine mean FORTRAN compilers typically produce faster code...

Nothing is straightforward to compile in to efficient machine code, and FORTRAN is not at all easier than C. Many compilers (e.g. GCC) use the same back-end for FORTRAN, C and other source languages. FORTRAN's clumsy arrays are a little nicer to the compiler than C's flexible pointers but the "restrict" keyword solves this.

> - C's tooling is hardly something to brag about, especially compared to its contemporaries like Smalltalk and Lisp. Most of the debuggers people use with C are command line monstrosities.

Yes, C debuggers may be a little clumsy compared to modern source level debuggers. But you can plug gdb in to almost anything, from a regular user space application, a microcontroller chip like Arduino, a kernel image running in QEMU, remotely debug Win32 code on Linux, a live CPU with a debugger dongle, etc.

> - Claiming a fast build/debug/run cycle for C is sad. It seems fast because of the failure in this area of C++. Go look at Turbo Pascal if you want to know how to make the build/debug/run cycle fast.

What's the point in compiling slow code quickly? Turbo Pascal was not really a good compiler, especially if you'd compare the output to a modern compiler.

Also take a look at the progress going on with LLVM/Clang/LLDB, they're working on better debugging and REPL-like environments for C.

Re: The Unreasonable Effectiveness of C

#354
post #348

Earlier quoted context omitted.

Here's one I used in a GC implementation a while back. That last 'uint_8t obj[]' is used to hold the object that was actually allocated. struct meta_obj { meta_obj_type *next; // next object in our list mark_type mark; size_t size; gc_type_def type_def; uint8_t obj[]; // contained object }; Or another (contrived) example: struct obj_type { obj_type_enum type; }; struct string_obj_type { obj_type_enum type; char *c; }…

Is this standard? I mean the unknown size field 'obj'.

It was added to the C99 standard.

Re: The Unreasonable Effectiveness of C

#355

Earlier quoted context omitted.

C is the language that doesn't force any preconceived notions about how the world should work onto you. ... except for a type system based on the memory model of a machine which strongly resembles the PDP-11, a compilation strategy built for machines with less RAM than my car fob, and optimization possibilities limited by aliasing, plus everything kscaldef mentioned.

> except for a type system based on the memory model of a machine which strongly resembles the PDP-11 I'm interested in hearing about alternative memory models that are an improvement; every one I hear about is specific to some higher-level language or programming paradigm. Baking high-level language concepts into hardware is basically asking for stagnation. > a compilation strategy built for machines with less RAM t…

> I'm interested in hearing about alternative memory models that are an improvement;

Intel 80286 introduced segmented protected mode where you had the option of placing each of programs objects (struct, array, string, even a single variable, if necessary!) into its own segment described by privilege access level (0-3, RO or RW) and length. So you had hardware-based array length checking. Access an out-of-bounds index, BOOM - segfault!

This is actually not incompatible with C's memory model (it requires that only individual objects be stored in contiguous memory blocks), but is incompatible with how most C programs were written at the time so it never caught on.

Also, you had to distinguish between "near" and "far" pointers, there were few segment registers, etc. But had Intel developed segmentation further, and had C programmers adapted, we could have ended up in the world where you could run programs with performance of C and safety of Java.

Re: The Unreasonable Effectiveness of C

#356
post #322

Earlier quoted context omitted.

C is built to run on a MASOS (multiple address space operating system) like UNIX so it wouldn't run as fast on a system like the Lisp machines that uses a single address space. Many of the things C deals with like the file system and interprocess communication would be obsolete in a system with single address space orthogonal persistence. Running C on a Lisp machine will be possible but at a performance cost. JavaScr…

> C is built to run on a MASOS (multiple address space operating system) What? You can run C on machines without a MMU, without an OS, or even to implement an OS. > Many of the things C deals with like the file system and interprocess communication would be obsolete in a system with single address space orthogonal persistence. What if people want a filesystem? They can't have one because the machine designer liked "s…

> What?

The principal application of C was to build the UNIX MASOS. C gained popularity on UNIX systems because they already had support for the language. The vast majority of C programs use UNIX features that will be obsolete on a SASOS, so running these C programs will come at a performance cost.

> You can run C on machines without a MMU, without an OS, or even to implement an OS.

In my previous post I was referring to C programs which include C standard library files such as stdio.h which will be obsolete because it uses the file system and signal.h which is used for IPC. If a C program uses any header files at all it is obsolete because it should be using functions rather then files as its unit of composition.

> What if people want a filesystem?

As persistent data (data that is independent of the lifetime of the program) is always mapped to a single global virtual address space in SASOS, there will be no need to have a file system. A file system interface can be provided, but it will be just another way of accessing virtual memory.

> They can't have one because the machine designer liked "single address space orthogonal persistence" better?

Although eliminating file systems will be enormously advantageous to developers, it will also be equally advantageous to users. Whenever a user of a UNIX system changes an object that user has to save those changes, usually by clicking File/Save in a drop down menubar. An orthogonally persistent system will be more accessible to ordinary users because they won't have to handle the details of saving data to the file system.

The user interface expert, Jef Raskins, set out to design a user interface based upon the needs of the user rather then from the needs of software, hardware, or marketing. The product of this search was Archy which is an orthogonally persistent system.

The hierarchical nature of modern file systems also isn't ideal from a user interface design perspective. Forcing users to fit their data into a hierarchy is problematic. Using tagging and search will arguably make for an easier to use interface then a file system.

> Just because a language is "dynamic" doesn't mean it can take advantage of generic "hardware support for dynamic languages" to be as fast as highly sophisticated and language-specific VMs like V8 or IonMonkey.

The V8 virtual machine is implemented with a high degree of sophistication so that it can run large JavaScript programs. There will be no need to waste memory storing such a sophisticated VM in a Lisp machine because all large programs will be written in Lisp instead. JavaScript will only be used for small scripts in web pages, ensuring that users won't fall into the JavaScript trap. In this sense, JavaScript may run somewhat slower without a sophisticated VM, but that performance difference will be irrelevant because the language will only be used for small scripts.

http://www.gnu.org/philosophy/javascript-trap.html

Re: The Unreasonable Effectiveness of C

#358
post #285

Earlier quoted context omitted.

Seriously? Actual production code in ALGOL in 2013? If I ever had to deal with that code, I think I'd feel about like you would have if I wrote this comment in Aramaic because I prefer it to English on numerous grounds. I'd very much prefer the extremely unpopular Racket which is at least alive to some degree. I think the author's criteria for "effectiveness" are very much different from yours, hence the different co…

You might enjoy this link ;) http://cowlark.com/2009-11-15-go/

I've read this comparison between Go and ALGOL-68, and I did enjoy it. Here are quotes from it that explain the difference between "good" and "effective" - exactly the point that I was making here (the article we're discussing claiming that C is effective, not that it is good in whatever sense):

"So why am I comparing Go with a language 41 years older? Because Go is not a good language."

But...

"I'm not suggesting that everyone drop Go and switch to Algol-68. There's a big difference between a good programming language and an effective programming language. Just look at Java. Go has a modern compiler, proper tools, libraries, a development community, and people wanting to use it. Algol-68 has none of these. I could use Go to get proper work done; I probably couldn't in Algol-68. Go is effective in a way that Algol-68 isn't."

Note that the author of a parent comment actually claimed to prefer ALGOL-68 to C for writing production code today, in practice.

Re: The Unreasonable Effectiveness of C

#359
post #326

Earlier quoted context omitted.

> Because Lisp Machines didn't win. And if Lisp Machines had won, do you really think they'd run JavaScript, Erlang, C, and Haskell (as a rough sample) as fast as our Von Neumann machines do today?

They would because Lisp Machines were not some magical functional machines but pretty much standard CPU designs of their era with additional hardware support for object memory (tagged pointers, GC...) and relatively large word size.

Modern computer operating systems are systems of bloat. The amount of duplication between programming languages like C, C++, Objective C, C#, Java, JavaScript, Perl, Python, and Ruby, user programs, and applications is immense. To have a streamlined system that uses a single language all the way down to the machine itself, and that makes full use of the sharing capabilities of a single address space, would be truly magical!

Re: The Unreasonable Effectiveness of C

#360
post #24

"But amazingly it's proven much more predictable when we'll hit issues and how to debug and fix them. In the long run, it's more productive." That's nothing to do with C. It's because Damien worked on CouchDB first, and learned a lot from that. If I were to go and rewrite our current system in Java or Scala, I'd also be able to predict where performance, and other, issues would crop up, simply because I've already en…

"It wasn't, it was a race condition bug in core Erlang. We only found the problem via code inspection of Erlang. This is a fundamental problem in any language that abstracts away too much of the computer."

Another way to look at this is that all languages which offer poor abstractions force you to write more code, by definition. Up front you will have to write much more code, but when the inevitable bug comes up, you will have the luxury of debugging code you authored. For some individuals and teams, this trade-off is a sensible one.

Post reply on HN