Live data from Hacker News

A case against currying

emi-h.com

31–40 of 135 posts

Re: A case against currying

#31
With a language like Forth, you know that you can use a stack for data and apply functions on that data. With currying it you put functions on a stack instead. This makes it weird. But you also obscure the dataflow.

With the most successful functional programing language Excel, the dataflow is fully exposed. Which makes it easy.

Certain functional programming languages prefer the passing of just one data-item from one function to the next. One parameter in and one parameter out. And for this to work with more values, it needs to use functions as an output. It is unnecessary cognitive burden. And APL programmers would love it.

Let's make an apple pie as an example. You give the apple and butter and flour to the cook. The cursed curry version would be "use knife for cutting, add cutting board, add apple, stand near table, use hand. Bowl, add table, put, flour, mix, cut, knife butter, mixer, put, press, shape, cut_apple." etc..

Re: A case against currying

#32

I completely agree with the points in this article and have come to the same conclusion after using languages that default to unary curried functions. > I'd also love to hear if you know any (dis)advantages of curried functions other than the ones mentioned. I think it fundamentally boils down to the curried style being _implicit_ partial application, whereas a syntax for partial application is _explicit_. And as if…

Well, I totally disagree with this. One of the main benefits of currying is the ability to chain function calls together. For example, in F# this is typically done with the |> operator: let result = input |> foobinade a b |> barbalyze c d Or, if we really want to name our partial function before applying it, we can use the >> operator instead: let f = foobinade a b >> barbalyze c d let result = f input Requiring an e…

You can still do this though:

  let result = (barbalyze(c, d, $) . foobinade(a, b, $)) input
Or if you prefer left-to-right:

  let result = input
    |> foobinade(a, b, $)
    |> barbalyze(c, d, $)
Maybe what isn't clear is that this hole operator would bind to the innermost function call, not the whole statement.

Re: A case against currying

#33

I completely agree with the points in this article and have come to the same conclusion after using languages that default to unary curried functions. > I'd also love to hear if you know any (dis)advantages of curried functions other than the ones mentioned. I think it fundamentally boils down to the curried style being _implicit_ partial application, whereas a syntax for partial application is _explicit_. And as if…

Well, I totally disagree with this. One of the main benefits of currying is the ability to chain function calls together. For example, in F# this is typically done with the |> operator: let result = input |> foobinade a b |> barbalyze c d Or, if we really want to name our partial function before applying it, we can use the >> operator instead: let f = foobinade a b >> barbalyze c d let result = f input Requiring an e…

[deleted]

Re: A case against currying

#34
post #2

What benefit does drawing a distinction between parameter list and single-parameter tuple style bring? I'm failing to see how they're not isomorphic.

The parameter list forces the individual arguments to be visible at the call site. You cannot separate the packaging of the argument list from invoking the function (barring special syntactic or library support by the language). It also affects how singleton tuples behave in your language.

The article is about programmer ergonomics of a language. Two languages can have substantially different ergonomics even when there is a straightforward mapping between the two.

Re: A case against currying

#35
post #21

Prior to this article, I didn't think of currying as being something a person could be "for" or "against." It just is. The fact that a function of multiple inputs can be equivalently thought of as a function of a tuple can be equivalently thought of as a composite of single-input functions that return functions is about cognition, and understanding structure, not code syntax.

But it is about code syntax. Languages like Haskell make it part of the language by only supporting single-argument functions. So currying is the default behaviour for programmers. I think you are focusing on the theoretical aspect of partial application and missing the actual argument of the article which having it be the default, implicit way of defining and calling functions isn't a good programming interface.

Similar to how lambda calculus "just is" (and it's very elegant and useful for math proofs), but nobody writes non-trivial programs in it...

Re: A case against currying

#37
I've long been thinking the same thing. In many fields of mathematics the placeholder $ from the OP is often written •, i.e. partial function application is written as f(a, b, •). I've always found it weird that most functional languages, particularly heavily math-inspired ones like Haskell, deviate from that. Yes, there are isomorphisms left and right but at the end of the day you have to settle on one category and one syntax. A function f: A × B -> C is simply not the same thing as a function f: A -> B -> C. Stop treating it like it is.

Re: A case against currying

#38
post #30

I like currying because it's fun and cool, but found myself nodding along throughout the whole article. I've taken for granted that declaring and using curried functions with nice associativity (i.e., avoiding lots of parentheses) is as ergonomic as partial application syntax gets, but I'm glad to have that assumption challenged. The "hole" syntax for partial application with dollar signs is a really creative alterna…

Glad to hear the article did what I meant for it to do :)

And yes, another comment mentioned that Scala supports this syntax!

Re: A case against currying

#39

I completely agree with the points in this article and have come to the same conclusion after using languages that default to unary curried functions. > I'd also love to hear if you know any (dis)advantages of curried functions other than the ones mentioned. I think it fundamentally boils down to the curried style being _implicit_ partial application, whereas a syntax for partial application is _explicit_. And as if…

Well, I totally disagree with this. One of the main benefits of currying is the ability to chain function calls together. For example, in F# this is typically done with the |> operator: let result = input |> foobinade a b |> barbalyze c d Or, if we really want to name our partial function before applying it, we can use the >> operator instead: let f = foobinade a b >> barbalyze c d let result = f input Requiring an e…

For pipelines in any language, putting one function call per line often works well. Naming the variables can help readability. It also makes using a debugger easier:

  let foos = foobinate(a, b, input)
  let bars = barbakize(c, d, foos)
Other languages have method call syntax, which allows some chaining in a way that works well with autocomplete.

Re: A case against currying

#40
post #32

Earlier quoted context omitted.

Well, I totally disagree with this. One of the main benefits of currying is the ability to chain function calls together. For example, in F# this is typically done with the |> operator: let result = input |> foobinade a b |> barbalyze c d Or, if we really want to name our partial function before applying it, we can use the >> operator instead: let f = foobinade a b >> barbalyze c d let result = f input Requiring an e…

You can still do this though: let result = (barbalyze(c, d, $) . foobinade(a, b, $)) input Or if you prefer left-to-right: let result = input |> foobinade(a, b, $) |> barbalyze(c, d, $) Maybe what isn't clear is that this hole operator would bind to the innermost function call, not the whole statement.

Wow, this convinced me. It's so obviously the right approach when you put it this way.
Post reply on HN