Closed gampleman closed 11 years ago
I don't think this is gonna make it, CoffeeScript isn't that kind of functional language. I think underscore has sugar for this, or may want to look at @gkz /LiveScript (or wait for @michaelficarra /coffee-of-my-dreams)
@Nami-Doc, coffeescript is a functional language
@Nami-Doc: AFAIK, LiveScript only has partially-applied operators. I actually really like this proposal. This is a great partial function application syntax.
LiveScript has partialization too. (and currying of course)
a = b 1, _
LiveScript supports both partial application and currying.
Partial application - using the _
placeholder.
add = (x, y) -> x + y
add-three = add _, 3
add-three 5 #=> 8
Currying (note the function is defined with a long arrow - -->
)
add = (x, y) --> x + y
add-three = add 3
add-three 5 #=> 8
Ah, I knew about the currying, but not the _
for partial application. @gkz: I can probably look it up, but others might be interested: is _
reserved only in that context, or everywhere?
_
is reserved in a couple of contexts - this, when defining backcalls, and when used after a case
(aka |
) to mean default
.
You can still use _
normally as a variable, and it does not conflict with the use of underscore.js, for instance, as it is only reserved as a bare identifier.
_ = 5
f = g _.map
==>
var _, f;
_ = 5;
f = g(_.map);
I thought about using the underscore, but the advantage of the proposed syntax (...
) is that it is currently a compile error which means that adding it on shouldn't break any code.
It also has a natural name: the To Be Continued operator.
LiveScript doesn't conflict with underscore.js - that was my point... it would not break any code.
Also your proposal is pretty limited. If you can only omit the last argument, you might as well use currying and omit having to type anything at all. Eg.
add = (x, y) --> x + y
add-three = add 3
add-three 2 #=> 5
LiveScript's partial application syntax let's you omit any argument, and more than one:
add = (x, y, z) -> x + y + z
add-one = add _, 1, _
add-one 10, 9 #=> 20
I think it would be odd and confusing for the feature to be limited in the way you prescribe.
add 1, _
currently compiles - therefore changing its semantics would affect current code, whereas add 1, ...
doesn't. That was my point.
I am open to having it be less limited, but on the other hand the current proposal is more geared as a gentle introduction to the concept rather than a thing out of the functional programmer's dreams.
This syntax is pretty neat -- we should definitely discuss it further. My main concern about built-in partial application is use cases. Depending on how you tend to write your code, I find that partial application is extremely rare in JavaScript unless explicit in the function's API. You don't tend to do it to functions that don't do it for you...
On further consideration I do find one problem with this proposal and that is on combining this with the OOP parts of the language. Consider:
class MyQuery
constructor: (el) -> @els = document.querySelectorAll el
bind: (event, fun) -> el.addEventListener(event, fun, false) for el in @els
click: @bind('click', ...)
focus: @bind('focus', ...)
# etc...
The @bind
here would currently refer to MyQuery.bind
not to MyQuery.prototype.bind
. The more correct syntax of click: @::bind('click', ...)
does seem notably less appealing. While making this case an exception would solve this problem, it would muddle the semantics of the language.
Any ideas?
Oh, very interesting. Is the context determined at the initial call site or the final call site? That's a very good question.
I'd love to see a pull request that tries to tackle this feature...
I like partial application, I blogged about it recently: https://github.com/raganwald/homoiconic/blob/master/2013/01/practical-applications-of-partial-application.md
Using Ellipses for it seems nice.
Moving over to #2597.
There are some previous issues on currying/partial application #251, #1886, ...
They all seem kind of too complex to be of use in common everyday scripting and the form they take on seems to be hard to understand for someone unfamiliar with the concept, so I understand that they were not applied.
I would like this code:
to compile to:
I would opt to not to support stuff like: