forward-incompatible Function.prototype.toString requirement

Mark S. Miller erights at google.com
Thu Apr 16 14:57:31 UTC 2015


On Thu, Apr 16, 2015 at 6:55 AM, Mark S. Miller <erights at google.com> wrote:

>
>
> On Thu, Apr 16, 2015 at 6:36 AM, Andreas Rossberg <rossberg at google.com>
> wrote:
>
>> On 16 April 2015 at 14:34, Frankie Bagnardi <f.bagnardi at gmail.com> wrote:
>>
>>> The part that sticks out to me is... toString on functions currently
>>> throws a syntax error when eval'd for non-named functions.  Tested in
>>> chrome:
>>>
>>> var f = function(){ return 1 };eval(f.toString()); // SyntaxError
>>> // becausefunction(){ return 1 }; // SyntaxError
>>> // but, force an expression: eval("(" + f.toString() + ")") // essentially clones f
>>>
>>>>>> This... is confusing in my opinion.
>>>
>>
>> Yeah, the spec says:
>>
>> "The string representation must have the syntax of a FunctionDeclaration
>> FunctionExpression, GeneratorDeclaration, GeneratorExpression,
>> ClassDeclaration, ClassExpression, ArrowFunction, MethodDefinition, or
>> GeneratorMethod depending upon the actual characteristics of the object."
>>
>> which is weird. First, it doesn't really make sense, because whether
>> something originates from a declaration vs expression isn't a
>> "characteristic of the object". Second, making it return different
>> syntactic classes in different cases is not particularly useful for your
>> case.
>>
>> But then again, using the result of f.toString as input to eval is A REAL
>> BAD IDEA anyway; toString should only be used for diagnostics, not
>> programmatically, because that is meaningless in general. So I personally
>> don't mind the friction.
>>
>
> Disagree. The purpose of this change in toString spec from ES5 is
> primarily to support pass-by-copy closed functions. The intent was that it
> always work to evaluate them as expressions, i.e., with the surrounding
> parens.
>
> http://wiki.ecmascript.org/doku.php?id=harmony:function_to_string
>


Hmmm. Looking again, where the strawman says:

if eval()uated in an equivalent-enough lexical context, would result in a
function with the same [[Call]] behavior as the present one. Note that the
new function would have a fresh identity and none of the original’s
properties, not even .prototype. (The properties could of course be
transferred by other means but the identity will remain distinct.)


the spec text at <
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-function.prototype.tostring>
says only

if the string is evaluated, using eval in a lexical context that is
equivalent to the lexical context used to create the original object, it
will result in a new functionally equivalent object.


This "functionally equivalent" is bizarrely vaguer than "same [[Call]]
behavior" and, if taken literally, is clearly wrong. As the strawman (but
not the spec) says clearly, evaling the returned string is not expected to
replicate the properties of the original function object. And of course it
cannot replicate the original function's identity.

Allen, is this a spec bug, or was this weakening intentional? If so, why?




>
> http://wiki.ecmascript.org/doku.php?id=strawman:concurrency#there
>
>
>
>
>>
>> /Andreas
>>
>>
>>
>>>
>>>
>>> On Thu, Apr 16, 2015 at 2:56 AM, Andreas Rossberg <rossberg at google.com>
>>> wrote:
>>>
>>>> On 16 April 2015 at 11:34, Michael Ficarra <mficarra at shapesecurity.com>
>>>> wrote:
>>>>
>>>>> ES2015 section 19.2.3.5 (Function.prototype.toString) places four
>>>>> restrictions on the output of Function.prototype.toString, one of which is
>>>>>
>>>>> If the implementation cannot produce a source code string that meets
>>>>>> these criteria then it must return a string for which *eval* will
>>>>>> throw a *SyntaxError* exception.
>>>>>>
>>>>>
>>>>> What is a SyntaxError today may not be a SyntaxError tomorrow. How can
>>>>> an implementation return a string that will satisfy this requirement in the
>>>>> future when the language has added new syntax? Does the committee have a
>>>>> SyntaxError recommendation that can be added as a non-normative note to
>>>>> that section?
>>>>>
>>>>
>>>> In the (probably unlikely) case that the language changed that way, and
>>>> an affected implementation adopted that change, then it would simply have
>>>> to change its toString implementation accordingly at that point. I don't
>>>> see a problem there.
>>>>
>>>> /Andreas
>>>>
>>>>
>>>> _______________________________________________
>>>> es-discuss mailing list
>>>> es-discuss at mozilla.org
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>
>>>>
>>>
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
>
> --
>     Cheers,
>     --MarkM
>



-- 
    Cheers,
    --MarkM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150416/56dba654/attachment.html>


More information about the es-discuss mailing list