LiveScript
LiveScript copied to clipboard
--> function binder shorthand?
for example, i have this code:
api =
method: (me) -> !->
me.flag = true
it compiles to:
api = {
method: function(me){
return function(){
me.flag = true;
};
}
};
later, i iterate a list of those methods and bind them with this code:
for name in apiList
@[name] = api[name] @
i could do:
for name in apiList
@[name] = api[name].bind @
but with multiple objects, function.prototype.bind works slow.
what you think about this syntax:
api =
method: (me) !-->
me.flag = true
..or, if it does return something, it could be --> without !. i could use let syntax, but it creates binder functions each time. how to approach this?
hmm.. not good. sorry. ->-> is okay.. was in hurry.... wanted to use @ inside those methods..
I'm sorry, I don't quite understand what you're proposing... perhaps you figured out that --> already means something? What should be shorthand for what here?
well, i thought about this syntax
method = (param1, param2) !-->
@property = true
to this syntax
method = function(this$) {
return function(param1, param2) {
this$.property = true;
};
};
so, it will act like bind with only first parameter thisArg specified (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind)
--> - is free, it does not generate any syntax, only simple function.
It looks very implicit.. ye. but if you know how you defined it shouldn't be the problem. shorthand is for both function and first parameter that will become @ inside the body.
method = (param1, param2) !-->
@property = true
currently produces a curried function, so that exact syntax is out.
However, there's precedent for ‘assigning to this’ with the let keyword, so perhaps instead of yet another arrow variant, could we compromise on the below?
method = (this) -> (param1, param2) !~>
@property = true
(The ~ would be necessary to keep the inner function using the same this as the outer one.)
It's more verbose than your proposal, but also more explicit and made of more reusable parts.
oh, i didn't noticed that with parameters it will be curried function...
well, i like (this) -> (param) ~> more than (me) -> (param) ->, ye, it will be more useful,
but it doesnt work for now, says compile error..
in case, when there is no parameters in the inner function it will be:
method = (this) -> !~>
@property = true
which doesn't look great, right?
what about using more compact syntax with this or @ as the first parameter to make binder:
method1 = (this) !~>
@property = true
method2 = (this, param1, param2) !~>
@property = true
hmm.. docs are saying that ~> creates a bound function, so,
some crazy idea came now, it probably can be used to create variable binder like:
method1 = (this, boundParam1, param2, param3) !~~>
@property = true
method2 = (this, boundParam1, boundParam2, param3) !~~~>
@property = true
or better
method1 = (this, boundParam1, [param2, param3]) !~>
@property = true
method2 = (this, boundParam1, boundParam2, [param3]) !~>
@property = true
but i compromise to your variant, anyway
Repeating the ‘shaft’ of a function arrow (-> to -->, ~> to ~~>, etc.) is the cue to make the function curried, so we can't use that as a clue for how many parameters should be bound.
On principle, I'm opposed to two things that these last few suggestions would require:
- creating the equivalent of more than one function with a single (non-curried) arrow symbol
- letting the presence of
thisin the parameter list significantly change how the rest of the parameter list is interpreted
I'll take this in parameter lists as a low priority feature for now. There are possibly some issues that I need to think about further—consider the following:
f = (this, a = @a) -> a
should probably compile to
var f;
f = function(this$, a){
a == null && (a = this$.a);
return a;
};
and
f = (a, {obj: this} = a) -> @foo
should compile to
var f;
f = function(a, arg$){
var this$;
this$ = (arg$ != null ? arg$ : a).obj;
return this$.foo;
};
but then for consistency, I think
f = (a = @a, {obj: this} = a) -> @foo
has to compile to
var f;
f = function(a, arg$){
var this$;
a == null && (a = this.a);
this$ = (arg$ != null ? arg$ : a).obj;
return this$.foo;
};
so the effect of this-parameters can reach forward but not backward through the parameter list. I think that's probably fine? Anyone else think that this is possibly fishy, or see anything else wrong with the proposal?
Okay, i understand your first example, but the rest look complicated to me, why not reduce the syntax trigger to only the first this parameter specified, for now, and in other cases, drop syntax errors?
That will be easier, i think, and maybe later you will come up with other cases.
Also, you skipped binder variant, how do you see binder?
i mean something like this:
method = (this, param1, [param2, param3]) !~>
@property = true
to
var method = function(this$, param1) {
return function(param2, param3) {
this$.property = true;
};
};
..using this as first parameter perfectly fits the MDN docs (about .bind)
Again, I don't want to create more than one function with a single arrow symbol. So to create that JavaScript code, which contains a function that returns a function, you'd write
method = (this, param1) -> (param2, param3) !~>
@property = true
Sorry if I confused you with all those other examples; they weren't meant to apply to your use case. What I'm trying to do is show the implications of letting this be bound in a function parameter, and how that would interact with other advanced features of function parameters in LiveScript. It's important for us to work through potentially complicated interactions before we put new features in, to make sure that we don't box ourselves into any corners that it would then be hard to get out of without breaking backwards compatibility.
Okay, now i got it.