Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Some time as a professional coder in a team with developers of varying ability, and working with legacy code bases, and you might learn to appreciate a less malleable, more predictable language with more universal idioms.



You’d think, wouldn’t you? But I’ve worked professionally with codebases in something like a half-dozen languages by now, and I’m here to tell you that you’d be wrong.

The lower bound of code quality is limited not by choice of language, but only by what a given compiler or interpreter will flatly refuse to put up with — there’s always a better fool. The upper bound, on the other hand, is highly susceptible to such limitation.


A whole half-dozen, eh? :) You haven't been around long.

Specific code quality is not what I'm talking about. I think you've misunderstood me. Let me try and be more specific and concrete.

The degree to which code written by different authors at different times can gel together depends on the idioms they have in common. In languages without common collection libraries, code needs to communicate at the level of arrays and custom iterators. Languages without a single common memory allocator need have libraries negotiate who owns what memory, and have custom free functions specific to routines and libraries. Languages without lambdas typically reinvent the concept a half-dozen different, incompatible ways.

The amount of friction when trying to compose code or integrate with existing code is proportional to its divergence from the lowest common denominator of all code written in that language. The higher-level a language is, the larger a standard library it has, the more concepts that are shared between libraries and codebases and don't need to be reinvented in each individual code silo.

Go back to C in the dark days of Windows 95. Merely getting a string out of the OS was an ordeal; you could choose to allocate a buffer, send it to the OS, but always prepared to react to a failure and reallocate the buffer when the string turns out bigger than expected. C has no universal string type nor a common memory allocator (you might rely on glibc's malloc on Linux, but you're relying on non-portable convention). This directly resulted in a substantial amount of friction simply interoperating between two binary libraries.

The same thing follows through with higher-level concepts. When higher-level concepts are concrete in the language or available in standard libraries rather than composed out of simpler primitives a half-dozen times in slightly different ways, you lose a bunch of composability. You spend more time writing shims and adapters to smooth away the differences between interfaces.

And code isn't the only interface; your mind is too, especially in a larger legacy codebase. You may understand iterators, lambdas, functors, monads and so on, but in a language without first-class support and standard definitions for these things, you'll find them reinvented over and over again, to varying degrees of fidelity, sometimes under obscure names, which you'll need to discover and research as you dig into code nobody still in the organization has ever had to dig through themselves.

None of this has anything to do with code quality possible in a language. I've had to maintain some extremely high quality assembly. But it wasn't mentally cheap to get into, and a lot of concepts had to be reverse engineered from the code before they could be modified and transformed back down.

The risk with something like Lisp is that you use it as a language construction toolkit. With a closely knit team that grows a codebase amongst themselves, this can be a huge productivity win. But I don't think it scales. And I think history agrees. Excessively malleable languages (including Smalltalk) have not outcompeted less expressive languages, for one reason or another.


We have good and predictable languages like C++ (or even python) where you have many esoteric ways to do things (and lots of coders who do these things for some reason).

Coding standards are needed whether you're using C++, Java, python or lisp.

If you have coding standards and peer review processes, then lisp's flexibility is not going to be a liability.


This is so true. I have worked with several legacy code bases and I had discovered that in two opposite settings.

When I was developing on a quite malleable and a bit unpredictable language, I wished it would not be like that.

When I was developing on a less malleable, more predictable one, I was thankful it was like that!

I think it makes sense when you view a program as a cultural artifact. If a programmer has much freedom, so much that he is able to define his own conventions down to how to code the tiniest thing, he should really work hard to pass this "culture".

Unfortunately, as we all know, we seldom have the time and the means to share views about the code. So, indeed, the more universal the idioms, the less we jeopardize the understanding of the code by our peers.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: