by ux266478 | 2026-02-19 20:47:41+00:00
> In the latter, if you see `foo` in the body of a function definition you have no idea if it's a simple computation or some sophisticated and complex control structure just from what it looks like.

All control structures are reserved as keywords in Haskell and they're not extensible from within the language. In C I can't tell that an if(condition) isn't a function call or a macro without searching for additional syntactic cues, or readily knowing that an if is never a function. I generally operate on syntax highlighting, followed by knowing that an if is always a control structure, and generally never scan around for the following statement terminator or block to disambiguate the two.

I've found in general programmers greatly overestimate the unreadability they experience with the ISWIM family to be an objective property of the grammar. It's really just a matter of unfamiliarity. Firstly, I say this as a programmer who did not get started in the ML family and initially struggled with the languages. The truth of the matter is that they simply engage a different kind of mental posture and have different structural lines you're perceiving, this is generally true of all language families.

Pertinant to that last point and secondly, the sense of "well this is clearly less readable" isn't unique when going from the Algol family to the ISWIM family. The same thing happens in reverse, or across pretty much any language family boundary. For example: Prolog/Horn clauses are one of the least ambiguous syntax families (less so than even S-expressions IMO), and yet we find Elixir is greatly more popular than Erlang, and the most commonly cited preference reason has to deal with the syntax. Many will say that Erlang is unintuitive, confusing, strange, opaque, etc. and that it's hard to read and comprehend. It's just the same unfamiliarity at play. I've never programmed Ruby, I find Elixir to be borderline incomprehensible while Erlang is in the top 3 most readable and writable languages for me because I've spent a lot of time with horn clauses.

I think there's a general belief programmers have where once you learn how to program, you are doing so in a universal sense. Once you've mastered one language, the mental structures you've built up are the platonic forms of programming and computer science. But this is not actually the case. More problematically, it's propped up and reinforced when a programmer jumps between two very similar languages (semantically and/or syntactically) and while they do encounter some friction (learning to deal without garbage collection, list comprehensions, etc), it's actually nothing that fundamentally requires building up an entirely different intuitive model. This exists on a continuum in both semantics and syntax. My Erlang example indicates this, because semantically the language is nothing like Prolog, its differentiation from Elixir is purely syntactic.

There is no real universal intuition you can build up for programming. There is no point at which you've mastered some degree of fundamentals that you would ever be able to cross language family boundaries trivially. I've built up intuition for more formal language families than is possibly reasonable, and yet every time I encounter a new one I still have to pour a new foundation for myself. The only "skill" I've gotten from doing this ad nauseum is knowing at the outset that mastery of J does not mean I'd be able to get comfortable reading complex Forth code.