Re: LR(1) grammar/parser and lookahead-restrictions
On 01/11/2017 10:28, Michael Dyck wrote: In the past, it has been said (usually by Brendan Eich) that TC39 intends that the ECMAScript grammar be LR(1). Is that still the case? (I'm not so much asking about the "1", but more about the "LR".) If so, I'm wondering how lookahead-restrictions (e.g., [lookahead I'm the source of the LR(1) condition. I've been doing that ever since ECMAScript Edition 3, and in fact am using the LR parser to help design and debug the spec. I have an implementation of the parser with a few extensions to the LR grammar, including support for parametrized productions, lookahead restrictions, and lexer-parser feedback used to disambiguate things such as what token / will start. I validate various things such as making sure that there is no place where both an identifier and a regular expression can occur. Waldemar ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Determining if an object can be constructed
Actually it's possible to create pretty good heuristics to decide if it's possible to call function as constructor, but there is no way to be sure it's really safe. On Mon, Jan 23, 2017 at 7:49 PM, Jordan Harbandwrote: > Unfortunately, the only practical way to know that without risking side > effects is to read the human-produced documentation on the function, or to > have a human read the code. > > On Mon, Jan 23, 2017 at 8:19 AM, Isiah Meadows > wrote: > >> I'll point out that all I need is some way to detect anything that is >> callable except for classes. Basically, anything that has a `[[Call]]` that >> doesn't throw unconditionally without entering a different scope (like >> classes, but not %ThrowTypeError%). >> >> And to clarify, these would both be included per above, since it does >> enter a different scope: >> >> ```js >> // New language scope >> function foo() { >> throw new TypeError() >> } >> >> // New native scope (%ThrowTypeError%) >> "use strict" >> var foo = Object.getOwnPropertyDescriptor( >> arguments, "callee" >> ).get >> ``` >> >> `Reflect.isConstructor` isn't sufficient for my needs, since it would >> still consider the first `foo` above to be a constructor. >> >> On Sat, Jan 21, 2017, 01:14 Jordan Harband wrote: >> >>> The reality here is that we're all playing around what the definition of >>> "constructor" and "callable" mean. >>> >>> In the spec, "constructors" are defined as having a `[[Construct]]` >>> internal slot; something is "callable" if it has a `[[Call]]` internal >>> slot. By that definition (https://tc39.github.io/ecma26 >>> 2/#sec-isconstructor and https://tc39.github.io/ecma262/#sec-iscallable), >>> a `class` constructor is indeed callable (because it's defined to have >>> `[[Call]]` throw a `TypeError`). Similarly, as defined in the spec, `typeof >>> class Foo {}` is "function" only because it has a `[[Call]]` internal slot ( >>> https://tc39.github.io/ecma262/#table-35); if constructors lacked a >>> `[[Call]]` slot (such that `IsConstructor` returned `true` for them), then >>> `typeof someConstructor` would return "object". >>> >>> Obviously the committee could have chosen to define these things >>> differently; but this is how things are defined. >>> >>> >>> >>> I'm going to claim that conceptually - eg, to the majority of users - >>> something is a constructor when it's *intended* to be used with `new`. In >>> other words, "what it returns" isn't actually the point - if you're "meant" >>> to use it with `new`, it's a constructor, otherwise, it's a function - and >>> functions that work with both can be thought of as a dual >>> constructor/factory (the factory calls the constructor for you). However, >>> that conceptual definition is not one that can be programmatically >>> determined, because "programmer intention" in this regard simply isn't >>> inherently enshrined in an observable way, whether choosing `class` or >>> `function`. >>> >>> Personally I think it would be wonderful to expose `IsConstructor` >>> (`IsCallable` is already exposed via `typeof` returning "function"), but I >>> feel quite confident that neither actually address any of the use cases in >>> this thread. >>> >>> In addition, "safe to call" or "safe to use with `new`" all depends on >>> your definition of "safe", and it's clear from this thread that that does >>> not have a universally agreed-upon definition either. >>> >>> It might be useful to distill things down to 1) concrete use cases for >>> calling or instantiating a function where you don't already know what it >>> does, and can't assert in your human documentation what you expect; 2) a >>> definition of "constructor", either a different one if you don't agree with >>> mine above, or if you do, a form of mine that can be programmatically >>> determined, and 3) a definition of "safe" which means more than "doesn't >>> throw an exception". >>> >>> On Fri, Jan 20, 2017 at 6:52 PM, Scott Sauyet wrote: >>> >>> Bradley Meck wrote: >>> >> 1. every call to `new Foo(...args)` creates a distinct object not >>> >> reference-equal to any other such call. >>> > >>> > Would this mean >>> > >>> > ``` >>> > function factory() { return []; } >>> > ``` >>> > >>> > would qualify as a constructor? >>> >>> I'm thinking of that as a necessary, but not a sufficient condition. >>> >>> If it fails that test it cannot be a constructor. It's clear that >>> there are other tests. It's not clear to me what they are. >>> >>> -- Scott >>> ___ >>> es-discuss mailing list >>> es-discuss@mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >>> ___ >>> es-discuss mailing list >>> es-discuss@mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >> > > ___ > es-discuss mailing list > es-discuss@mozilla.org >
Re: Determining if an object can be constructed
Unfortunately, the only practical way to know that without risking side effects is to read the human-produced documentation on the function, or to have a human read the code. On Mon, Jan 23, 2017 at 8:19 AM, Isiah Meadowswrote: > I'll point out that all I need is some way to detect anything that is > callable except for classes. Basically, anything that has a `[[Call]]` that > doesn't throw unconditionally without entering a different scope (like > classes, but not %ThrowTypeError%). > > And to clarify, these would both be included per above, since it does > enter a different scope: > > ```js > // New language scope > function foo() { > throw new TypeError() > } > > // New native scope (%ThrowTypeError%) > "use strict" > var foo = Object.getOwnPropertyDescriptor( > arguments, "callee" > ).get > ``` > > `Reflect.isConstructor` isn't sufficient for my needs, since it would > still consider the first `foo` above to be a constructor. > > On Sat, Jan 21, 2017, 01:14 Jordan Harband wrote: > >> The reality here is that we're all playing around what the definition of >> "constructor" and "callable" mean. >> >> In the spec, "constructors" are defined as having a `[[Construct]]` >> internal slot; something is "callable" if it has a `[[Call]]` internal >> slot. By that definition (https://tc39.github.io/ >> ecma262/#sec-isconstructor and https://tc39.github.io/ >> ecma262/#sec-iscallable), a `class` constructor is indeed callable >> (because it's defined to have `[[Call]]` throw a `TypeError`). Similarly, >> as defined in the spec, `typeof class Foo {}` is "function" only because it >> has a `[[Call]]` internal slot (https://tc39.github.io/ecma262/#table-35); >> if constructors lacked a `[[Call]]` slot (such that `IsConstructor` >> returned `true` for them), then `typeof someConstructor` would return >> "object". >> >> Obviously the committee could have chosen to define these things >> differently; but this is how things are defined. >> >> >> >> I'm going to claim that conceptually - eg, to the majority of users - >> something is a constructor when it's *intended* to be used with `new`. In >> other words, "what it returns" isn't actually the point - if you're "meant" >> to use it with `new`, it's a constructor, otherwise, it's a function - and >> functions that work with both can be thought of as a dual >> constructor/factory (the factory calls the constructor for you). However, >> that conceptual definition is not one that can be programmatically >> determined, because "programmer intention" in this regard simply isn't >> inherently enshrined in an observable way, whether choosing `class` or >> `function`. >> >> Personally I think it would be wonderful to expose `IsConstructor` >> (`IsCallable` is already exposed via `typeof` returning "function"), but I >> feel quite confident that neither actually address any of the use cases in >> this thread. >> >> In addition, "safe to call" or "safe to use with `new`" all depends on >> your definition of "safe", and it's clear from this thread that that does >> not have a universally agreed-upon definition either. >> >> It might be useful to distill things down to 1) concrete use cases for >> calling or instantiating a function where you don't already know what it >> does, and can't assert in your human documentation what you expect; 2) a >> definition of "constructor", either a different one if you don't agree with >> mine above, or if you do, a form of mine that can be programmatically >> determined, and 3) a definition of "safe" which means more than "doesn't >> throw an exception". >> >> On Fri, Jan 20, 2017 at 6:52 PM, Scott Sauyet wrote: >> >> Bradley Meck wrote: >> >> 1. every call to `new Foo(...args)` creates a distinct object not >> >> reference-equal to any other such call. >> > >> > Would this mean >> > >> > ``` >> > function factory() { return []; } >> > ``` >> > >> > would qualify as a constructor? >> >> I'm thinking of that as a necessary, but not a sufficient condition. >> >> If it fails that test it cannot be a constructor. It's clear that >> there are other tests. It's not clear to me what they are. >> >> -- Scott >> ___ >> es-discuss mailing list >> es-discuss@mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> >> ___ >> es-discuss mailing list >> es-discuss@mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Determining if an object can be constructed
I'll point out that all I need is some way to detect anything that is callable except for classes. Basically, anything that has a `[[Call]]` that doesn't throw unconditionally without entering a different scope (like classes, but not %ThrowTypeError%). And to clarify, these would both be included per above, since it does enter a different scope: ```js // New language scope function foo() { throw new TypeError() } // New native scope (%ThrowTypeError%) "use strict" var foo = Object.getOwnPropertyDescriptor( arguments, "callee" ).get ``` `Reflect.isConstructor` isn't sufficient for my needs, since it would still consider the first `foo` above to be a constructor. On Sat, Jan 21, 2017, 01:14 Jordan Harbandwrote: > The reality here is that we're all playing around what the definition of > "constructor" and "callable" mean. > > In the spec, "constructors" are defined as having a `[[Construct]]` > internal slot; something is "callable" if it has a `[[Call]]` internal > slot. By that definition ( > https://tc39.github.io/ecma262/#sec-isconstructor and > https://tc39.github.io/ecma262/#sec-iscallable), a `class` constructor is > indeed callable (because it's defined to have `[[Call]]` throw a > `TypeError`). Similarly, as defined in the spec, `typeof class Foo {}` is > "function" only because it has a `[[Call]]` internal slot ( > https://tc39.github.io/ecma262/#table-35); if constructors lacked a > `[[Call]]` slot (such that `IsConstructor` returned `true` for them), then > `typeof someConstructor` would return "object". > > Obviously the committee could have chosen to define these things > differently; but this is how things are defined. > > > > I'm going to claim that conceptually - eg, to the majority of users - > something is a constructor when it's *intended* to be used with `new`. In > other words, "what it returns" isn't actually the point - if you're "meant" > to use it with `new`, it's a constructor, otherwise, it's a function - and > functions that work with both can be thought of as a dual > constructor/factory (the factory calls the constructor for you). However, > that conceptual definition is not one that can be programmatically > determined, because "programmer intention" in this regard simply isn't > inherently enshrined in an observable way, whether choosing `class` or > `function`. > > Personally I think it would be wonderful to expose `IsConstructor` > (`IsCallable` is already exposed via `typeof` returning "function"), but I > feel quite confident that neither actually address any of the use cases in > this thread. > > In addition, "safe to call" or "safe to use with `new`" all depends on > your definition of "safe", and it's clear from this thread that that does > not have a universally agreed-upon definition either. > > It might be useful to distill things down to 1) concrete use cases for > calling or instantiating a function where you don't already know what it > does, and can't assert in your human documentation what you expect; 2) a > definition of "constructor", either a different one if you don't agree with > mine above, or if you do, a form of mine that can be programmatically > determined, and 3) a definition of "safe" which means more than "doesn't > throw an exception". > > On Fri, Jan 20, 2017 at 6:52 PM, Scott Sauyet wrote: > > Bradley Meck wrote: > >> 1. every call to `new Foo(...args)` creates a distinct object not > >> reference-equal to any other such call. > > > > Would this mean > > > > ``` > > function factory() { return []; } > > ``` > > > > would qualify as a constructor? > > I'm thinking of that as a necessary, but not a sufficient condition. > > If it fails that test it cannot be a constructor. It's clear that > there are other tests. It's not clear to me what they are. > > -- Scott > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss