6 ms·
Programming is in tension between the Light Side and the Dark Side. The Light Side is about preventing the programmer from making mistakes: Get rid of go-tos!
by GMoromisato 3mo ago
Programming is in tension between the Light Side and the Dark Side.
The Light Side is about preventing the programmer from making mistakes: Get rid of go-tos! Add static types! Do not allow a bug to be expressible. The Dark Side is about giving power to the programmer: Macros? Obviously. Operator overloading? Self-modifying code? Multi-line reg-exps? Go to town!
The Light Side knows programmers are flawed and imposes constraints. The Dark Side trusts programmers with power. Neither side is correct all of the time, and a good programmer learns both.
Lisp is interesting in that it is clearly Dark Side programming (the programmer can do anything) but it's still admired by Light Side programmers. Maybe there's something about the simplicity of the language that makes it seem platonic--almost incorruptible. Or maybe Lisp is so pure that it embodies both Light Side and Dark Side, like a god that spawned the programming universe.
- rogue7 3mo agoKind of agree, but in my view preventing the programmer to make mistakes is futile. I have seen awful stuff in languages made to prevent errors. It's much better to give all the power to the programmer, to allow him to fix his mistakes rather than fantasising about preventing them.
- pfdietz 3mo agoI'm not big on static type checking in most situations -- adequate testing should find the type errors too -- but one place it looks very useful is avoiding data races in multithreaded programs. See Rust.
- bigpeopleareold 3mo ago... or Ada.
- malkia 3mo agoHah, didn't think of it this way... To me it was if it allows live updates (+support for them) or not :)
- tancop 3mo ago[dead]
- busfahrer 3mo ago> Or maybe Lisp is so pure that it embodies both Light Side and Dark Side, like a god that spawned the programming universe. This isn't so far off, considering that some people consider the "Lisp in Lisp" bit from the 1.5 manual to be the "Maxwell's Equations in Software": https://michaelnielsen.org/ddi/lisp-as-the-maxwells-equations-of-software/ https://michaelnielsen.org/ddi/lisp-as-the-maxwells-equation...
- GMoromisato 3mo agoMaybe machine language is the formless chaos and Lisp is the purest manifestation of order. All other languages are points in between.
- throwaway81523 3mo agoSee Cardelli's breakdown in his famous article "Typeful programming": http://www.lucacardelli.name/Papers/TypefulProg.pdf http://www.lucacardelli.name/Papers/TypefulProg.pdf Page 52 perhaps.
- gf000 3mo agoThat makes no sense without specifying what Lisp actually is. S-expressions are a generic tree, that's not a language, that's just syntax. Is it CL, Clojure, scheme? Like these don't even share a basic object model, it's like getting the AST of Haskell and C and then talking about how good that AST is.
- DonaldFisk 3mo agoI have always assumed that Alan Kay compared Lisp to Maxwell's Equations because of the similarity between the interplay of eval and apply in Lisp on the one hand, and the interplay of the electric and magnetic fields in Maxwell's equations on the other.
- agumonkey 3mo agoAlso because lisp core can be reduced to a few "equations" (at least that was my understanding)
- patrickmay 3mo agoI like your metaphor but I'd argue that trusting programmers with power is the Light Side. Relevant PG: https://paulgraham.com/langdes.html https://paulgraham.com/langdes.html
- GMoromisato 3mo agoThat's a great essay--thanks. And you have a good point. Maybe it's a weakness in the metaphor if one can see it either way. I fundamentally believe that there is no perfect language, instead one merely chooses a set of trade-offs. What's interesting about Lisp is that it is simultaneously well-respected and yet not widely used in productions (compared to C, C++, Python, JavaScript, and even Rust). It's almost like Lisp chose a particularly extreme set of trade-offs that yield great power but also repel large swathes of programmers. I think PG might say that it repels dumb programmers, but maybe not.
- solumunus 3mo agoI think it’s just that the syntax is more difficult to grok. When I first saw code (PHP and JS) it was fairly easy to read and figure out what was going on. I’m now experienced but I’ve never tried Lisp, but reading Lisp code takes considerably more effort than when I first saw the PHP/JS. I’m sure with very little experience it becomes just as easy, but to the novel eye I think it’s simply less intuitive to reason about.
- oalae5niMiel7qu 3mo agoOur entire profession has been moving more and more in the "bondage-and-discipline" direction over the past 10 years or so, tracking with broader sociological trends that are also justified with arguments involving "safety". That by itself can explain why Lisp has such low adoption. While Lisp has never been the most-popular language, it was never as unpopular as it is today. If that pendulum swings the other way, Lisp will get more popular again.
- Barrin92 3mo agofor a while there's been a strong cultural tendency in programming to mistrust people and trust tools (often even blindly because tools are just assumed to make no mistakes), and so expressiveness has been sacrificed for safety. There can be something to this but it's also self-fulfilling, if you strip people of agency of course they'll unlearn to program. I've always thought it's a misanthropic philosophy and sucked much joy out of programming but also there's something to be said that there's safety in the expressiveness of Lisp. I read an article a while ago that found a robust correlation simply between length of a code base and errors regardless of languages used. And given how succinct and clear Lisp codebases can be that's valuable in itself. we're kind of at the logical endpoint of this now with gigantic slop codebases that nobody understands just held together by 20 different tools, and if you ask me if I had to pick one of those or something one tenth the size written by a guy or girl who has been writing Lisp for ten years I'd say thank you I'll go with #2
- coliveira 3mo agoThe issue is also social, the average software engineer will treat Lisp code as a liability because most people really don't know what to do with it. In the mind of a professional SE, code is "maintainable" only if it's writing in Javascript or some other commercial language.
- skydhash 3mo agoYep, you have to use C# and Java because they are safe. If you want anything extra, you need to use $library, because only $library's maintainer is trusted with the dark corners of the language. Look how powerful we are, millions of libraries. Look at those Lisp guys and their sorry examples of package managers. /s If there's one thing I've been happy with learning Common Lisp and Clojure is that you only want libraries for things like algorithms, data formats, and protocols/interfaces. Mostly because those often have standards. Anything else should be a snippet to copypaste even when presented as a full program.
- adamddev1 3mo agoI think the big thing is that Lisp is (aside from mutable variable assignment) basically all declarative, rather than the imperative paradigm. Even without static types, and even allowing macro craziness, there's just such a stronger baseline of declarative and functional thinking, you're off to such a good start in clearer thinking and reasoning about a program.
- enfield-argent 3mo agoI think this depends on the Lisp, no? AFAIK Common Lisp supports a lot of imperative style programming--besides all the mutation/assignment functions, there's the `prog` macro that lets you use goto, `do`/`do*` to iterate over groups of statements, or even the `loop` macro. OTOH the Scheme-style Lisps are much more declarative thanks to TCO and a community that prefers the functional/declarative programming style. But again, I suppose all the Lisp forms return values, and quibbling about the declarative : imperative :: expressions : statements mapping is just petty semantics
- lgas 3mo ago> But again, I suppose all the Lisp forms return values, and quibbling about the declarative : imperative :: expressions : statements mapping is just petty semantics I would argue that it's very much not just semantics, or at the very least it's certainly not petty. The distinction has a noticeable effect on what the experience of writing code and on the reliability and related properties of the written code.
- ludston 3mo agoThis is just not true. The Lisp family contains all conceivable variants of languages, from statically typed Coalton, to dynamically typed Scheme. From functional, immutable by default Clojure to the imperative-style of Common Lisp. There are prologs, constraint solvers, ffis, JavaScript alternatives, garbage collected and not garbage collected languages that call themselves lisps.
- agumonkey 3mo ago
- tikhonj 3mo agoIt isn't nearly as much of a trade-off as people say. Languages like Haskell are both remarkably expressive and provide a lot of safety. (And, of course, languages like Python, Java and Go are the opposite.)
- GMoromisato 3mo agoHaskell is currently at #18 in LangPop: https://langpop.com/rankings https://langpop.com/rankings Almost by definition that implies that it makes some trade-offs that turn off lots of programmers. Still more popular than Lisp, though.
- lgas 3mo agoIt may very well be the case that it makes trade-offs that turn of lots of programmers but I don't think it's popularity directly implies it by definition, rather just that it implies there's something about it that prevents lots of programmers from taking it up en masse, and I think that's perhaps just the fact that it is so different from what everyone's used to and it takes some time to adapt to it enough to be able to appreciate the tradeoffs.
- ludston 3mo agoThat argument seems crazy to me. 18th is so good. There are literally thousands of programming languages that it is competing with.
- jimbokun 3mo agoLanguage design has almost nothing to do with language popularity. People learn JavaScript or TypeScript because they want to write web apps. Swift or Objective C to write iOS or Mac apps. SQL because there’s a database they need to get data out of. Python because there’s a machine learning library they need to use. Etc etc. Language design is far down the list of priorities.
- psd1 3mo agoI would refine that: Language design has only indirect relevance to language popularity. People go where the money is, hence python. But python is widespread because there is employment in it. That adoption by employers follows a network effect, but it originally came about through the language design. Early-adopter => mainstream => long tail Adoption hinges on that jump from evangelists to the mass market, and that implies: - attracts early adopters because of language design - early adopters can pitch the language to their bosses by showing cleat benefits, also because of language design The most obvious exception is javascript, which was inflicted on the world by browsers. Even so, it had to be sufficiently shit for the php crowd to feel at home. (Unsure which came first, but you get my point.) Php is exactly popular due to design. It was an exact fit for the myspace dotcom era, and there were no json APIs to illuminate its shonkiness. (I am still angry that [ ] serialises to either [ ] or { } depending on a fucking global variable. I cannot think, being maximally charitable, of any value that comes from conflating arrays and hashmaps. No, i do not want an array containing the keys 0 and "0". I can count on the fingers of one foot the times i have wanted that.) Sorry - my therapist encourages me to rant about php. She said it's part of healing. I haven't even told her about back-end php yet.
- dreamcompiler 3mo agoI think of C as more of a dark side language because it's basically a portable assembler. Lisp at least prevents you from doing the stupidest things like overrunning array bounds or writing to freed pointers*, which C is perfectly happy to let you do. * Of course there are no user-visible pointers** in Lisp so the concept of free vs. not free doesn't come up because memory allocation and garbage collection are automatic. **Under the hood most everything in Lisp is a pointer, but the user cannot see them or mess with them.
- throwaway81523 3mo agoLisp generally has precise GC, which I'd say makes it light side. It's even relatively type-safe if you count runtime type-checking. Highly reliable systems are written in Erlang, which if you squint is another Lisp dialect. There's even a sexp-based version called LFE, for Lisp-flavored Erlang. Erlang's key to reliability is error recovery, rather than exceptional levels of error prevention. I do like your light side/dark side classification.
- gf000 3mo agoIf you squint enough, JS is a lisp.. Define a goddamn language, syntax is not enough to define one! What are the semantics? Without that you are just talking about syntax trees like they would mean anything
- dosisking 3mo agoJS is Self, which is a dialect of Smalltalk. So not really Lisp imo
- throwaway81523 3mo ago> If you squint enough, JS is a lisp.. Yes, that is true. I'm not big on the idea that Lisp is defined by parentheses. The implementation strategies are another way to look at it. That doesn't capture it either, but it's an angle to try.
- gf000 3mo agoSo then what it is? Because otherwise it's a magical nothing-term to which everything lisp people like applies, but no criticism can ever reach it because "that's not really lisp, see it's different in this other implementation"
- Pay08 3mo agoIn my mind, it's 2 distinct criteria: interactivity and the manipulation of symbols (whether those are implemented as symbols or identifiers doesn't really matter). I don't know about Erlang, but from the admittedly little JS I've written, I believe it achieves both criteria, even if it's worse at them than a "proper" Lisp.
- akkartik 3mo agoYou mixed up Light and Dark. Creator-knows-best bondage-and-discipline is the Dark side. Trusting people with power is the Light side.
- sph 3mo agoLight and dark is propaganda depending on which side you're on. I'm with you, on the dark side I've seen people slowly turn into crabs, screeching about memory safety and static types. Can you imagine that? Now stick those wings on me, I'm going to fly close to the sun.
- tyeaglet 3mo agoOnly if you knew the power of the Lisp side…
- James_K 3mo agoI dislike when people use the term “power” to describe making code slightly shorter to type. Operator overloading is not in any meaningful sense more powerful than a language which lacks it.
- never_inline 3mo agoWith operator overloading you can provide same numeric operation interface to library types such as big integers. Sure, you can also define methods and make sure your primitive types also define those methods but now you have some confusions (like equals vs == in Java).
- gf000 3mo agoI agree with you on overloading - the real word here should be "expressivity", which is defined by language constructs that could NOT be syntactic sugared into a local context. Those may occasionally be useful, though not by itself. E.g. gotos are more expressive by the above definition, yet it was largely deemed to not be a useful "power".
- adrian_b 3mo agoCertain kinds of GOTOs are indeed proven mathematically to be necessary to write certain programs, in the sense that eliminating the GOTOs can be done only by making the program more inefficient, i.e. by increasing the number of executed instructions and the amount of memory that is used. Because of this, any decent programming language must include GOTOs, but in many modern languages they are not named GOTOs, because of the bad reputation of the word. For instance the language Scheme does not have GOTOs, but it has mandatory tail call optimization, which means that a "tail call" is just an alternative name for "GOTO". For example, this allows the writing of a state machine in Scheme, exactly like it would be written in a language with GOTO, but using tail calls instead of GOTOs. Other languages have labelled loops and they allow exit a.k.a. break with a label and next a.k.a. cycle a.k.a. continue with a label. Such instructions with labelled targets are just GOTOs with a bad placement of the label, which makes reading the source more tedious than with a classic GOTO. For providing the benefits of GOTO, a restricted variant is sufficient, i.e. a GOTO that may jump only forwards and which cannot jump inside nested blocks.
- user3939382 3mo agoCheck out Clojure spec. The light dark bifurcation doesn’t hold up.
- sdfsfdsdfs3d 3mo ago> Do not allow a bug to be expressible That is a very powerful idea, but unfortunately it cannot be realized with a fixed set of language rules. Some invariants are universal, but some are bound to the domain. Some projects require, say, an int (EvenInt) to take on only even numbers and others odds (OddInt). You can imagine the possibilities here are unbounded ("the numbers should be prefixed by numbers that are divisible by my age squared"). Ideally your base language has the expressive power to formulate new abstractions and constraints. This fundamentally requires the Dark Side. Once the proper primitives are in place a different "language" - this can be literally or figuratively - is used to express the interplay between those primitives. In effect you are starting with the most general (say, all of Lisp), restrict it to become more and more and specific - only "these modules" - until it cannot be reduced any further. If you can bring your domain down into being expressible as, say, a single config file, that'd be quite ideal. If you don't need the powers of abstraction to express your solution then exposing said powers would only invite in trouble. The mathematical equivalent of introducing unnecessary variables. As a programmer you are free to traverse the journey from say all of Lisp to a JSON config file in whatever way you please. The "Light Side" people have converged, or try to converge, on some intermediate state between full powers of abstraction and configuration only. I think this is useful because many if not all problems travel through that intermediate landscape on the way "down" (into their specificity). For example what you call "types" is a significant restriction on your freedom but at the same time it's so enormously general that this restriction can be considered a worthwhile default because just about any problem I can think of can potentially benefit from that restriction. All this is to say that I don't think it's a dichotomy so much as two interacting polarities whose interplay gives each its strength. Lisp is a particularly minimal base introducing very few restrictions of its own. But it's not the only one. Forth would be one in another direction.
- psd1 3mo agoWell put. Minor quibble: I see what you're driving at with "inexpressibility" but i think i could write EvenInt and OddInt in F#. I don't know Haskell, but i believe you would have to work hard to find a domain constraint that you can't declare in the Haskell type system.
- sdevonoes 3mo agoBut there are two types of “programming”: 1) programming per se (just you writing code for fun and perhaps building your own tools) and 2) a team of people with real-world constraints writing software for others for revenue It’s clear why it feels so good to use something like Lisp for personal projects. It’s also clear why the vast majority of companies don’t use it
- astrobe_ 3mo agoI'll paraphrase someone who commented on HN once (about dynamic vs static typing, IIRC): permissive languages are enablers for solo programmers, but you need more restrictive languages for team programming. This matches my experience because you don't chose who you work with. Skill level is uneven among the team. Less skilled co-workers will make mistakes that will have more consequences when the language is more permissive. That's one of the reasons you want code reviews, but then you convert your skilled programmers to teachers. This is not a good trade, because the time they spend improving the skills of other programmers is partially wasted because programmers are free to come and go. AI could change this picture. The name of the game is therefore to keep your teams small and skilled, but this is can be difficult because of typical company politics - e.g. "bus factor" considerations, shortening time-to-market is often achieved by adding more programmers.
- oalae5niMiel7qu 3mo ago>This matches my experience because you don't chose who you work with. That's what job interviews are supposed to be for. It should be easy to hire only the most skilled programmers, especially with the massive number of unemployed programmers out there right now.
- 3form 3mo agoMaybe it's trivial what I'm saying, but hiring the most skilled available person does not solve the skill disparity.
- dosisking 3mo agoJust look for the people who like Rust and filter them out
- Arubis 3mo agoI know this is obvious trolling, but it’s close to a truth. Selecting for a passion for languages that aren’t anyone’s first language gets you polyglots—folks that’ve had to abstract their knowledge and understand what’s an ecosystem feature vs what’s more broadly applicable. Joking about Rust users rhymes with joking about vegans; it’s true both parties generally can’t keep from talking about their choice. But you do want to hire someone who’s thought about their options and made a decision.
- bryanrasmussen 3mo agoProgramming is in tension between the Light Side and the Dark Side. The Light Side believes in giving people freedom and power to achieve freedom, to allow themselves to express themselves better through programming, to become better programmers through the tools the light side provides; in the Light Side believes in programming as a way of thinking. The Dark Side believes that people are incapable of handling freedom and must be restricted and controlled under the service of various organizations - generally companies. The companies will control access to programming and control the programmers via this access. The dark side does not believe in making programmers better programmers, it believes in managing programmers. The dark side does not believe in helping programmers to think, it believes in thinking for them.
- oalae5niMiel7qu 3mo agoYou have it inverted. Your "Light Side" is what previous generations of programmers called "Bondage and Discipline", because this philosophy assumes that a good programming language has built-in shackles to impose the will of a so-called "benevolent dictator" on all programmers.
- agumonkey 3mo agoit's dark side-ish at the ast level mostly, which is not the same as the dark side of mutable state over byte arrays
- yogsototh 3mo agoI wonder what side you would put Malbolge, What side for python? Haskell? Idris? Clean? C? K?... white/dark side is too much of a simplification to me. Programming language equilibrium is a very complex subject and fascinating one. After years of experimenting with many of them, it is all a matter of context of usage, personal preferences, objectives, etc.. there is no such thing as "the best programming language ever", neither "best for light side programming" nor "best for dark side programming". Similarly, there is no such things as: Light side/Dark side in artistic painting. There are tons of paints some are clearly greater than others, but there is no such thing as "the best painting most beautiful for everyone seeing this paint comparatively to any pain". [^Malbolge]: https://en.wikipedia.org/wiki/Malbolge https://en.wikipedia.org/wiki/Malbolge [^Clean]: https://en.wikipedia.org/wiki/Clean_(programming_language) https://en.wikipedia.org/wiki/Clean_(programming_language) [^K]: https://en.wikipedia.org/wiki/K_(programming_language) https://en.wikipedia.org/wiki/K_(programming_language)
- eimrine 3mo agoMalbolge is not an instrument for building, come on programmer. C is clearly the dark side with to chance to protest. The only way to consider K as dark side is its speed constraints relative to my favorite PL which is J. K is so fast because its interpreter fits into CPU cache. Haskell is a border case between sides because the idea of PL is so light that using so much light in programming leans to be really dark. Haskell extracts the cognitive friction from the code environment to the types environment, programming in paper is not a joke for Haskell.
- dosisking 3mo agoPython is definitely Light Side
- drannex 3mo agoIf there is any language that has ever been, Python is the very definition of light side, so much so that anything that needs to be done in the cover of night, is purposefully directed elsewhere by rather shady dark siders (C).