7 ms·
> How does "map inc [1, 2, 3]" know not to do "inc [1, 2, 3]" and then pass the result to "map"? I'm guessing it's a language rule, but it could be the type sys
by curryhoward 8y ago
> How does "map inc [1, 2, 3]" know not to do "inc [1, 2, 3]" and then pass the result to "map"? I'm guessing it's a language rule, but it could be the type system.
That is a lot like saying: in the Python expression "5 - 4 - 1", how does the language know to subtract 4 from 5 first, and then subtract 1 from the result, rather than subtracting the 1 first?
The answer is: precedence rules. It's not ambiguous, though you might not know which order applies if you aren't familiar with the language. The same could be said of the syntax of any language, except perhaps for those in the Lisp family.
Functional languages generally don't try to be familiar to programmers who are used to other paradigms, because that compromises the elegance of the language (for example, mandatory parentheses for function calls and currying are an ugly mix). But once you learn a language in the ML family (Haskell, OCaml, etc.), they all have the same kind of familiarity that a Java programmer feels when they look at C#.
- mkl 8y agoThat's kind of my point - people know the rules for maths, and Python's function call notation is the same, so it's familiar and unambiguous to outsiders. I understand that other languages make different choices regarding syntax and readability. This particular choice, while not inherently a bad choice, makes things more difficult for most people, and led to eximius's comment at the start of the thread: > It makes code much more difficult to read
- curryhoward 8y agoI think it's only more difficult to read initially, when you aren't used to it. I actually find it more natural than the more mainstream function call syntax after having used it for a while. When I look at code in C-family languages, it feels like there is a lot of unnecessary syntactic noise that distracts me from understanding what the code is doing. I agree that the "f x y z" syntax can look confusing/unfamiliar to people who haven't seen it before, whereas everyone knows how subtraction works. But it's worth learning because currying is an elegant way to simplify a language and make it more uniform: a function is just a map from a single argument to a single result. To compose functions, you only need the output type of the first function to match the input type of the other function. You can build a general function composition function that takes two functions and returns their composition. There is no arity to worry about. Parentheses should be used for grouping and not be overloaded to also indicate function calls.
- chriswarbo 8y ago> people know the rules for maths, and Python's function call notation is the same, so it's familiar and unambiguous to outsiders Personally I'm really not a fan of relying on operator precedence. Even in that Python example I would write it `(5 - 4) - 1` to disambiguate. I have a few issues: - Firstly, parsing combinations with varying precedence is something that computers are good at but people not so much, so I see no reason to force readers to juggle this sort of stuff. - Second, mathematical precedence rules are overly complicated. Trying to support them can make a language overly complicated. Languages like Smalltalk prefer to remain simple, even if that "breaks" standard mathematical expressions https://en.wikipedia.org/wiki/Smalltalk#Expressions https://en.wikipedia.org/wiki/Smalltalk#Expressions - Finally, arithmetic is a tiny part of a programming language. There's no "standard" way to extend operator precedence to include, say, 3D rendering operations, or parser combinators, or attaching event handlers, etc. All we can do is give each operator a number, at which point we're just exacerbating the "humans aren't good at precedence tables" problem. This has also been discussed elsewhere, e.g. at http://wiki.c2.com/?OperatorPrecedenceConsideredHarmful http://wiki.c2.com/?OperatorPrecedenceConsideredHarmful PS: I prefer the `f a b c` function call syntax to `f(a, b, c)`, but prefer s-expressions to both. Scheme is really nice, but I don't want to live without currying and laziness by default. I have high hopes for https://lexi-lambda.github.io/hackett https://lexi-lambda.github.io/hackett :)