5 ms·
> 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
by 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`getChar` is not of type `() -> SomeType`, but directly of type `SomeType`. (Though yes, `f` also is a constant... it's just a constant that happens to be a function, which `getChar` is not.)
- somenewacc 8y agoIn Haskell, getChar isn't a function (something of type a -> b), its type is IO Char http://hackage.haskell.org/package/base-4.11.1.0/docs/Prelude.html#v:getChar http://hackage.haskell.org/package/base-4.11.1.0/docs/Prelud... It represents an interaction with the outside world that results in a Char when you perform it. It isn't a function because in Haskell functions must be pure (with no side effects).
- tome 8y agoI feel the responses to you were somewhat unhelpful. Would they also claim that something of type `MyFun Char` is not a function, where data MyFun a = MyFun (() -> Char) Technically they'd be right.
- Miky 8y agoIn both Gluon and Haskell, functions without arguments can be represented as functions over the unit type: f: () -> SomeType which can be called via: f () There are examples of this in the Gluon book (http://gluon-lang.org/book/syntax-and-semantics.html http://gluon-lang.org/book/syntax-and-semantics.html). There are no syntax-related difficulties at all here. This is also how it's done in OCaml and related languages. (Note: This is (basically) useless in Haskell, since laziness makes this have the same semantics as a constant: f :: SomeType But since Gluon is strict, there's a pretty important difference between the two.)
- mkl 8y agoHow 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. (I last used Haskell in about 1999.) It's certainly ambiguous to outsiders, which is kind of the point of the discussion. Simpler would be something like Python: map(inc, [1, 2, 3]). No ambiguity.
- azdavis 8y agoFunction application in most languages in which 'f x' means 'apply the function f to the argument x' is left associative. So `map inc [1,2,3]` is the same as `(map inc) [1,2,3]`. This is consistent with the fact that -> is right associative. So in Haskell, we usually say map :: (a -> b) -> [a] -> [b] Which is usually interpreted as 'If you give me a function which can turn a's into b's, and then you give me a list of a's, I can give you a list of b's.' But it is exactly equivalent if we write the type of map like this: map :: (a -> b) -> ([a] -> [b]) Which I like to read as 'If you give me a function which can turn a's into b's, I can give you a function which turns a list of a's into a list of b's. It's certainly the case that ML-style languages have a syntax that can be unfamiliar to outsiders, but I would disagree that the syntax is ambiguous. Indeed, Standard ML (another functional language) is one of the few languages to be formally specified.
- mkl 8y agoOkay. I know a lot of languages, but not really functional ones (I have used Haskell, OCaml and Lisp (though that's not like this), but not much and long ago). Maths is more type-dependent in the absence of parentheses. E.g. sin cos⁻¹ x = sin(cos⁻¹(x)), but A cos⁻¹ x = A × cos⁻¹(x). By "ambiguous" I mean to people looking at the code. Obviously it's unambiguous and well-defined to the computer.
- Athas 8y agoThe rule is simple to learn and perfectly consistent once you know it, even to a human programmer. This is in direct contrast to mathematical notation, which remains ambiguous and context-dependent forever. While it's been over a decade since I first learnt this style of functional languages, I don't remember being confused by application syntax. It also helps that function application binds more tightly than anything else. I don't think it's any great indictment that it is not immediately understandable to someone who does not know the rule. There will be lots of other things someone will not be able to understand in a Gluon program, unless they know Gluon. It's perfectly reasonable to expect someone to learn a programming language before they write code in it.
- eximius 8y agoI didn't say it was unambiguous, just hard to read. Literally visually parsing it is more difficult than with parens. Depending on how dense the code is, it isn't that bad. But it is another barrier to understanding.
- laurentlb 8y agoThis means you have to rely on precedence, or add your own parens. For example, how do you read this? f -4 In F#, whitespace is significant (and it's a function call); in OCaml, it's a subtraction. The idea of wrapping a negative number with parens is not necessarily obvious.