3 ms·
The Lisp Curse essay is an interesting read. I don't think I agree with its basic conclusion that language flexibility leads to a kind of social problem akin t
by mattarm 6y ago
The Lisp Curse essay is an interesting read.
I don't think I agree with its basic conclusion that language flexibility leads to a kind of social problem akin to a "curse."
From what I've seen over my career, both C and C++, which the essay claims are not cursed, have many libraries that don't interoperate well, re-invent wheels, are under documented, solve only part of a problem, and are basically solo/hobby efforts. In every job, the first thing I have to learn is how I'm allowed to write C or C++ at the company, since each provides such a huge surface.
The difference between C/C++ and Lisp/D is, I think, not language flexibility. They are all incredibly complex and flexible languages in their own way. The difference is funding and critical mass. C and C++ persist because companies pay people to use them and to improve them. Or, in terms of the curse essay, companies pay people to cooperate. The result is an enduring dominance. Those languages work better because more people use and improve them, so they stay relevant. Neither Lisp nor D seem to benefit significantly from that, so you have what is left: people without the time or interest in producing truly polished solutions.
- kazinator 6y agoC came from the Unix environment, gained momentum in the 1980's. The 1980's was a time when microcomputers exploded. Unfortunately, these microcomputers only had the memory and CPU power of big iron from 25 years before that. The best applications and games for these machines were written by assembly language wizards. The C language played right into that. C came from an environment of "mid-grade iron" from about ten years before that. It was developed for the efficient programming of machines that Unix ran on, which were roughly similar in power to the consumer-grade microcomputers of the 1980's. There were tools like Pascal and Modula also, but C came shrouded with a naive mystique thanks to its cryptic syntax, reputation for bending to the programmer, and creds due to its Unix connection. Naive programmers believed that expressions like i++ were faster than i := i + 1, or else, in any case, they liked it better. Moreover, in some situations, an expression stuffed with side effects in C would actually generate better code than less densely coded equivalent (the only equivalent available in a Pascal family language), due to the limitations of compiler capability. Coders whose ego was built on writing big programs in assembly language and getting them debugged were less threatened by a cryptic language in which you could write programs that were hard to understand, and those used to macro assemblers would also have liked the preprocessor. The ability to abuse the language to get the compiler to do what you want also would have helped. "C gets out of the way so you can get the machine to do what you mean (unlike those other things from the Wirthian family). Before there was an ANSI standard, that would have applied double. The printf function with its format strings also blew away Pascal and Fortran. On the latter point, I started to learn C at about the same time I enrolled in engineering. There was a mandatory Fortran course in the engineering curriculum. In one of the assignments, I wanted the Fortran program to have numeric output with dynamic column widths. It was really difficult; I can't remember whether I even got it working. I also remember the issue that Fortran's output would replace a fixed field with * characters when the value would not fit, instead of just expanding it. A few months later when I was learning C, I made it a point to try to do that with printf. Wow, I was easily able to do that. I was thinking, why would anyone use Fortran for number crunching if we have C?
- crazypython 6y agoC became popular because it's easy to implement– the syntax is easy to write a compiler for.
- glouwbug 6y agoIt really isn't... The grammar isn't formal. For instance: person * me; Is this a multiplication statement, or a pointer to a person typedef?
- kazinator 6y agoBut that's the easy part of writing a compiler anyway. All we do is, right in the lexical analyzer (not ever the parser) look up the person identifier in the table of declared identifiers in the current scope. It then returns the identifier as a type-identifier, object-identifier or undeclared-identifier. These are then referenced in the grammar phrase structure rules as necessary. I think there was an aspect of writing a C compiler that was easier, which was namely that certain optimizations in C were just left to the programmer. To get good code out of C, you depended on the basics, like decent instruction selection and peephole optimization, and jump-threading, and maybe elimination of dead code. Then to otherwise get good code out of C, you stuffed multiple side effects into a single expression, which allowed the compiler the generate the computation and storage accesses any order without analyzing whether any particular order is correct (ensuring they are all correct was left to the programmer, who often didn't care as long as the one compiler he or she were using gave them the right results). Even the assignment of local variables to registers was programmer-hinted: C had the (now deprecated) register keyword. With the register keyword, your compiler just had to place those variables in registers which were marked with it, and screw the rest. No analysis about which ones should be in registers: particularly good in register-starved architectures. The microcomputer world was characterized mainly by register-starved architectures, with the notable exception of the Motorola 68K series.
- kazinator 6y agoC is no easier to write a compiler for than Modula 2 or any such C alternative that was relevant in the 80s.