Live data from Hacker News

The Unreasonable Effectiveness of C

damienkatz.net

321–330 of 394 posts

Re: The Unreasonable Effectiveness of C

#321

Earlier quoted context omitted.

And so this buy-in occurs at the library level rather than the language level. One might see that as a good thing.

Those people would be wrong. When buy-in occurs at the library level, then the de-facto response is to fall back to the lowest common denominator, whatever that happens to be. In a language with standard containers, that lowest common denominator is a reasonable floor. Having containers in the standard library has basically zero downside aside from some perceived conceptual elegance. People who need custom containers…

I agree with this so much. A few years ago I realized that my C code wasn't longer or harder to reason about than most higher-level languages (yes, that factors in the memory management and even error checking), except for one thing: those languages came with built-in resizable arrays and hash tables.

I was grossly disappointed when the C11 revision had nothing about some default algorithm implementations in the standard library. If a C hacker needs something more specialized than those default containers, they can go write their own (they would have anyway), but for the rest of us it allows getting something reasonable off the ground relatively quickly.

APR and Glib are nice in theory, but most software shouldn't require such dependencies. Also, every C hacker I've spoken to has a different opinion about the quality and usefulness of those two libraries; most dislike the two.

Re: The Unreasonable Effectiveness of C

#322

Earlier quoted context omitted.

> A stack with C at the bottom You realize C is not at the bottom of the stack, right? > Why do you suppose that no serious VMs or language runtimes are written in Haskell (or other functional languages)? Because Lisp Machines didn't win. > plenty of systems implemented in C define models in which none of what you mentioned is true True, but that's the whole point of abstraction. C, in turn, gets rid of some of the "…

> 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?

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.

JavaScript would run faster then it does on Von Nuemman machines because it would use the hardware support for dynamic languages and since JavaScript runs in a browser independently of the OS, the new machine architecture and OS wouldn't be a problem. Haskell, in so far as its purely functional, would probably run the same as it does now.

Re: The Unreasonable Effectiveness of C

#323
post #47

Earlier quoted context omitted.

It may be cumbersome, but C has string handling: http://en.wikipedia.org/wiki/C_string_handling

This is an article about the standard library. C has no built in string handling. As an example, there are embedded systems that do no have support for string types due to a lack of support for libraries that handle it, yet they are 100% compliant with the C spec.

The C standard library is specified as part of the language specification document. The language defines two kinds of implementations: "hosted", which must support the entire standard library; and "freestanding", which do not.

Those embedded systems that do not support the full standard library are 100% compliant freestanding implementations, but are not compliant hosted implementations.

Re: The Unreasonable Effectiveness of C

#324

Earlier quoted context omitted.

Here's the thing: "high-level", when applied to a programming language, has a historical context. It means something specific (see: http://en.wikipedia.org/wiki/High-level_programming_language ), and what it means and has always meant is that the language in question abstracts away registers and allows structured programming (as in, through the use of if, while, switch, for, as opposed to using labels and branching).…

Under that classification, what is a low level language then? Even Forth abstracts away registers, and allows structured programming (or a sort). Is the set of low level languages that people have heard of in 2013 an empty set?

"Heard of", maybe not. But "working with" I can believe. A friend of mine was writing an assembler with a built-in arithmetic expression syntax last year.

Clearly it was low-level, because it wasn't trying to abstract away hardware - but it also wasn't just a straight-up (macro) assembly language, since it provided some specific features that needed a more sophisticated compiler to work properly.

When we speak of low-level coding, almost any abstraction can constitute a huge jump in power from the machine language.

Re: The Unreasonable Effectiveness of C

#325

Earlier quoted context omitted.

And can't be _implemented_ in any language. C gives you at least the charming fact that you can implement one without any overhead of objects, classes, implicit memory management or some other concept, just having a lightweight implementation that you may use in an environment without any libraries, like std or else..

