4 ms·
Closures and higher-order procedures do not a functional language make. It has to be convenient to implement procedures that compute actual mathematical functio
by catnaroek 10y ago
Closures and higher-order procedures do not a functional language make. It has to be convenient to implement procedures that compute actual mathematical functions.
Assume there exists a (pure) function `f` and a list `xs`. Does the following expression always return `true`, or, at least, never return `false`?
map(f, xs) == map(f, xs)
- tomp 10y agoBy this criterium Ocaml isn't functional either. Hell, even Haskell's not!
- catnaroek 10y agoBy this criterion, both Haskell and ML are functional. If you attempt to compare values whose type doesn't support decidable equality testing, you get an error, either at compile time (Haskell, Standard ML) or at runtime (OCaml, arguably a design defect). And, if `f` is a pure function whose codomain supports decidable equality testing, then `map f xs = map f xs` (or double equals using Haskell syntax) is always true.
- kevinnk 10y agoλ> map acos [2] == map acos [2] False :: Bool Interesting.
- catnaroek 10y agoAh, yes, there's a problem with `Float`s in Haskell. There should be no `Eq Float` instance. Standard ML handles this properly: > map Math.acos [2.0] = map Math.acos [2.0]; poly: : error: Type error in function application. Function: = : ''a * ''a -> bool Argument: (map Math.acos [2.0], map Math.acos [2.0]) : real list * real list Reason: Can't unify ''a to real list (Requires equality type) Found near map Math.acos [2.0] = map Math.acos [2.0] Static Errors
- tomp 10y ago> And, if `f` is a pure function whose codomain supports decidable equality testing, then `map f xs = map f xs` (or double equals using Haskell syntax) is always true. This statement is true in any language. So it's useless as a criterium for determining which language is "functional" and which isn't. Edit: except, of course, Haskell - `xs` could be infinite, in which case the expression wouldn't be true (but bottom instead).
- catnaroek 10y agoSee for yourself: lolcathost% js17 js> function twice(x) { return 2*x; } js> var xs = [1,2,3]; js> var ys = xs.map(twice); js> var zs = xs.map(twice); js> ys == zs false js> Of course, the fundamental problem (in both Haskell and dynamic object-oriented languages) is types: (0) Haskell doesn't have a type of lists. It has a type of potentially infinite streams. (1) Dynamic object-oriented languages don't have a type of lists. They have a (dynamic) type of objects with physical identity, whose state (mutable or otherwise) can be interpreted as a list. ML is free of these problems. It has a bona fide type of lists. Of course, you can also define a bona fide type of streams if you want to. Or a type of dynamic objects with identity. And those will be different types.
- tomp 10y agoThat's surprising, but really has more to do with the failure of JavaScript's standard library than with being functional. For example, the same is true for OCaml (using `==` reference equality instead of `=` structural equality), but `[1, 2] == [1, 2]` is true in Python (a dynamic language, one that most people probably wouldn't call "functional").
- catnaroek 10y agoIn Python, the actual equality testing operator is `is`, not `==`. The fundamental property of equality is that equal objects can't be distinguished in any way. (Indiscernibility of identicals, aka Leibniz's principle.) xs = [1,2,3] ys = [1,2,3] # are xs and ys equal? ys.append(4) print(xs == ys) # no!