Closed domenic closed 10 years ago
Some of the steps used to create %ThrowTypeError% can be abstracted into a separate abstract operation if we are going to need to have a number of such dynamically created functions. However, we need to look at the specific functions variations chosen for that %ThrowTypeError% and see if they also apply to your use cases. In particular, you need to think about whether these functions should be non-extensible.
Also, I notice that your functions are parametrized via closure capture fairly frequently. We don't currently have a convenient way in the specification to describe built-ins that use such "own" state. (Remember, built-ins are as likely to be implemented in C++ as JS so we can't just assume that all of the JS semantics are available in these algorithms).
I need to do something similar to specify Revocable Proxies. I try to work on it this week and will try to come up with something that also will work for you.
I don't think there's much benefit in making these functions extensible. The only observable effect is invoking them.
@annevk you have the question backwards. By default, all ES objects are extensible. If you think one needs to be non-extensible you need to justify it.
Note regarding closure capture: it's actually important for one use case that the captured variables be "let-like" as opposed to "var-like". In particular, for Promise.all
I have an index
variable that is continually updated, but then inside a "Repeat" step I do "Let currentIndex be the current value of index," and then one of my created functions uses currentIndex under the assumption that subsequent loop iterations do not change currentIndex.
Hmm.. I thought I'd already respond with this, but I can't find it. So here goes again:
I suggest you follow the pattern establish by this spec fragment:
26.2.2.1 Proxy.revocable ( target, handler ) The Proxy.revocable function takes two arguments target and handler, and performs the following: The Proxy.revocable function is used to create a revocable Proxy object When Proxy.revocable is called with arguments target and handler the following steps are taken:
26.2.2.1.1 Proxy Revocation Functions A Proxy revocation function is an anonymous function that has the ability to invalidate a specific Proxy object. Each Proxy revocation function has a [[RevokableProxy]] internal slot. When a Proxy revocation function, F, is called the following steps are taken:
Note that step 3 of the first function creates an instance of the the function described in the sub section. The per instance captured state is held in an internal data property (now called internal slots, if you want to make that change) and which is set in step 4. If you instantiate such a function in multiple places it might be worth it to create an abstract operation to do steps 3 and 4, but in this case it wasn't worth it.
Oh awesome, thanks Allen. That looks quite pleasant. Only a couple questions:
length
is, what its prototype is. Any ideas on that?They are built-in functions so all the rules in http://people.mozilla.org/~jorendorff/es6-draft.html#sec-17 apply to them.
Just describe the arguments like you would for any other built-in. For example: When an anonymous resolver function is called with arguments resolve and the following steps are taken:
This occurs with some frequency throughout the spec. The simpler cases are currently in the form:
A more complicated case is:
And
Promise.all
has an even more complicated one.The ES6 spec does not create functions and pass them to user code very often. When I asked @allenwb about this, he pointed me to the sole example of the strict-mode
function.caller
poison pill. The machinery invoked is somewhat formidable:The
ThrowTypeError
syntactic production then has to manifest under Function Definitions, with syntax:and runtime semantics under the subheading [Runtime Semantics: EvaluateBody](Runtime Semantics: EvaluateBody):
I would prefer not to have to invoke all the above machinery, changing all those different places in the spec, if at all possible. I could wrap up most of the steps in the %ThrowTypeError% definition into a reusable function-creator, but the function body specification---the most important part---would be quite difficult.
At this point I'd love some help from @allenwb on how we can abstract this into something reusable but also of sufficient formality. Our existing language is very imprecise, not specifying the function's prototype, normal vs. method vs. arrow status, scope,
length
, and so on.