34 ms·
Adding 'curry' is relatively easy. Difficult is the idea of implicit currying: a function call with one argument less, returns a curried function. (mapcar
by lispm 10y ago
Adding 'curry' is relatively easy. Difficult is the idea of implicit currying: a function call with one argument less, returns a curried function.
(mapcar (+ 1)
'(1 2 3))
Above does not work in Lisp, because it has variadic function arguments and no automatic currying. One would always need to explicitly write that (+ 1) should not return 1, but the function 1+. In some functional programming languages it works, because + with one argument returns a one argument function.
- kazinator 10y agoBut we can easily write a function plus such that (plus) returns (lambda (x y) (+ x y)), (plus 1) returns (lambda (y) (+ 1 y)) and (plus 1 1) just returns 2. And we can make a function writing macro to simplify writing such a function.
- lispm 10y agoTrue: but still you have to decide at definition time what kind of function it is. Plus it adds bloat to the function. Ideally the currying would be a task for the compiler/interpreter.
- kazinator 10y agoDefinition time is a big deal in static languages. For us, that could be while the app is running. I want that three arg function inside that running service to curry if called with two args, with no restart. Poof, done.
- shakna 10y agoImplicit currying sounds like a bad idea, at least for a Lisp. Most Lisps show off inbuilt functions that have side effects, such as setf in CL or set! in Scheme. Magic with side effects tends to be looked down on in the community, because it changes an incredibly simple syntax that is just about self-describing to one that has cognitive load in differing circumstances. Take pity on whoever has to come after you. My point was merely to show that it is possible. It should be also possible to add implicit currying, by messing with a read macro, but I would ask that you don't.
- kazinator 10y agoAnother consideration/angle is this. Suppose I call a three-arg function with only two args. Why should that curry in the Haskell way? That is just someone's design opinion. Suppose I want that two-arg call to return a function, but not the ordinary curried one. For instance, I might want the function to curry to a transduce kernel. Meaning, I can pass the resulting function to reduce, such that the reduce now performs a mapping through the original function. In other words, this: (map (lambda (x) (foo 1 2 x)) list) <--> (reduce (foo 1 2) list) In mainstream languages that have implicit currying, we're stuck with the one and only currying semantics.