Re: The `super` keyword doesn't work as it should?

2016-07-18 Thread Bergi

/#!/JoePea wrote:


Why can't `super` simply be a shortcut
for "look up the prototype of the object that the method is called on, then
find the `.constructor` property and call it on `this`"? That seems to be
simple.


Simple, yes, and broken in the case of multi-level inheritance:
```
const x = Object.assign(Object.create({
method() {
console.log("parent");
}
}), {
method() {
console.log("child");
Object.getPrototypeOf(this).method(); // super.method()
}
});
x.method(); // works as expected

const y = Object.create(x);
y.method(); // infinite loop/stack overflow
```
A `super` query must not depend on `this` (only), it must statically 
resolve the object on which the called method is defined.


In constructors, using the prototype of the currenctly called 
constructor for `super()` works well, but you'd need to use 
`Object.setPrototype` as there is currently no declarative way other 
than `class`es to define functions with custom prototypes.


In methods, there would need to be a way to populate the [[HomeObject]] 
other than declaring the method as part of a class/object literal.


Kind regards,
 Bergi
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: The `super` keyword doesn't work as it should?

2016-07-18 Thread /#!/JoePea
Regarding the second example, [this resource](
http://exploringjs.com/es6/ch_oop-besides-classes.html#_caveat-objectassign-doesnt-work-well-for-moving-methods)
explains why `Object.assign` doesn't work as expected.

I believe the VM should be smarter than that, and let end-developers use
any technique for inheritance that they wish.

For example,maybe the VM should determine at runtime what the
`[[HomeObject]]` is based on what object the method is called on. Seems
like that would make `super` much more useful.

Doesn't that make more sense? If not, why not?

If this were the case, then the first example would work just fine too.

*/#!/*JoePea

On Mon, Jul 18, 2016 at 2:00 PM, /#!/JoePea  wrote:

> For example, both of these examples don't work in Chrome:
>
> ```js
> function A() {
> console.log('A')
> }
> A.prototype.constructor = A
> A.prototype.hello = function() {
> return 'hello'
> }
>
> function B() {
> console.log('B')
> // super()
> A.call(this)
> }
> B.prototype = Object.create(A.prototype)
> B.prototype.constructor = B
> B.prototype.hello = function() {
> return super.hello() + 'there'
> }
>
> new B
> ```
>
> and
>
> ```js
> let obj1 = {
> hello() {
> return 'hello'
> },
> sayHello() {
> console.log(this.hello())
> }
> }
>
> console.log('Obj1 says hello:')
> obj1.sayHello()
>
> let obj2 = Object.create(obj1)
> Object.assign(obj2, {
> hello() {
> return super.hello() + 'there.'
> }
> })
>
> console.log('Obj2 says hello:')
> obj2.sayHello() // Error
> ```
>
> I was hoping `super` was more flexible than that.
>
> For example, in the first snippet, why can't `super` simply be a shortcut
> for "look up the prototype of the object that the method is called on, then
> find the `.constructor` property and call it on `this`"? That seems to be
> simple. It could throw an error if `.constructor` is not found, in the case
> of ES5-style classes that aren't defined using that pattern that ES6
> classes are syntax sugar for.
>
> And in the second example, why does `super.hello` not work as expected?
>
> I believe that these limitations may severely limit my ability to create
> the multiple-inheritance tool that I'm imagining over at
> https://esdiscuss.org/topic/symbol-for-modifying-property-lookup#content-8
> .
>
> Any ideas or suggestions?
>
>
> */#!/*JoePea
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


The `super` keyword doesn't work as it should?

2016-07-18 Thread /#!/JoePea
For example, both of these examples don't work in Chrome:

```js
function A() {
console.log('A')
}
A.prototype.constructor = A
A.prototype.hello = function() {
return 'hello'
}

function B() {
console.log('B')
// super()
A.call(this)
}
B.prototype = Object.create(A.prototype)
B.prototype.constructor = B
B.prototype.hello = function() {
return super.hello() + 'there'
}

new B
```

and

```js
let obj1 = {
hello() {
return 'hello'
},
sayHello() {
console.log(this.hello())
}
}

console.log('Obj1 says hello:')
obj1.sayHello()

let obj2 = Object.create(obj1)
Object.assign(obj2, {
hello() {
return super.hello() + 'there.'
}
})

console.log('Obj2 says hello:')
obj2.sayHello() // Error
```

I was hoping `super` was more flexible than that.

For example, in the first snippet, why can't `super` simply be a shortcut
for "look up the prototype of the object that the method is called on, then
find the `.constructor` property and call it on `this`"? That seems to be
simple. It could throw an error if `.constructor` is not found, in the case
of ES5-style classes that aren't defined using that pattern that ES6
classes are syntax sugar for.

And in the second example, why does `super.hello` not work as expected?

I believe that these limitations may severely limit my ability to create
the multiple-inheritance tool that I'm imagining over at
https://esdiscuss.org/topic/symbol-for-modifying-property-lookup#content-8.

Any ideas or suggestions?


*/#!/*JoePea
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleDeclarationInstantiation behaviour after failure

2016-07-18 Thread Allen Wirfs-Brock

> On Jul 18, 2016, at 7:04 AM, Jon Coppeard  wrote:
> 
> On 15/07/2016 18:36, Allen Wirfs-Brock wrote:
> 
>> 
> 
>> ModuleDeclarationInstantiation is a semantics of the ES spec. and it
>> isn’t clear to me why the HTML spec. would need to invoke it.
> 
> The HTML spec needs some way of linking and executing modules.  It's not
> clear (to me) which parts of ES can be "called into" and referred to
> externally from another spec.

The intent is that after the “host” has fetched a module (and its dependencies) 
it enqueue a TopLevelModuleEvaluationJob. But, as stated there, much of the 
work of that TopLevelModuleEvaluationJob can be performed eagerly. 



> 
> I guess at this point HTML is providing the source texts required by
> RunJobs step 2:
> 
> "In an implementation dependent manner, obtain the ECMAScript source
> texts ... for zero or more ECMAScript scripts and/or ECMAScript modules”

That’s the “fetch” process, it’s completely host/implementation defined

RunJobs is dealing with an initial set of prefetched sequentially evaluated 
scripts and modules.  This would probably include the inline sequentially 
evaluated scripts/modules within an HTML file. It wouldn’t include any deferred 
scripts/modules.  A host handles deferred or dynamically identified 
scripts/modules  (eg, via dynamically inserting a script tag into the DOM)  by 
enqueuing additional Script/TopLevelModuleEvaluationJobs after RubJobs has 
already occurred.

> 
> I'm still not sure how I would refer to that exactly from an external spec.

The external spec.describes the process of fetching the source text and then 
either says that it performs RunJobs (if hit is initiating a new ES engine 
instantiation) or performs EnqueueJob to create a ScriptEvaluationJob or a 
TopLevelModuleEvaluationJob.

> 
> Further to this, if we do pre-instantiation of modules then we need some
> way of making this happen before TopLevelModuleEvaluationJob runs.  I
> don't think saying something like "use an implementation specific way to
> pre-instantiate a module" would be that useful, whereas saying "call
> ModuleDeclarationInstantiation for the module record" makes it clear
> what is supposed to happen.

In a loader spec. that is expect to have multiple implementations (eg, the HTML 
module loader) you want to be careful to not over-specify things that should be 
implementation details. For example, whether or not modules are (fully) eagerly 
or asynchronously parsed should be something an implementation should be able 
to decide. 

The only real requirement on a TopLevelEvaluationJob is the one implied by step 
8.a of https://tc39.github.io/ecma262/#sec-moduledeclarationinstantiation 
 “Before 
instantiating a module, all of the modules it requested must be available.” By 
“module” here, it is really talking about the source code of a module. So, 
before enqueuing such a job the host needs to ensure that all the transitively 
referenced source modules are available.  An implementation could perform a 
full  parse of the module (as specified by 
https://tc39.github.io/ecma262/#sec-parsemodule 
) but an implementation might 
also work out a simpler way to identify a module’s dependencies that doesn’t 
require a full parse/static semantics analysis. So, you want to be careful not 
to transitively “call” ParseModule in your spec. to satisfy that requirement. 
Instead, you might use language like: “Determine, as if by recursively invoking 
PaarseModule, that all module source texts imported by the top level module are 
available.”

The primary interface from the ES spec. back into a loader is 
https://tc39.github.io/ecma262/#sec-hostresolveimportedmodule 
 .  ES expect to 
get a Module Record for a fully parsed/analyzed source module back from that.  
Something that isn’t said there (but probably should be) is that if the 
referenced module is is a source text module (there can be other, 
host/implementation defined kinds of modules that are defined using the ES 
Module grammar) then ParseModule must be “called” to produce the corresponding 
Source Text Module Record.

I would expect any  host spec. for MostResolveImportedModule to roughly follow 
this pattern:
  Use referencingModule and specifier to obtain a host internal module id, mid.
  If the host known module registry has an entry for mid, then return the 
Module Record associated with mid in the registry. 
  If mid identifies a source text module, then
Assert: The source text of the module has already been fetched
Let src be the source text identified by mid.
Let modRec be ?ParseModule(src, currentRealm, hostProvided).
Create an entry in the host known module registry for mid that associates mid 
with modRec.
Return modred
  handle other implementation specified kinds of modules
Finally, I want to 

Re: ModuleDeclarationInstantiation behaviour after failure

2016-07-18 Thread Jon Coppeard
OK, this is great and I think it solves the problems of what to throw
away and not throwing away too much.

> Implementing this efficiently means
> tracking, for each module, "all the stuff that's depending/waiting on
> me". But the loader has to do this anyway, right?

Yes, this already has to happen to know when we can evaluate the
top-level module.

Thanks,

Jon

On 15/07/2016 18:31, Jason Orendorff wrote:
> How about this: Linking happens as eagerly as possible whenever a module
> arrives off the network. This means that very often we'll be linking one
> module at a time. In any case, every link set will be a strongly
> connected component of ready-to-link modules in the dependency graph;
> and therefore if linking fails, we should discard all the modules that
> we were trying to link.
> 
> When a link error or any other error happens, we immediately discard the
> failed module and everything that depends on it (potentially many
> modules in various states, etc.). Implementing this efficiently means
> tracking, for each module, "all the stuff that's depending/waiting on
> me". But the loader has to do this anyway, right?
> 
> More complete description of this proposal, in case that's not clear:
> https://gist.github.com/jorendorff/fc5bad969137402caa10bb3570b3f202
> 
> On Fri, Jul 15, 2016 at 9:32 AM, Jon Coppeard  > wrote:
> 
> Another similar approach that also uses the committed state might be to
> parse all modules as they become available and discard any uncommitted
> dependencies on instantiation error.
> 
> 
> What I'm proposing doesn't discard in-flight dependencies, but allows
> them to finish loading.
> 
> However that still has the disadvantage that too many modules are thrown
> away on error.
> 
> 
> Agreed.
>  
> 
> I guess what I'd really like is some support for this simultaneous
> loading in ES.
> 
> 
> At the least, I think it makes sense to mark Module Records for modules
> that failed to parse or link as permanently bad, and assert as we go
> that we are only ever working on good Module Records. It would be a nice
> clarification. (I suspect TC39 would accept patches for this, even
> though the status quo seems correct in every way -- it's just a matter
> of someone doing the work.)
> 
> -j
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleDeclarationInstantiation behaviour after failure

2016-07-18 Thread Jon Coppeard
On 15/07/2016 18:36, Allen Wirfs-Brock wrote:

> Can you point me at the parts of the HTML spec. that involved here?

The script tag is defined here:

https://html.spec.whatwg.org/multipage/scripting.html#the-script-element

The mechanism for loading modules starts here:

https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-script-tree

And HostResolveImportedModule is defined here:

https://html.spec.whatwg.org/multipage/webappapis.html#integration-with-the-javascript-module-system

> ModuleDeclarationInstantiation is a semantics of the ES spec. and it
> isn’t clear to me why the HTML spec. would need to invoke it.

The HTML spec needs some way of linking and executing modules.  It's not
clear (to me) which parts of ES can be "called into" and referred to
externally from another spec.

I guess at this point HTML is providing the source texts required by
RunJobs step 2:

"In an implementation dependent manner, obtain the ECMAScript source
texts ... for zero or more ECMAScript scripts and/or ECMAScript modules"

I'm still not sure how I would refer to that exactly from an external spec.

Further to this, if we do pre-instantiation of modules then we need some
way of making this happen before TopLevelModuleEvaluationJob runs.  I
don't think saying something like "use an implementation specific way to
pre-instantiate a module" would be that useful, whereas saying "call
ModuleDeclarationInstantiation for the module record" makes it clear
what is supposed to happen.

> (BTW, a loader API that includes the ability of ES code to
> programmatically introduce additional modules will also complicate eager
> or parallel processing.  If that is possible, then failure of eager
> processing of some module trees might be a temporary condition, and
> failure means that the processing of the module tree needs to be
> deferred until the API causes something to change.In other words,
> statically fetched modules that have dependencies upon dynamically
> created modules are tricky )

I totally agree and thankfully we are not doing that yet!

> My sense is that you are seeing requirements/restrictions in the ES
> spec. that aren't there (or aren’t intended if they are).

I think you're right.  I'm not sure exactly what I had in mind but it
seems the answer is "do anything you like as long as it is not
observable to script", which is a lower bar than I realised.

Thanks,

Jon

On 15/07/2016 18:36, Allen Wirfs-Brock wrote:
> 
>> On Jul 15, 2016, at 7:32 AM, Jon Coppeard > > wrote:
>>
>> Thank you for the detailed response.
>>
>> To start with I should say that although I'm working on an
>> implementation of the basic module loader defined by the HTML spec for
>> 

Re: Re: Optional Static Typing (Part 2)

2016-07-18 Thread Bruno Jouhier
What about TypeScript and Flow? They look like the natural candidates here:
already implemented, with real-world projects, tools, and growing
communities. Shouldn't the efforts be put on TypeScript/Flow
convergence/standardization rather than on a new proposal from scratch.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss