Arc Forumnew | comments | leaders | submitlogin
4 points by waterhouse 5177 days ago | link | parent

I think the main problem with implicit currying is that it's basically incompatible with functions that take a variable number of arguments. E.g. should (+ a b) return a+b, or should it return (fn (c) (+ a b c))? Should (disp x) print x, or should it return (fn (out) (disp x out))? I think there is no satisfactory way for both concepts to coexist in a language.

You might just implement it for a couple of built-in functions to make them nicer (e.g. say that + or > called with one argument should probably curry rather than returning immediately) and not make it a general feature of the language, but I think that would be bad. For one thing, it wouldn't be nicer if your code contained, say, (apply + xs) when xs will have anywhere from 0-10 elements: nasty casework even if you are aware of this "feature".

Or you might say, "Well, we can certainly say that if a function f requires at least two arguments, then, when f is given only one argument, it should be curried." I think that's a bad idea too. It seems like a pretty rare case in the context of currying, and it makes things more complicated--now you have to figure out how many arguments f requires, instead of how many you intend to supply.

If you want implicit currying, I think you have to make it happen everywhere in the language, which means throwing out optional and rest parameters. (Interestingly, it does seem like it would work fine with keyword arguments.) Take a look at Haskell.

I prefer the way things are currently done. I don't find it a problem to write [> _ 4] instead of (<= 4) or something. I am annoyed whenever I have to write (fn args (apply f x args)), but if that becomes a problem, I'll write a partial macro to express it as (partial f x). ...Actually, it can just be a function.

  (def partial (f x)
    (fn args (apply f x args)))

  arc> (map (partial + 2) '(1 2 3 4))
  (3 4 5 6)
  arc> (map (partial (partial + 2) 3) '(1 2 3 4))
  (6 7 8 9)
See previous discussion as well (obtained with a Google search of "site:arclanguage.org currying").

http://arclanguage.org/item?id=3871



2 points by rocketnia 5173 days ago | link

Interestingly, it does seem like [currying] would work fine with keyword arguments.

Very interesting observation! XD It's inspiring....

Well, CSS has the slickest keyword argument API I've ever seen. The declaration "border: 2px solid black;" conveys the same information as a whole lot of other declarations like "border-top-width: 2px;", "border-bottom-style: solid;", etc. What if the "border" keyword were definable as a library?

  ; Haskellish syntax with liberties taken
  
  border width style color f = f -: border-width width
                                 -: border-style style
                                 -: border-color color
  
  border-width width f = f -: border-top-width width
                           -: border-bottom-width width
                           -: border-left-width width
                           -: border-right-width width
  
  Type Border-Top-Width  ; singleton type
  
  border-top-width value f = f -: keyword Border-Top-Width value
The premise behind -: is that it's a low-precedence left-associative binary operator such that (a -: b) is just (b a). (I don't know if Haskell has something like that already....)

The "keyword" function is axiomatic to the language. It takes a key value, a value to associate with it, and a function, and it returns the result of currying that function with that keyword information, overwriting the previous association for that key if necessary.

As for defining a function that does something with the keyword arguments it gets this way... I'm out of steam for now. What do you think?

EDIT: Hmm. With currying, we consider two-argument functions to be indistinguishable from functions that return functions, right? If a programmer naturally wants to write a two-argument function that takes keyword arguments, should that be a keyword-taking function that returns a plain function, a plain function that returns a keyword-taking function, or what? What about keyword-taking functions that naturally have zero arguments? Maybe currying and keyword arguments aren't very compatible after all, or maybe they just need a different evaluation model. (Maybe keywords should be dynamic variables observed using an "I'll consume this whole subspace of keywords, thanks" syntax?)

-----