Necessity of a syntax construct for bind
You may be interested in code.google.com/p/es-lab/source/browse/trunk/src/ses/repairES5.js#1283
A reason your exercise is more pressing than it may seem is that f.p.bind is still missing on WebKit Nightly. See < bugs.webkit.org/show_bug.cgi?id=26382#c29>. I agree with your
assessment that it is not possible to do a conformant implementation in JavaScript.
On Tue, Aug 30, 2011 at 6:42 PM, David Bruant <david.bruant at labri.fr> wrote:
Hi,
A couple of people (including myself) have been working on trying to implement a Function.prototype.bind pure-JS implementation as close to the spec as possible. Despite the fact that this is impossible, all implementations relied on the built-in Function.prototype.call (or Function.prototype.apply).
I've had that problem in other cases too.
It's interesting that .call/.apply can't be protected from tampering without freezing them. If there was a function, say Function.callFunction, that allowed you to write the equivalent of foo.call(bar, baz) as Function.callFunction(foo, bar, baz), then you could store a copy of callFunction in a safe place and not have to worry about Function.prototype.call being modified.
Any attempt I have tried of extracting the call functionality without leaving a visible trace on the existing objects can be thwarted. Most other functions can be extracted to local variables and called later on the appropriate object (using .call) if you want to save an environment.
A syntax construct allowing reliable binding without having me to go over one of the previous solutions would be welcome I think.
A reliable .call could probably also achieve the same.
Le 30/08/2011 21:59, Lasse Reichstein a écrit :
On Tue, Aug 30, 2011 at 6:42 PM, David Bruant <david.bruant at labri.fr <mailto:david.bruant at labri.fr>> wrote:
Hi, A couple of people (including myself) have been working on trying to implement a Function.prototype.bind pure-JS implementation as close to the spec as possible. Despite the fact that this is impossible, all implementations relied on the built-in Function.prototype.call (or Function.prototype.apply).
I've had that problem in other cases too.
It's interesting that .call/.apply can't be protected from tampering without freezing them. If there was a function, say Function.callFunction, that allowed you to write the equivalent of foo.call(bar, baz) as Function.callFunction(foo, bar, baz), then you could store a copy of callFunction in a safe place and not have to worry about Function.prototype.call being modified.
True. I admit that i'm currently doing some JS static analysis and i realize how much i prefer syntax over functions since syntax tends to be easier to analyse statically. With syntax you never wonder "has the semantic of this been overridden?" "if so, has the semantics changed?" the latter question being in general undecidable i think.
Any attempt I have tried of extracting the call functionality without leaving a visible trace on the existing objects can be thwarted. Most other functions can be extracted to local variables and called later on the appropriate object (using .call) if you want to save an environment.
A syntax construct allowing reliable binding without having me to go over one of the previous solutions would be welcome I think.
A reliable .call could probably also achieve the same.
A reliable .call could be achieved by composing a reliable .bind and the function call syntax. However, due to the current impossibility to emulate .bind with .call I'm doubtful that a reliable .bind (per ES5.1 15.3.4.5) is possible by composition of a reliable .call and other things. Based on harmony:spread [1], i think it could be possible to have a reliable .apply based on a reliable .bind and function call syntax.
Consequently, I have the impression that syntax for a reliable .bind would be a good fundamental brick to add to build the rest.
David
[1] harmony:spread
On Tue, Aug 30, 2011 at 11:46 PM, David Bruant <david.bruant at labri.fr>wrote:
Le 30/08/2011 21:59, Lasse Reichstein a écrit :
A reliable .call could probably also achieve the same.
A reliable .call could be achieved by composing a reliable .bind and the function call syntax.
True. The Bind operation is the currying of the Call operation.
Ah, that got me thinking. I can do var CallFunction = Function.prototype.call.bind(Function.prototype.call); since bind does give a different way to set the this-object for a call. This can be done once, before anybody gets to mangle the builtins, and can be stored for afterwards. Excellent!
Le 31/08/2011 10:52, Lasse Reichstein a écrit :
On Tue, Aug 30, 2011 at 11:46 PM, David Bruant <david.bruant at labri.fr <mailto:david.bruant at labri.fr>> wrote:
Le 30/08/2011 21:59, Lasse Reichstein a écrit :
A reliable .call could probably also achieve the same.
A reliable .call could be achieved by composing a reliable .bind and the function call syntax.
True. The Bind operation is the currying of the Call operation.
Ah, that got me thinking. I can do var CallFunction = Function.prototype.call.bind(Function.prototype.call); since bind does give a different way to set the this-object for a call. This can be done once, before anybody gets to mangle the builtins, and can be stored for afterwards. Excellent!
Brilliant!
Of course, it requires a native Function.prototype.bind, but that's brilliant!
This is my first reply on es-discuss, so my apologies if I've done something incorrectly and this doesn't get properly routed.
David and Lasse, I'd like to direct you to kriskowal/es5-shim and, in particular, pull request #43: kriskowal/es5-shim#43
In that series of commits, I removed all runtime dependence on the
environment and bootstrapped Function.prototype.bind while relying only on
the existence of Function.prototype.call at definition time and with no
dependencies at runtime. This allows me to call any function using
call(functionName, thisArg, argument0, argument1, ...)
. I also used that
to bootsrap a similar apply
function. The general idea behind
bootstrapping a bind method was to make a sub-par call
and apply
implementation that relied on Function.prototype.call.call
, but replacing
them after defining bind by using our new bind method similarly to how you
suggested. It'd probably be easier to just read the code, though, than have
me continue trying to explain it.
Michael Ficarra
---------- Forwarded message ----------
On Aug 31, 2011, at 2:28 AM, David Bruant wrote:
Le 31/08/2011 10:52, Lasse Reichstein a écrit :
On Tue, Aug 30, 2011 at 11:46 PM, David Bruant <david.bruant at labri.fr> wrote: Le 30/08/2011 21:59, Lasse Reichstein a écrit :
A reliable .call could probably also achieve the same. A reliable .call could be achieved by composing a reliable .bind and the function call syntax.
True. The Bind operation is the currying of the Call operation.
Ah, that got me thinking. I can do var CallFunction = Function.prototype.call.bind(Function.prototype.call); since bind does give a different way to set the this-object for a call. This can be done once, before anybody gets to mangle the builtins, and can be stored for afterwards. Excellent! Brilliant!
That is a head-spinner -- well-done, Lasse.
Le 31/08/2011 19:56, Michael Ficarra a écrit :
This is my first reply on es-discuss, so my apologies if I've done something incorrectly and this doesn't get properly routed.
David and Lasse, I'd like to direct you to kriskowal/es5-shim and, in particular, pull request #43: kriskowal/es5-shim#43
In that series of commits, I removed all runtime dependence on the environment and bootstrapped Function.prototype.bind while relying only on the existence of Function.prototype.call at definition time and with no dependencies at runtime. This allows me to call any function using
call(functionName, thisArg, argument0, argument1, ...)
. I also used that to bootsrap a similarapply
function. The general idea behind bootstrapping a bind method was to make a sub-parcall
andapply
implementation that relied onFunction.prototype.call.call
, but replacing them after defining bind by using our new bind method similarly to how you suggested. It'd probably be easier to just read the code, though, than have me continue trying to explain it.
So if I understand correctly, the relevant part of code to remove the dependency to the runtime Function.prototype.call is the following:
var nativeCall = Function.prototype.call; var nativeApply = Function.prototype.apply; nativeCall.call = nativeCall; // adding an own "call" property to the native call
// assuming there is no native bind var apply = function (fn, context, args) { return nativeCall.call(nativeApply, fn, context, args); }, call = function (fn, context) { return apply(fn, context, nativeCall.call(nativeArraySlice, arguments, 2)); };
Function.prototype.bind = function bind(that){ // no dependency on runtime Function.prototype.call // but dependency on runtime nativeCall.call // and dependency on runtime variable "call" }
call = Function.prototype.bind.call(nativeCall, nativeCall); apply = Function.prototype.bind.call(nativeCall, nativeApply);
The idea of defining an own "call" property to nativeCall is interesting, because it indeed allows to do nativeCall.call without depending on redefinition of Function.prototype.call. However, it only shifts the problem to the runtime value of Function.prototype.call.call (all dots refer to an own property, even the last one). In order to protect yourself from this dependency, you could define nativeCall.call as non-writable and non-configurable (in platforms allowing this). Another idea would be to remove your dependency to nativeCall.call and replace it with only "call" (which at the end is a new function which no one should have access to unlike Function.prototype.call).
Regardless, the dance where you first define a call function, use it to define Function.prototype.bind, use bind to redefine call to make it independent of other things is a very interesting move!
Thanks,
A couple of people (including myself) have been working on trying to implement a Function.prototype.bind pure-JS implementation as close to the spec as possible. Despite the fact that this is impossible, all implementations relied on the built-in Function.prototype.call (or Function.prototype.apply). Also, Function.prototype.bind is writable and configurable. This leads to the situation that, on my code, when i write f.bind(obj), it is either unreliable or for it to be reliable, i am forced to make at least Function.prototype.bind non-configurable (and non-writable or a getter that returns the same and correct value) (and do the same thing to Function.prototype.call/apply if i'm emulating Function.prototype.bind) or add a bind own property to every function i am susceptible to bind.
A syntax construct allowing reliable binding without having me to go over one of the previous solutions would be welcome I think.
The CoffeeScript-inspired arrow_function_syntax strawman [1] seems to have such a syntactic construct (though i'm not really sure i understand it, i'd need more examples). What i wish is a syntax equivalent to Function.prototype.bind (which would take a function and an object as input and generate a bound function as output)
David
[1] strawman:arrow_function_syntax
Ps : I sent this message already on August 19th and August 26th, but i haven't seen it popping up on es-discuss, sorry for the spam if it appears several times