10 ms·
The Tragedy of the Common Lisp: Why Large Languages Explode (2019)
- diskzero 5y agoPrevious discussions: 2019: https://news.ycombinator.com/item?id=20233220 https://news.ycombinator.com/item?id=20233220 2015: https://news.ycombinator.com/item?id=9738866 https://news.ycombinator.com/item?id=9738866
- phoe-krk 5y agoIt needs to be repeated over and over that Common Lisp is a pretty damn poor choice for this blogpost's title, even though the first part of its name kinda-sorta fits into the "tragedy of the commons" idea. CL honestly isn't a large language by modern standards. The Common Lisp standard library is tiny compared to modern C++, Java, Python, Ruby, Rust, Haskell, APL, or whatever other mainstream language one is working with nowadays. CL might have been "batteries-included" in 1994, when it was standardized, but the idea of "batteries" that a language can and "should" include has been expanded hundreds of times since then.
- smackeyacky 5y agoSmalltalk, Lisp, Forth and retro computing are just easy front page HN submissions. I understand why people might get nostalgic for simpler times and simpler computers, I'm partial to the rose coloured glasses view of the past myself. Its been interesting using C# for the last 15 years through that perspective. Microsoft seem intent on folding every cool language feature from every programming language into .NET and it does feel overwhelming, but in the end most experienced programmers have a style so we naturally settle on a subset of language features until we need something new. I really wish somebody had implemented the async patterns in mainstream languages in the 1990s for example. I really don't think nostalgia for simpler times is useful for solving todays problems, I much prefer C# to Smalltalk or lisp for getting stuff done today.
- CraigJPerry 5y agoIt’s hard to argue with c# as a pragmatic choice today: The language itself has adopted just about everything interesting from contemporary languages, from pattern matching to top level statements allowing you to write a hello world or simple scripts that rival python for simplicity. It’s performant, asp.net is at the top of the tech empower benchmarks, c# is only just behind c++ on the compiler benchamrks game leaderboards (although if you actually read the code i question the value of the deceptive impls there, e.g. the regex redux example is just calling a c library rather than using native c# facilities). It’s not as memory efficient as go, by about 5x-10x worse but it’s comparable to java. The clr has a much faster allocator than go (although go developers just pre-allocate up front as an idiomatic optimisation). Since dotnet 5.0 the developer experience is very decent across all platforms. 6.0 with its further enhanced hot reload etc looks even better. It’s cross platform - apple tv apps or apple watch, ios, android, windows, linux, macos, they’re all first class citizens. Whether you want to write 3d games (ubiquity), machine learning, web apps, desktop apps, mobile apps, wasm / blazor, it has 1st class support for them all. And yet, i can’t help but feel common lisp is probably a better language. The developer experience in CL is superior - repl driven development combined with structural editing and easily accessible ast manipulation just put CL (and other lisps) beyond what more static languages can ever hope to offer in terms of developer ergonomics.
- cutler 5y agoAll available with Clojure plus you get the JVM.
- CraigJPerry 5y agoAnd very slightly nicer syntax in clojure, at least to my eye (i'm talking about the vector arg list vs list, and i believe the use of a keyword as a function to pull a value from a map is a clojure-ism too. Both could be added to common lisp though - the vector arg list would be a short reader-macro and my lisp-foo isn't yet strong enough to say how to implement the keyword as a function thing but i'm 100% confident it can be done...)
- 5y ago
- Rochus 5y agoThe CL 1994 standard has close to 1400 pages; the C++11 standard had the same size and doubled the number of pages compared to C++03. In comparison to that, the original Oberon language specification in 1990 had less than 20 pages. CL might be "small" in terms of syntax; but the number of constructs to take into account in practice is still large.
- 4ad 5y agoThe CL standard describes the standard library. The language is described in about 40 pages of said standard.
- Rochus 5y agoAlso the C++ standard includes the standard library. The standard library can be considered part of the language. If you include the standard library for C# this adds up to several thousand pages. Lisp like Smalltalk have very little syntax, but this is mostly because constructs which are part of the syntax in bigger languages are constructed in Lisp and Smalltalk on the simple syntax; and you still have to know how to write loops or closures or the like; or if you want OO in Lisp you have to know CLOS, which has many pages.
- kryptiskt 5y agoThe Common Lisp standard library includes most of the control flow constructs, the object system, and ways to bind values. Things that in another language would have been in the core language. You can't learn CL in any meaningful sense without in-depth knowledge of the standard library.
- adrian_b 5y agoIt is true that the CL standard is not much smaller than the C+11 standard but the number of pages on my (officially bought) standard copies are: Common Lisp 1994 (2004 edition): 1153 pages C 1999: 554 pages C++ 1998: 776 pages C++ 2011: 1356 pages C++ 2014: 1375 pages C++ 2017: 1618 pages C++ 2017(2018): 1620 pages In comparison, the reference manual for Ada 1983 had only 336 pages and the Algol 68 report had only 146 pages, these 2 being considered very large languages at their time. It is true, however, that the Algol 68 report would have required a double length to include enough explanations to make it intelligible for everybody.
- jonathanstrange 5y agoI don't buy the basic premise that CL is too large. Languages get popular if they allow programmers to achieve what they want to achieve with minimum effort. It doesn't matter whether they are large or small. CL never had many good GUI options (except very expensive commercial implementations) and until recently many programmers wanted to create GUI applications. So CL was a bad choice. It's still a big minus. CL lacked a good package manager, which was very inconvenient. Now that there is Quicklisp, a big plus. CL has no concurrency support in the language and the quasi-standard Bordeaux-threads has disadvantages over concurrency primitives of other languages. Here you go, three reasons why CL is less popular than it could be that have nothing to do with the size of the language, and these are just examples. A language doesn't need to be big but it needs to offer what programmers need in one way or another. It's irrelevant whether that's part of the language or part of an ecosystem.
- satellite2 5y ago> Languages get popular if they allow programmers to achieve what they want to achieve with minimum effort. It doesn't matter whether they are large or small For any sufficiently large organisation or lasting use cases a language is almost not at all about writing it but about reading it. Any subsequent modifications after the initial creation will require reading and hopefully understanding what is happening. Even if the code is properly documented the code is always the final specification and if you can't read, you can't understand what your organisation is really doing. In that sense, adding a feature that is possibly detrimental to reading the language means detrimental to the whole language and its users.
- jonathanstrange 5y agoI'm a big fan of Ada, and of all languages I've seen it is by far the most readable. It has been deliberately and carefully designed to be self-documenting. The Ada developers shared your vision. But it's also the reason why I don't think it's true that readability plays a major role in language adoption.
- 5y ago
- lmilcin 5y agoI program multiple languages including Common Lisp. I don't buy that Common Lisp is too large. I would say the opposite is true. The base language is rather simple and what you mistake for language are just standard library. What is complex is it being Lisp language which means you need to adjust your brain structure to a different level of functioning and focus when reading code. ** But languages do get too large. I think the reason languages get too large is because developers, as soon as they get some experience, start demanding more features. Maybe they want to have more functional experience in an object-oriented language, or maybe they want async in one that was not designed for it. These developers form a core of users that enjoys being able to absorb these features over time as the language evolves. On the other hand, new users need to learn it all at once. There will come a point where new users will just look at horrendously complicated language with vast specification and will just say "Fuck it, I don't want to spend so much time to be able to do anything, I will program in this neat new other language that is simple to start and already has most of what I need."
- WalterBright 5y agoI lost count of the number of posts in the D language forums along the lines of "don't add any more features, just fix bugs. BTW, I need features X and Y, please implement them."
- cb321 5y agoThat made me crack up. Thanks for the morning smile. Priority variation is one thing, but boy oh boy..add lack of self-awareness and you have a pickle of a problem.
- lmilcin 5y agoThat's basically what is happening in Java, too. I have been programming Java for the past 20 years and I do enjoy new features. And I would like couple more features myself. But I am also tech lead for a lot of new developers which I see they struggle finding sense in what is going on with Java. Not just the language, but the multitude of frameworks and other paraphernalia supposedly needed to make a working modern application. Rather than trying to understand it they are giving up and revert to copying and pasting code that works. And wait for somebody with experience to catch obvious problems on code review. I think this is not sustainable.
- fbn79 5y agoFor example my opinion is that introduction of "class" in Javascript was not a good idea that only added confusion to newcomers.
- qwerty456127 5y ago> Once a language gets beyond a certain complexity — say LaTeX, Common Lisp, C++, PL/1, modern Java Nevertheless Common Lisp, C++, let a lone Java (I know nothing about PL/1) at least are reasonably easy to grok, read and write. At the same time LaTeX seems a language of extraterrestrial insectoids as soon as you go beyond composing formulae and substituting text in pre-made templates and and want really custom typesetting. I once felt like I would like to actually learn it, tried it and gave up completely quickly - it really feels unapproachable.
- the_duke 5y agoI disagree on this one. Before `class`, people built ad-hoc class-like constructs based on prototype inheritance. Often in slightly different ways, with different constructor choices and different implementation details. For larger code bases in team environments class is a really critical standardization, otherwise you can easily end up with a mess. It's also important for tooling, because IDEs can much better understand what's going on and present information better. Now, if Javascript really needs things like private class members and a lot of the other difficulties around classes is another question.
- szastamasta 5y agoI personally see very few use cases for classes in JS. Most of the stuff can be solved by using factories and objects without all "this" issues.
- qwerty456127 5y agoI appreciate your opinion and generally agree but feel like you probably meant this to be a response to some other comment.
- the_duke 5y agoWhoops, indeed, the intended target was https://news.ycombinator.com/item?id=28549925 https://news.ycombinator.com/item?id=28549925.
- 5y ago
- szastamasta 5y agoWhile I do agree that title of the article is clickbaity. I also agree with most of the arguments in the article itself. I'm a big fan of JavaScript as being a simple functional language with tiny bit of prototype based OOP. I do like some of the newer features of the language - arrow functions, block scoped variables, destructuring... But I'm not sure stuff we're adding now are really giving us any value: the ugly async/await that is leaking abstractions and needs a lot of fixes to support iteration, classes, static members, constructors, annotations, etc. For me personally it adds nothing valuable to the language. It simply is there to make language attractive to C# and Java programmers. It clashes with current libraries and way we used to work with JS. Thanks to that, we'll probably see explosion of crazy complex tools from these languages being introduced into JS - ORMs, DI containers, code generators and dynamic proxies everywhere... Most of our problems could be easily solved using functions, objects and closures. But now we'll have Spring Data JS and in few years we'll also get our SimpleBeanFactoryAwareAspectInstanceFactory.
- cutler 5y agoAs soon as you see a Builder a Container is sure to follow then you need a Factory for your Containers and a Proxy to mediate access to your Factory. Alternatively you can opt for Clojurescript and never have to deal with any of this crap.
- codeflo 5y agoThe problem with growing languages is often age more than size alone. Some features turn out to be less useful, or will later be superseded by more general features. But beginners still have to learn all of the the old ways to understand existing code. C++ is perhaps the most prominent example of this, I’d consider it to be at least three different languages merged into one at this point. JavaScript has also accumulated some weird stuff over the years, like var, == and (arguably) a class-based OO system that doesn’t interact very well with the rest of the language. One “solution” is using only young languages (e.g. Rust is very large, but young enough that most of its features are still useful). I personally like switching technologies every few years, but as a field, we can’t keep doing that forever. The other idea is using a language that’s more or less frozen, like C.
- shakna 5y agoI like the way that Scheme dealt with this recent-ish-ly, even if it hasn't gained overwhelming support in the community. R6RS was considered too big, and too influenced by one of the players, by a large amount of the community. So, the big player distanced themselves a bit, renaming themselves to Racket, etc. But for the next standard, two were produced. R7RS-small and R7RS-large. A core language that stays the same, that everyone has to use to call themselves a "Revision 7 Scheme", and an extended standard language that is useful, for those wanting to provide a "batteries included" kind of environment.
- pjmlp 5y agoFrozen, like having C2X around the corner?
- codeflo 5y agoRelatively speaking, those changes are mild. And it’s the first language extension in a decade (since C11). Compared to the insanity that the C++ committee does every three years, that’s a good thing.
- pjmlp 5y agoIt helps that WG14 almost has no one around left, because most improvements are anyway available in C++ for the last 20 years. And no one is obliged to use every single feature from C++.
- marcus_holmes 5y agoI see this happening with Go, a language with a specific design goal of remaining simple. Generics getting added is OK. I mean, almost every veteran Gopher I've talked to agrees that there's been a couple of times, maybe, that they've needed generics and not had them, and that interfaces work fine for 99% of cases. Everyone outside the language insists that it needs generics. But sure, let's add generics for those few times we need it [0]. But then "error handling is too onerous", "there's too much boiler plate", "why can't I code in Go using a functional style?", "Go needs to look more like Ruby", etc, etc. I really hope they keep Go simple and don't cave in to demands to add stuff to it. It doesn't need more syntax. It needs smaller runtimes, a method of determining whether two slices are using the same backing array, and a few other gotchas. I can see a future where there's a "Go classic" forked from 1.17 (or possibly 1.18) that never moves forward, while the main Go gets ever more complex and Java-fied. [0] Except, of course, that as soon as we have generics then every new gopher will insist on using them for everything, and not learn how to use interfaces well instead.
- Zababa 5y ago> I can see a future where there's a "Go classic" forked from 1.17 (or possibly 1.18) that never moves forward, while the main Go gets ever more complex and Java-fied. What I think will actually happen is that Go will continue increasing in size, generics will bring a new kind of fragmentation with people using libraries everywhere to replace the base constructs of the language, and in 10 years a new "minimalist" language to replace Go will appear, and the cycle will continue. You see that happening with pretty much everything. At first the new thing is easy to learn, and then it slowly becomes as large and hard to learn as the thing it replaced, because accidental complexity wasn't such a big part of the original thing.
- mark_l_watson 5y agoThis article barely mentions Common Lisp. The author makes a good point that for complicated languages, programmers carve out a subset of features to get their work done. (At least, this is what I do for Common Lisp, Haskell, Swift, etc.) I have always loved a tech world with many programming languages, but I wonder if this might change in a few decades if software reliability becomes more of an issue. I don’t know much Rust, but I have taken a good look at Swift as being a possible direction for a universal language (REPL development, strongly typed with fast compilation speeds on M1, and a generally pleasant language). I have a prediction: IT security will become such a larger problem in the future that programming languages and operating systems will go through a winnowing out phase, fewer choices, and those fewer choices will have more effort in producing provably correct software.
- nescioquid 5y agoScott Meyers, in Effective C++, writes at the outset that C++ is a federation of languages and that one must come to an agreement at the beginning of a project about which parts of the federated language will be used. I think Java is in the same ball-park these days. Common Lisp has little syntax (but complicated by macros), 900+ functions in the language spec, supports many programming paradigms, and yet I don't feel it as having become fragmented as a language. Your winnowing idea is interesting, but would seem to suggest we periodically discard entire languages. A language's library ecosystem is often a critical factor in selection, which also makes it harder to give up. The longer a language is actively developed, it seems there's a greater risk for the language to become fragmented. I wonder if this is ever a concern for language designers (I presume it is) and what sorts of decision might lessen the probability of fragmentation occurring in the future. > I have always loved a tech world with many programming languages, but I wonder if this might change in a few decades if software reliability becomes more of an issue. I don't expect that to happen unless the liability landscape or some other financial incentive changes. Do you see force that would drive an increased focus on reliability in the industry?
- Mikeb85 5y agoLots of big languages are successful; C++ is a prime example. My understanding of Lisp 'history' is that most CL implementations were by large vendors charging silly licensing fees and they got undercut by C and Pascal vendors... Another theory I have is that Lisp encourages the use of macros which makes sharing code more difficult. Or maybe it's simply that the languages that built/were built on Unix and PCs became most popular as those systems were most popular (C, C++, Perl, Python, Ruby, etc...). And of course now the language of the browser (JS). Or maybe a bit of everything. On the plus side, SBCL is pretty fantastic and people still do things with Lisp.
- mbrodersen 5y agoOnly big languages are successful. The world runs on C/C++.
- mrcode007 5y agoCommon Lisp is an extremely compact, regular and small language. It comes with a huge standard library that you can but don’t have to use. By that measure, Javascript would be a large language because it has a big NPM ecosystem. Common Lisp wanted to avoid the problem so that people don’t have to write seven versions of the left pad library. As a result it includes useful stuff in the standard library.
- tsimionescu 5y agoThis is probably a bit unfair, because technically things like the object system and conditions and loop are part of the standard library, but they can also be considered part of the core language given their importance in much CL software.
- mrcode007 5y agoCLOS is implemented in Common Lisp. These two books explain how it’s done: https://en.m.wikipedia.org/wiki/Object-Oriented_Programming_in_Common_Lisp https://en.m.wikipedia.org/wiki/Object-Oriented_Programming_... https://en.m.wikipedia.org/wiki/The_Art_of_the_Metaobject_Protocol https://en.m.wikipedia.org/wiki/The_Art_of_the_Metaobject_Pr...
- tsimionescu 5y agoI know it is. That's not the point. The point is that you need to know CLOS with its many rules to understand many CL code bases, just like you need to understand C++ classes. The fact that C++ classes are part of the C++ core langauge while CLOS is a library doesn't really change this aspect.
- mrcode007 5y agoI agree with the claim that knowing CLOS is useful to read code bases. Where I think we differ is that I don’t consider CLOS a part of the language itself. I consider it a part of a particular implementation of the language. You can be a fluent and prolific CL programmer without ever writing any code that relies on CLOS, defstruct or defclass, etc. The big difference between C++ and CL in this particular instance is that you can’t write C++ without writing or using classes/structs. For example, using STL almost always involves using or writing custom comparator “classes”. Even if you choose to go with lambdas, the whole concept of a container is object oriented. In CL, you can, if you want, stick with lists all the way down without ever touching defclass/defstruct at all. An equivalent abstraction level of the C++ code would only use integral data types. Whereas in CL those types are part of the language.
- maydup-nem 5y agoComparing CL to C++ isn't very fair. That's like comparing a quartz-watch with multiple displays and a set of carefully laid-out knobs to a mad hairball of debris which will sting you every time you try to pick it up / comb it / whatever. And OK, maybe their formal descriptions both will run similar length. But it's not a fair comparison. Size isn't all, what it really is is comprehensibility. Perception of its essence. If the foundations are solid, if you don't have a feeling that it might just be an ad hoc contraption mucked up by the devil himself to make people suffer, if it feels like you don't have to fight it every step of the way, if you don't get nauseous just by thinking about it, you just might as well stroll through it, no matter the pathwalk length. Maybe a better question is, what's really extraneous? You know, with CL, I can't immediately tell. The Scheme folks have an idea. But Scheme and CL still look like a pair of siblings nonetheless. Or maybe an even more fundamental question is: "is it well-designed"? Or maybe "does it provide depth without imposing unnecessary complexity"? There are plenty of questions, but the size one is quite boring, honestly.
- mbrodersen 5y agoYep I agree that it isn’t fair to compare the two languages. C/C++ is the language that runs the world. Including the OS you are using right now. CL is a niche language that close to nobody use in production. It’s like comparing a container ship with a paper drawing of a ship. No comparison.
- maydup-nem 5y agoDid I hurt your feelings?
- mbrodersen 5y agoHahaha not at all :)
- fouric 5y agoIt occurs to me that there are very different penalties for growing the standard library vs the language itself. Adding new things to the language (e.g. closures, conditions, a borrow checker, first-class functions, immutable variables, multiple return values) results in the user having to keep more things in their head at once to use the language. Adding new things to the standard library increases the size of the language distribution, but doesn't appear to increase cognitive load that much. The fact that CL has a `round` function doesn't really make programming in it any harder. Adding syntactic sugar to the language can make it harder to read, and usually breaks backward-compatibility. My impression is that most language "bloat" is in the standard library and syntactic sugar, not the language "core" - although I have little experience with C++. Any counter-impressions?
- tediousdemise 5y agoI think increasing the size of the standard libraries is the solution to avoiding core language bloat. C++ has mostly taken this approach. A bloated core language means that programmers now have a lot of baggage to deal with--particularly features that reduce performance. In my opinion, I do not think features that reduce performance should ever be added to a core language. The only features that should be added to a core language are ones that increase code readability and safety and reduce the amount of code you need to write to accomplish your goal. > Bjarne was resolute in preserving his fundamental goals … People were telling Bjarne that you should turn C++ into a fully object oriented language… make it automatically garbage collectable… make all the member functions virtual… eliminate global functions… in other words they wanted him to design Java. He listened politely to them and kept maintaining the fundamental integrity of the language. [0] [0] CppCon 2014: Bjarne Stroustrup "Make Simple Tasks Simple!" (https://youtu.be/nesCaocNjtQ?t=296 https://youtu.be/nesCaocNjtQ?t=296)
- sterlind 5y agoI kinda like large languages though. C# is very much a "sharks with frikking laser beams" kitchen sink of paradigms and features (fun fact, it even has dynamic typing!) but it's a joy to program in, because I have options and a lot of ways to express myself. the dark side of having minimal syntax is that code accumulates boilerplate, design patterns and frameworks.
- Zababa 5y agoI agree with the author's point that JavaScript is getting too big too fast. I don't like all the new support for OO stuff. I don't like how TypeScript often looks like C#. I don't like the direction in which JavaScript is heading. I may very biased here, but I think things like the promise proposal not being a monad is an example of those small cuts that kill slowly. Instead of having a well-thought abstraction, we have a "quick fix" around some problems, but then we have a quick fix on the quick fix (async/await). I wonder what the future of JS holds, but I'm not too confident.
- mbrodersen 5y agoA programming language that doesn’t get big is a programming language that almost nobody use.