Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

Ahh, I see what you meant. That should work with a correct currying implementation for sure


sort by: page size:

Firstly, this is definitely partial application not currying (see my other post on this thread for great expansion on this point).

Secondly, this is merely a syntactic item you're looking for. It's trivial to achieve this end in any language with first class anonymous functions. I'm not claiming that syntax isn't important, but instead just pointing out that it really is a trivial transformation to include if it were valuable enough.


Is there a typo on the Currying example?

let addToFiveAndThree = addFive(3);

Should be:

let addToFiveAndThree = addToFive(3);

I belive.


You can curry the second parameter without it being too ugly like this:

  half = (`div` 2)
Also, I think the idea with curried languages is that you're supposed to write your functions with the parameter that people are most likely to want to curry first.

Scala does that, with `_` being a "hole in the expression". I wouldn't call it currying though.

  func(param1, _)
Every once in a while you have to make some change to that expression.

  // you may want to write
  func(param1, func2(_))
  // but you need to write the full lambda
  param2 => func(param1, func2(param2))

I would go for a split of the currying and proposed solutions. Logically

  y = x |> f2(a, _)
  y = x |> f2(_, b)
are currying, but the implementation doesn't need to create functions any more than if the _ was %. And

  fb = f2(a, _)
  fa = f2(_, b)
are explicit currying which would be nice to have at times, but would mostly use in piped context at first, perhaps to give it a more meaningful or narrowed-scope name.

Is the currying example even currying? It looks like it's just a function returning a function to me. I thought currying it's some thing like func contains(subString: String, string: String) -> Bool, and calling contains("a") would automatically return a func(x: String) -> Bool.

> It strikes me as being very useful in combination with the 'apply' functions.

It's very useful with higher-order functions in general. Even more so because most of the languages with operators simply being (binary) infix function calls also default to curried functions[1], which you can easily partially apply.

Haskell also has the reverse operation (MLs probably have it as well) of being able to use a binary function as an operator: "a `foo` b" is equivalent to "foo a b", but sometimes reads much better.

[1] http://en.wikipedia.org/wiki/Currying


consider currying, exploit symmetry, or exhaust cases

Let's say you have a validation function that matches a string with a given regex, and you need to use that same logic in several places, using a different regex. Currying allows you to write something like this:

validate :: Regex -> String -> T

validate r s = ...

validateIpAddr :: String -> T

validateIpAddr = validate ipRegex

validateZipCode :: String -> T

validateZipCode = validate zipCodeRegex

And so on and so forth. It can reduce boilerplate, and lets you do stuff like map partially applied functions to functors.


This sort of scheme is fine as long is there a way of overriding any particular piece of logic on the implementer's side.

That's an interesting idea, but how does it work for functions of multiple arguments?

If functions are curried, then I suppose the syntax for `f x y` would be `y.(x.f)`, which maybe you could write as `y.x.f` if the associativity worked as such. But that means you have to provide your arguments in reverse order?

If functions are not curried, do you write `(x, y).f`?


Lo-Dash 3.0 will be getting _.curryRight, _.rearg, & _.ary to complement _.curry. With them you can easily create auto-curried flavors of functions.

  var where = _(_.where).rearg(1,0).curry().value();

Yes, and this sort of application (pun intended) is what the one-liner library is for.

If you have a function isEqualTo(a, b), you can curry(isEqualTo, 5) and filter with it.

`assign` could be used in the same way for assigning/overwriting the same field in an array of Objects, and so on.


Conspicuously missing is the brilliant new Proc.curry method!

For those that don't know currying is a method that returns another Proc with one fewer argument, so you can do: multiply = Proc.new { |x, y| x * y } multiply_by_five = multiply.curry(5) multiply_by_five.call(3) # => 15


It would be nice if [] would act as a currying function if _ isn't present.

For instance:

(map [+ 10 _] '(1 2 3))

could be rewritten as:

(map [+ 10] '(1 2 3))

Or, taken directly from the tutorial:

arc> (trues [if (odd _) (+ _ 10)] '(1 2 3 4 5))

could be rewritten as:

(trues [if [odd] [+ 10]] '(1 2 3 4 5))

which is arguably simpler and clearer.

And by the way, _ could also be usable as before such as:

(filter [> _ 10] (range 1 100)).


Ahh.. you're right, of course. What I wrote has an undefined termination condition, besides not being consistent with the original algo. Thanks.

It's a problem with ML syntax, but one that can easily be overcome with parentheses. Sort of like how a circumspect C programmer uses parentheses in complex mathematical expressions rather than relying on everyone being able to correctly remember complex order of operation rules.

OTOH, pipeline operators make a good case for currying. There really is something nice about being able to write

  sliceOfBread
  |> smearWith peanut-butter
  |> smearWith jelly
  |> topWith sliceOfBread
  |> cutInHalf
  |> eat
instead of

  eat(cutInHalf(topWith(sliceOfBread, smearWith(jelly, smearWith(peanut-butter, sliceOfBread)))))

Thanks. I'll look into that. I'm working on understanding the syntax of these rules, but it's been slow going.

That would apply only if you were switching on a variable and not a more general expression. Scala does the same thing, I think.
next

Legal | privacy