So what you're saying is that C lets you write it on your own. In fact, and this might sound crazy, but you can do that exact same thing in C++, it's just that people don't because the C++ standard library provides plenty of performant and featureful data structures for you. Besides, anything the C++ standard template library map does when implementing a red-black tree is exactly what you would need to do if you wrot…

You do not need to cast to or from `void *` in C, and it's not idiomatic to do so.

Re: The Unreasonable Effectiveness of C

#326

Earlier quoted context omitted.

> A stack with C at the bottom You realize C is not at the bottom of the stack, right? > Why do you suppose that no serious VMs or language runtimes are written in Haskell (or other functional languages)? Because Lisp Machines didn't win. > plenty of systems implemented in C define models in which none of what you mentioned is true True, but that's the whole point of abstraction. C, in turn, gets rid of some of the "…

> 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.

Re: The Unreasonable Effectiveness of C

#327
post #3

To nitpick on a single statement: > C has the fastest development interactivity of any mainstream statically typed language. What? Despite all its shortcomings, Java in a modern IDE effectively has zero build time. The level of interactivity is as fast as that of interpreted languages. I haven't seen anyone manage this with C yet.

C and Java both have terrible productivity loops because they have a tedious compile step. Python you just run after editing. I was more productive in python using a test editor the very first week I learnt it than I ever was in Java or C++ even with IDE support and years of experience. Google App Engine python dev server reloads modified python files whithout server restart . That feature blew my mind after doing Ja…

Having a REPL is a big productivity boost for Python, not avoiding an explicit compile step. A compile step is utterly trivial to avoid (e.g. "make run" which builds and runs). Likewise, live reloading is possible in C using dlopen().

Re: The Unreasonable Effectiveness of C

#328

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…

Is there any way for software, even in assembly, to make intelligent use of on-cpu ram caches? I thought they were completely abstracted by the hardware.

Well, I am not as well-versed in optimization, but there is this:

https://en.wikipedia.org/wiki/Cache_timing_attack

If you can exploit the effect that cache has on latency, it is reasonable to assume that you can manipulate it in other ways.

Re: The Unreasonable Effectiveness of C

#329
post #63

I feel like I'm always trying to make this point to people, and doing so with far less eloquence. The fact that Katz is (a) an experienced and accomplished developer and (b) someone with very non-trivial experience with hot, hip, super-high-level languages should not go unnoticed. He's not some cranky old embedded systems programmer; he's doing thoroughly modern development. Someone the other day said that the great…

Can you give me an example of a problem in Haskell, where the abstractions are so complicated you can't get your head around it, but putting it back in C makes it easy enough to deal with? A more plausible explanation is that you wouldn't even attempt a similar design in C because it'd be obviously impossible.

An industrial operating system. In C, you know what you've got: its exact dimensions, location, and lifetime. Since you're not relying on a GC, you can make latency more predictable and with much lower upper bounds.

On that topic, I'd rather write crypto code in C too.

Re: The Unreasonable Effectiveness of C

#330
post #159

Earlier quoted context omitted.

Given the way that LLVM has come onto the scene, I'm not sure I'd agree. C defines assumptions in the programming environment and does not guarantee that it at all resembles the underlying hardware. You are never coding to the hardware (unless you are doing heinous magic), you're coding to C. That's a "virtual machine" to me. The concept of C as a virtual machine isn't new (I first heard it around 2006 or so? I don't…

It's more descriptive, but somewhat incorrect. The common definition of a process virtual machine is that it's an interpreter that can be written to that essentially emulates an OS environment, giving abstracted OS concepts and functionality. This aids with portability. Another concept of virtual machines in general is, for lack of a better term, sandboxing. You're limited to only the functionality that the VM provid…

"The common definition of a process virtual machine is that it's an interpreter that can be written to that essentially emulates an OS environment, giving abstracted OS concepts and functionality."

Is it? I have seen "virtual machine" used to describe the process abstraction and to describe the IR in compilers (hence "Java Virtual Machine"), and to describe the Forth environment (similar to compilers).

Post reply on HN