Jack-Works / proposal-strict-built-in-functions

1 stars 2 forks source link

What do you mean by “strict function” #3

Open claudepache opened 4 years ago

claudepache commented 4 years ago

By definition, a strict function, resp. a non-strict function, is an ECMAScript function whose code is in strict mode code, resp. non-strict mode code. Such a definition makes sense only for ECMAScript functions.

But you seem to give some other meaning for “strict” that would apply to non-ECMAScript functions (as builtin functions are, in practice, most often non-ECMAScript). I tried to think of some reasonable definition, but I couldn’t find one.

So, what do you mean exactly by “strict function”?

ljharb commented 4 years ago

Given that it’s observable from outside wrt arguments/caller, it makes sense to me for any function of any origin.

claudepache commented 4 years ago

@ljharb If a function is not censored for .caller and .arguments, then it is non-strict. But the implication goes only in one direction, so it cannot be used as a criterion for distinguishing between strict and non-strict. For instance, in JSC (and possibly other engines), it is impossible to distinguish between a non-strict generator function and a strict generator function using only .arguments and .caller.

I have guessed that there could have been some relation with the behaviour of .caller and .arguments, but, as I said, it didn’t suggested to me any reasonable definition of “strict”.

Jack-Works commented 4 years ago

I had a misunderstood about strict. I thought all functions are strict or nonstrict. I thought it is binary.

Now I know the "strict" only used in ECMAScript functions. With this nonbinary meaning, any words of "strict function" or "non-string function" will become a dangerous trap.

As you can see, we fall into this trap (.caller must not be a strict function, the editor might think that equals to "loose" functions), I think it's better to specify the "strictness" of non-ECMAScript functions so the "strict/nonstrict" can be a binary relation and never fall in to bug like this case.

e.g. All built-in function will be treated as strict (in the comparison like "must be strict" or "must not be strict") The bound function (returned by f.bind()) is strict when f is strict, vice verse.

ljharb commented 4 years ago

I also see it more as, “is this function sloppy? If i can’t determine that it is, including by looking at the code, then it’s strict”

claudepache commented 4 years ago

Ok, I’m still unconvinced, but let me go to the point. Why do we want a distinction between “strict” and “non-strict” non-ECMAScript function? Is it just for restrictions around .caller and .arguments, or are there other uses?

ljharb commented 4 years ago

Why do we care if a function is non-ECMAScript or not? ECMAScript functions may or may not have source available, so I'm not sure why it matters.

claudepache commented 4 years ago

@ljharb What I care about, is that the notion of “strict function” be sound with a clear purpose.

Jack-Works commented 4 years ago

There is not many use case of strict or non-strict and it might not increase in the future. So another way is to review all the current use cases of strict and non-strict to see if there is any that uses the term that not reflecting the design purpose (and might cause a bug).

hax commented 4 years ago

ECMAScript functions may or may not have source available

@ljharb I am not sure what that mean. Isn't ECMAScript functions always have ECMAScript code by definition?

ljharb commented 4 years ago

@hax function () {}.bind() is an ecmascript function that does not have source text available.

hax commented 4 years ago

@ljharb As I understand bound functions are not ECMAScript functions.

ljharb commented 4 years ago

ok, fair enough - then both of the implementation hiding proposal, or the Function.prototype.toString source hook that's already in the spec, can allow ECMAScript functions without available source text ¯\_(ツ)_/¯

hax commented 4 years ago

@ljharb They only hide source for the 3rd party libraries in runtime, seems no relation to engines?

ljharb commented 4 years ago

Engines have source text available for their c++ functions, it’s just not JS code.

claudepache commented 4 years ago

The issue of availability of source code is off-topic; it is orthogonal both to the issue of strictness and to the issue of .caller and .arguments.

Jack-Works commented 4 years ago

@erights I have mentioned my idea here https://github.com/Jack-Works/proposal-strict-built-in-functions/issues/3#issuecomment-577789819

I think it's better to specify every kind of non-ES functions case by case so .bind can specify its result as a non-strict function.

So on this purpose maybe it no longer gets covered by Claude's proposal. Maybe we should re-add it as a separate work?

erights commented 4 years ago

First, we made stage 1. Congrats to us!

What is the current behavior of bound functions? Can someone do these same tests across browsers? Thanks.

ljharb commented 4 years ago

@erights can you give me some code? i can run it in eshost.

erights commented 4 years ago

@claudepache do you have the code you tested with?

To be clear, what made it to stage 1 is the combination of the two proposals.

claudepache commented 4 years ago

Le 6 févr. 2020 à 03:33, Mark S. Miller notifications@github.com a écrit :

 First, we made stage 1. Congrats to us!

What is the current behavior of bound functions? Can someone do these same tests across browsers? Thanks.

See https://github.com/claudepache/es-legacy-function-reflection/issues/6#issuecomment-575162851

—Claude

ljharb commented 4 years ago
try {
        print((function(){}).caller);
} catch (e) { print(e); }

try {
        print((function(){}).bind().caller);
} catch (e) { print(e); }

yields:

#### ch
null
TypeError: 'arguments', 'callee' and 'caller' are restricted function properties and cannot be accessed in this context

#### Chakra
null
TypeError: 'arguments', 'callee' and 'caller' are restricted function properties and cannot be accessed in this context

#### JavaScriptCore
null
TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context.

#### jsc
null
TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context.

#### sm
null
TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

#### SpiderMonkey
null
TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

#### v8
null
TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

#### V8
null
TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

#### V8 --harmony
null
TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

#### xs
undefined
TypeError: ?: strict mode
claudepache commented 4 years ago

Le 6 févr. 2020 à 03:57, Mark S. Miller notifications@github.com a écrit :

 @claudepache do you have the code you tested with?

Here are some tests:

https://github.com/claudepache/es-legacy-function-reflection/blob/master/simple-tests.js

For bound functions and proxies, you may need to carefully follow their semantics in order to correctly interpret the results.

claudepache commented 4 years ago

For bound functions and proxies, you may need to carefully follow their semantics in order to correctly interpret the results.

More precisely: