6 ms·
:sigh: I hate function call syntax without parens. It makes code much more difficult to read and, if it supports first class functions, passing around no arg fu
by eximius 8y ago
:sigh: I hate function call syntax without parens. It makes code much more difficult to read and, if it supports first class functions, passing around no arg functions is harder than it should be.
- PeCaN 8y agoI hate function call syntax with parens. It makes code much more difficult to read and, if it supports calling functions, calling functions with args is harder than it should be.
- bobdolebob 8y agoI hate parens call syntax with or without functions. It makes code much more difficult to read, and if it supports functions calling first, arguing with functions and passing is harder than it should be.
- kjeetgill 8y agoWhile I agree the parent could have elaborated more, would you like to as well? I've never worked in a language without parents for function calls so I share their confusion reading Haskell or Ruby code at a glance. I don't think a language needs to bend for non-users but being intelligible without knowing the language canI be nice. As an outsider, the examples: A(B(C)) A(B,C) A(B)(C) Could all be valid Python but still communicate a little bit about A B and C. Without parents they'd all look like "A B C". I'm sure it's more obvious if you know those languages.
- flomble 8y agoThe interesting thing is that in Haskell, the equivalents of Python's `A(B,C)` and `A(B)(C)` are identical: `a b c`. This is because of currying: you're allowed to supply one argument to a function at a time, and you get back a function that takes one fewer argument. So if `add(x,y) = x + y`, then `add(5)` is a function (let's call it add5) so that `add5(y) = 5 + y`, or in Haskelly notation, if `add x y = x + y` then `(add 5) y = 5 + y`. If you write `add (x,y)` in Haskell, then it means a function that takes a single tuple `(x,y)` as an argument. A(B(C)) would be `a (b c)` or `a $ b c` or `(a . b) c`. The first is the most vanilla way, the second is convenience (basically "evaluate everything after $ first, then plug it in") and the third uses the function composition operator `.`.
- chriswarbo 8y agoNice summary. I would just like to add that `$` and `.` in Haskell aren't part of the language syntax, they're just normal functions/operators, which some people like to use. We can define `$` ("apply a function to an argument") as: f $ x = f x We can define `.` ("compose two functions") as (where `\x -> ...` is an anonymous function): f . g = \x -> f (g x) Equivalents in, say, Javascript would be: function dollar(f, x) { return f(x); } function dot(f, g) { return function(x) { return f(g(x)); } People mostly use `$` because of its precedence rules, which cause everything to its left to be treated as its first argument, and everything to the right as its second, i.e. we can use it to remove grouping parentheses like: (any complicated thing) (another complicated thing) with: any complicated thing $ another complicated thing It's also useful for partially applying, e.g. `map ($ x) fs` will apply each function in the list `fs` to the argument `x`.
- earenndil 8y ago> Without parents they'd all look like "A B C" No, that would just be a(b,c). You would use parentheses to express the others. a(b(c)) would be a (b c). a(b)(c) would be (a b) c. IMO it's still perfectly readable, you just have to know it and get used to it (which, granted, can be difficult if you're only used to paren-ized languages, but not an impossible ask, certainly not, imo, a deal-breaker).
- chriswarbo 8y agoThere's an added complication that `a(b, c)` could mean "call `a` with two arguments `b` and `c`" or it could mean "call `,` with two arguments `b` and `c` to form the pair `(b,c)`, then call `a` with that one argument". The latter would be written `a([b, c])` in other languages. These are all isomorphic (we're calling `a` and giving access to `b` and `c`), but can confuse people who are new to the syntax.
- k__ 8y agoI liked how LiveScript had ! instead of (), it made the whole source look like stuff would be done! xD I mean, why not give invocation its own one character operator, it's used all over the place.
- nostalgeek 8y ago> I hate function call syntax with parens. It makes code much more difficult to read and, if it supports calling functions, calling functions with args is harder than it should be. the parent has a point you have no point. foo is this a function call or a function value? foo() now it's explicit. Your sarcasm just does not work. > calling functions with args is harder than it should be care to explain? because it is not harder.
- joel_ms 8y agoIt’s a ”function value”, since you haven’t applied it to another expression. Whether that is a partially or fully applied function doesn’t matter in the first syntax, but in the second syntax you have to add ugly parens to disambiguate the partially applied function from the function call. As soon as you get serious about type-level functions, the first syntax beats the shit outta the second.
- nostalgeek 8y ago> It’s a ”function value”, since you haven’t applied it to another expression. foo bar is it calling bar then foo or passing bar as a value for foo? > As soon as you get serious about type-level functions, the first syntax beats the shit outta the second. Obviously it is not. Since you still need parenthesis for disambiguation and edge cases. foo(bar) There is no ambiguity here. Simple rules are the best ones: parentheses for all function call.
- chriswarbo 8y agoNot taking sides here, but just wanted to point out that in Haskell/Agda/Coq/Idris/etc. your `foo` would denote a function, just like writing `foo` in e.g. Javascript. Your `foo()` would call the `foo` function with the argument `()`, which is a unit value (AKA null, void, etc.). Interestingly a function which takes a unit value as argument (AKA a "thunk") is isomorphic to its return value, i.e. wrapping the body in a function doesn't change its meaning. Yet it can be useful to prevent side-effects from triggering, even if the effect is as benign as "heat up the CPU by performing lots of calculations". Now I will take sides and point out that if we have currying, all of the following are the same: f(a, b, c, d) f(a, b, c)(d) f(a, b)(c, d) f(a, b)(c)(d) f(a)(b, c, d) f(a)(b)(c, d) f(a)(b)(c)(d) f(a)(b, c)(d) Not only does this proliferation of forms over-complicate a language, but it's also completely redundant as a no-parens language would write it as `f a b c d`.
- jdreaver 8y ago> if it supports first class functions, passing around no arg functions is harder than it should be. Can you expand on that? How does no parens make it harder to pass around first class functions? In Gluon (and in Haskell, Purecsript, Idris, etc), you just pass around the function name. If you have "inc x = 1 + x" and you want to pass that to map, you just pass it by name: "map inc [1, 2, 3]" What could be simpler?
- parenthephobia 8y agoIt's impossible to pass around functions without arguments in Haskell, because there are no functions without arguments in Haskell. It looks like the same is true of Gluon. (So you don't really pass around the function name: you pass around the variable which contains the result of evaluating the expression.) In languages where there can be functions with no arguments, if referring to the function without parentheses calls it, it can be inconvenient to get a reference to the function itself.
- popnroll 8y agogetChar is a Haskell function without arguments.
- Miky 8y agoThis is false. getChar is a constant.
- popnroll 8y agoI am confused :S From your other post: "In both Gluon and Haskell, functions without arguments can be represented as functions over the unit type: f: () -> SomeType" Isn't `f` a constant here too?, how is this different than getChar? (I get I don't understand something here but not sure what)
- Rusky 8y ago
- sametmax 8y agoYeah this is what drove me off ruby. It makes scanning the code so much harder because you have to get the context of anything to understand it. Even python have a syntaxically useless ":" before idented block that makes it easier to spot.
- keymone 8y ago(a b c d) I agree, it’s much better with parens - the scope is immediately obvious.