This might be just my "ignorance", but am I the only one who thinks that "where" actually hurts readability?
I mean, it's not a problem when it's just a few lines, but when you have a lot of code, and you have to scroll further down to see, what do parts of it mean, and then jump back... It just seems backwards to me.
And yes, I know there is "let ... in", and if I ever start writing in functional languages I will use it, but when reading functional programs, I see way more "where" than "let ... in".
> I mean, it's not a problem when it's just a few lines, but when you have a lot of code, and you have to scroll further down to see, what do parts of it mean, and then jump back... It just seems backwards to me.
It's the same thing you'd have to do when the code was factored out into separate functions, which is generally (though not universally) seen as good practice in those circumstances in languages that don't have `where`. You want to be able to see a high level overview of what the function is doing and then drill down into the details, rather than be overwhelmed by all the details right from the start.
The fracturing of the narrative is an argument against the idea sometimes espoused (most often implicitly, but sometimes explicitly) that, as functions are useful, then the maximal factoring into functions must be optimal.
Nevertheless, functions (with names) differ from 'where' clauses in precisely that: they have a name, and ideally, a function's name might tell you everything you need to know about it, though in practice, it is hard to fully and unambiguously state a function's contract in its name, especially if it has side effects.
I doubt it is possible for a language to be such that everything that matters in understanding a given part is always lexically local. I think we need to look to tools, rather than syntax, to help with that.
> Nevertheless, functions (with names) differ from 'where' clauses in precisely that: they have a name, and ideally, a function's name might tell you everything you need to know about it, though in practice, it is hard to fully and unambiguously state a function's contract in its name, especially if it has side effects.
Huh? What's the difference in "naminess" between:
bar x = ...
foo x y = bar (x + y)
foo x y = bar (x + y)
where bar x = ...
I see that you are right; 'where' clauses don't restrict the ways an author can introduce what Landin calls user-coined names.
It comes from ML.
I don't think ML has the `where` clause. Haskell got it from Miranda, which got it from SASL, which got it from ISWIM.
I always think that let ... in ... can also use where. My mistake.
The original ML language (the one produced as part of the LCF theorem prover), did have a `where` clause that works like the one in Haskell. See here for example: https://github.com/theoremprover-museum/LCF77/blob/master/sr...
A brief skim over the revised definition of Standard ML indicates that it was abandoned at some point. I've no idea if Caml or OCaml kept it.
That said, I'm reasonably sure that the syntactic construct (insofar is it is used in programming languages) originated with the ISWIM introduced in this paper, which was rather influential in its day, perhaps especially in the functional programming community.
For people who immediately think Machine Learning, ML is a LISP like langage which OCaml is based on (among others).
How is ml a lisp like?
The original ML was implemented in Lisp (Stanford Lisp) as part of the Edinburgh LCF (Logic for Computable Functions) theorem prover. Different syntax, types - but other stuff it had were easily shared in the implementation with the underlying Lisp: functions, higher-order functions, garbage collection, lists (with cons and append operators), lambda expressions, ...
Here is a version of LCF with that first ML from 1977: https://github.com/theoremprover-museum/LCF77
quoting the wiki link provided upthread:
> ML (Meta Language) is a general-purpose functional programming language. It has roots in Lisp, and has been characterized as "Lisp with types". It is known for its use of the polymorphic Hindley–Milner type system, which automatically assigns the types of most expressions without requiring explicit type annotations, and ensures type safety – there is a formal proof that a well-typed ML program does not cause runtime type errors.
It may have roots in lisp, but the language itself is very different, both syntactically and how you approach problems.
Haskell's one language I know which has a `where` similar to the one described in the article.