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

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();


sort by: page size:

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

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))

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 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.

Is there a typo on the Currying example?

let addToFiveAndThree = addFive(3);

Should be:

let addToFiveAndThree = addToFive(3);

I belive.


> 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


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.


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.

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)).


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)))))

You still need to declare variables before using them in an expression, though. I wish more languages would adopt the "where" syntax that Haskell and Miranda have. It lets you do things like:

  y = m*x + b
      where
      m = calculateSlope()
      b = getYIntercept()
I think this fits the literate programming style well.

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.


I would borrow the ‘where’ clause from Haskell, reducing the need for assignments in imperative code. I can imagine it as a postfix operator on its preceding expression (its code, not just its value).

consider currying, exploit symmetry, or exhaust cases

its coming soon, already available on nightly.

   let Some(x) = foo() else { return 42 };

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`?


In case you don't speak Haskell:

    IEnumerable<T>.Where(Func<T, bool> predicate)
It's quite simple to use:

    var odd_numbers = numbers.Where( n => n%2 == 1 );
next

Legal | privacy