Re: Importing global into modules.
That was one the intentions but I get the feeling that this change is either too late or far more complex then it seems. In future we might have a use strict or use macros for modules which would enforce this clean slate for modules. It's not a big deal but I would have preferred the use globals approach and having modules clean by default instead. We have over 3000 classes + tests and I can't imagine more then 10% need access to the global (to access non module third-party libraries). I feel large scale JS applications using modules will be very much like this. I'm currently in the process of an automatic conversion of these global scripts into CJS modules. ( https://github.com/briandipalma/global-compiler ) The conversion to clean ES6 modules from global scripts seems very amenable to tooling/automation. Given the future is longer then the past I hope the reason for not considering this is not a deadline issue. B. On Wed, Oct 8, 2014 at 9:51 AM, A Matías Quezada amati...@gmail.com wrote: I like this idea mainly because it will allow us to create modules that explicitly define every used reference. This will help tooling detect exactly the source of every value we use. --- A. Matías Quezada Senior Javascript Developer amati...@gmail.com 2014-10-05 17:51 GMT+02:00 Brian Di Palma off...@gmail.com: I'm probably not understanding all the issues here but I'm also not explaining my suggestion well either. The way I see the two issues you raised is like this. 1) I think you mean that a parser wants to fail quickly if it comes across an identifier that was not previously declared as an import but that could be declared as one deeper in the module file? The simple solution to that problem is to not allow binding references before their import statements. 99.9% of modules will declare their imports at the top of the file anyway, most developers won't come across this restriction very often. It doesn't take away functionality, it's a useless degree of freedom and I can't think of any language where it's good practice to import/require etc anywhere but at the head of a module/class. I imagine these fast parsers work top down as the packets are streamed in from the network so this rule should work well for them? 2) I didn't explain this part well. I meant for the @global import to be a special one who's bindings will not go through the same checks that other modules do. In a browser importing global would return window. This should make it trivial to upgrade current code to ES6 modules while still allowing much stricter checks in modules. You would use tools that take the ES5 code and scan it for free identifiers and import them from @global. This then allows you to gradually move them all into ES6 modules. import * as global, {Date, XMLHttpRequest} from @global; All bindings provided by @global bypass the normal bindings checks. Think of it as a reverse use strict, currently to the do the right thing developers have to add an extra line at the top of all their scripts. With ES6 modules they should instead be required to add an extra line to do the wrong but temporarily necessary wrong thing. Adding this extra line is highly amenable to automation/tooling which developers will be using anyway when moving to ES6 modules. With time this line will be removed as their code is moved into modules or new versions of global classes are provided in standard modules. This would allow developers to still use Date as their constructor and not have it accidentally use the older version if a new one is added to standard modules. So by default an ES6 module starts of with a totally clean slate, it has no external state in its scope. Only if the developer chooses will the module be exposed to the madness of the global scope. Would this help macros or typing to be added to those modules with no access to the global? That would be a nice carrot to get developers to try and delete that line at the top of their module. B. On Fri, Oct 3, 2014 at 9:18 PM, Brendan Eich bren...@mozilla.org wrote: Brian Di Palma wrote: The recent thread on throwing errors on mutating immutable bindings touched upon the fact that there is no static unresolvable reference rejection in modules. I was wondering if that was down to needing to allow access to properties set on the global object? If that's the case why could you not just import the global into a module scope? Just like you import module meta data the module system could have a way of providing you the global object if you import it. That would mean that any reference that is accessed via the global import can't be checked but every other one can. Something like import * as global from @global; const myValue = global.myGlobalFunction(); //Special won't be checked can be mutated by everyone, big red flag in code reviews. function test() { x = 10; //Static error
Re: Importing global into modules.
Hi Andreas, Thanks for the response and explanations. I didn't realize how limited in power these fast parsers actually were, they are basically lexers. So yes this would require more bookkeeping on their part and that would impact performance. I'm doubtful that it would have a significant user perceivable effect though. I imagine modern browser engines perform a lot of work in parallel where they can. It would seem that the network would be far slower then the engine parsing JS. None the less I understand the concerns. One way around having an impact on current workloads is to only parse in this fashion for modules. This should mean no impact on existing code bases and the impact will only be felt with native modules. Those would rely on HTTP2, Server Push, Resource Hinting so they will tend toward smaller files. If you are shipping native modules then you couldn't bundle into a large module. As these modules would be stand alone fast parsing should be embarrassingly parallel. Lets be optimistic and say that in 5 years developers will be able to roll out native modules. I don't think that in 5 years a shortage of cores will be a problem, even on mobile devices. Given how slowly older IEs are being replaced on enterprise desktops it maybe 7 years... This is all conjecture on my part of course... Yes hoisting is another complication, more bookkeeping, it will probably delay when an error can be raised. But would you not have to deal with it anyway? Can you not export a hoisted function? The module system has to do binding checks on what it exports so keeping track of hoisted functions might have to happen anyway. Modules would end up being slower to parse then scripts but modules are for large scale development. I'm not sure in the grand scheme of things it will be that relevant though. Especially when weighted against increased static reasoning of modules. Fully closed modules are as you said are probably too tedious - that can be dropped. It's more about making modules closed against user defined state as opposed to system defined state. I think that will flow very well with the module system. import * as global, {myGlobalFunction} from @global; Should be enough to allow easy upgrading from ES5 scripts while still allowing the module system/tooling to provide more static guarantees. B. On Wed, Oct 8, 2014 at 11:30 AM, Andreas Rossberg rossb...@google.com wrote: On 5 October 2014 17:51, Brian Di Palma off...@gmail.com wrote: 1) I think you mean that a parser wants to fail quickly if it comes across an identifier that was not previously declared as an import but that could be declared as one deeper in the module file? The simple solution to that problem is to not allow binding references before their import statements. No, fail fast is not the issue, nor is the recursive nature of scoping in JavaScript. The issue is that, in order to know what identifiers are bound -- even in the simplest, linear case -- you need to maintain environments, i.e., do analysis and bookkeeping of declarations and scopes, both surrounding and local ones. So far, pre-parsing (the early approximate parse of lazily compiled functions, that only looks for early errors) didn't need anything like that. Adding it probably isn't overly expensive, but it's not free either, and nobody has measured the impact on large applications. 99.9% of modules will declare their imports at the top of the file anyway, most developers won't come across this restriction very often. It doesn't take away functionality, it's a useless degree of freedom and I can't think of any language where it's good practice to import/require etc anywhere but at the head of a module/class. It's not just imports, you can forward reference any declaration in JavaScript. That's a feature that cannot easily be removed, and binding analysis has to deal with it. It's not a problem, though, only a mild complication. 2) I didn't explain this part well. I meant for the @global import to be a special one who's bindings will not go through the same checks that other modules do. In a browser importing global would return window. This should make it trivial to upgrade current code to ES6 modules while still allowing much stricter checks in modules. You would use tools that take the ES5 code and scan it for free identifiers and import them from @global. This then allows you to gradually move them all into ES6 modules. import * as global, {Date, XMLHttpRequest} from @global; All bindings provided by @global bypass the normal bindings checks. IIUC, your suggestion is that modules should be closed, i.e., not be able to refer to any non-local or pre-defined identifiers. This idea has a long history in works on module systems, but I'm not aware of any practical language that ever managed to follow it through. It quickly becomes very tedious in practice, and I highly doubt it would jive well with JavaScript, or probably any
Re: Importing global into modules.
On Wed, Oct 8, 2014 at 1:52 PM, Andreas Rossberg rossb...@google.com wrote: No, that's not correct. They have to perform a full syntax check. That does not imply binding analysis, though, which is usually regarded part of the static semantics of a language, not its (context-free) syntax. (More by accident than by design, JavaScript so far didn't have much of a static semantics -- at least none that would rule out many programs, i.e., induce compile-time errors. Hence engines could get away with lazy compilation so well.) Right, I see. Yes, see the earlier posts by Dave an myself. Didn't happen, though. This seems an implementation detail of the engine, especially as you can't introduce checking to scripts. You can indeed parallelise parsing and checking of separate modules, but each individual task would still take longer, so there would still have been a potential overall cost. There will be a cost but it didn't sound like that was the reason why checking was taken off the table. I thought it was more around the need to still have access to the global scope in backward compatible code. Yes, but unfortunately, you cannot distinguish between the two in JavaScript -- globals, monkey patching, and all that lovely stuff. The way the global import would work would be more akin to a filter. When a developer uses the global import they are saying allow these identifiers from the global state to be available in my module. In the current approach there is a filter, it's just implicit and open to all identifiers. This change is about making it explicit and configurable. When a developer writes import {myGlobalFunction, MyPolyfilledConstructor} from @global; she creates a binding to these identifiers from the systems global scope. Unlike other bindings they will not be checked for existence. All the system will do is provide them if they exist, change them if they are changed and introduce them to the module scope if they are created at a later stage. The developer has no guarantees about these specific bindings. Just like any other global binding, it's purely a declaration mechanism. You are free to access global state, just declare it up front. Therefore even monkey patched/poly filled code will be allowed through. Any binding what so ever can be allowed through. I would hope that in future that new constructors will be added to standard modules though... B. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Importing global into modules.
A compiler can convert references like these import {myGlobalFunction, MyPolyfilledConstructor} from @global; myGlobalFunction(42); into global.myGlobalFunction(42); And the global scope can be window for a browser. This code has the exact same semantics as if the global scope was allowed fully into the module. The only difference is that the developer is being asked to explicitly list the bindings that should be allowed filter through. B. On Wed, Oct 8, 2014 at 2:49 PM, Brian Di Palma off...@gmail.com wrote: On Wed, Oct 8, 2014 at 1:52 PM, Andreas Rossberg rossb...@google.com wrote: No, that's not correct. They have to perform a full syntax check. That does not imply binding analysis, though, which is usually regarded part of the static semantics of a language, not its (context-free) syntax. (More by accident than by design, JavaScript so far didn't have much of a static semantics -- at least none that would rule out many programs, i.e., induce compile-time errors. Hence engines could get away with lazy compilation so well.) Right, I see. Yes, see the earlier posts by Dave an myself. Didn't happen, though. This seems an implementation detail of the engine, especially as you can't introduce checking to scripts. You can indeed parallelise parsing and checking of separate modules, but each individual task would still take longer, so there would still have been a potential overall cost. There will be a cost but it didn't sound like that was the reason why checking was taken off the table. I thought it was more around the need to still have access to the global scope in backward compatible code. Yes, but unfortunately, you cannot distinguish between the two in JavaScript -- globals, monkey patching, and all that lovely stuff. The way the global import would work would be more akin to a filter. When a developer uses the global import they are saying allow these identifiers from the global state to be available in my module. In the current approach there is a filter, it's just implicit and open to all identifiers. This change is about making it explicit and configurable. When a developer writes import {myGlobalFunction, MyPolyfilledConstructor} from @global; she creates a binding to these identifiers from the systems global scope. Unlike other bindings they will not be checked for existence. All the system will do is provide them if they exist, change them if they are changed and introduce them to the module scope if they are created at a later stage. The developer has no guarantees about these specific bindings. Just like any other global binding, it's purely a declaration mechanism. You are free to access global state, just declare it up front. Therefore even monkey patched/poly filled code will be allowed through. Any binding what so ever can be allowed through. I would hope that in future that new constructors will be added to standard modules though... B. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Importing global into modules.
On Wed, Oct 8, 2014 at 2:51 PM, caridy car...@gmail.com wrote: last time we discussed this, the conclusion was that `Reflect.global` is the way to go. more details here: https://gist.github.com/ericf/a7b40bf8324cd1f5dc73#how-do-we-access-the-global-object-within-a-module once realms landed, it will reflect `realm.global`. I guess import {myGlobalFunction, MyPolyfilledConstructor} from Reflect.global; then? ./caridy On Oct 8, 2014, at 8:52 AM, Andreas Rossberg rossb...@google.com wrote: On 8 October 2014 14:11, Brian Di Palma off...@gmail.com wrote: I didn't realize how limited in power these fast parsers actually were, they are basically lexers. No, that's not correct. They have to perform a full syntax check. That does not imply binding analysis, though, which is usually regarded part of the static semantics of a language, not its (context-free) syntax. (More by accident than by design, JavaScript so far didn't have much of a static semantics -- at least none that would rule out many programs, i.e., induce compile-time errors. Hence engines could get away with lazy compilation so well.) I'm doubtful that it would have a significant user perceivable effect though. I imagine modern browser engines perform a lot of work in parallel where they can. Unfortunately, parallelism doesn't help here, since this is all about the _initial_ parse (of every source), which has to happen before anything else, and so directly affects start-up times. One way around having an impact on current workloads is to only parse in this fashion for modules. Yes, see the earlier posts by Dave an myself. Didn't happen, though. As these modules would be stand alone fast parsing should be embarrassingly parallel. You can indeed parallelise parsing and checking of separate modules, but each individual task would still take longer, so there would still have been a potential overall cost. Yes hoisting is another complication, more bookkeeping, it will probably delay when an error can be raised. But would you not have to deal with it anyway? Can you not export a hoisted function? Yes, as I said, recursive scoping (a.k.a. hoisting) is neither a new nor a significant problem. Fully closed modules are as you said are probably too tedious - that can be dropped. It's more about making modules closed against user defined state as opposed to system defined state. Yes, but unfortunately, you cannot distinguish between the two in JavaScript -- globals, monkey patching, and all that lovely stuff. /Andreas ___ 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: Importing global into modules.
On Wed, Oct 8, 2014 at 3:21 PM, caridy car...@gmail.com wrote: var myGlobalFunction = Reflect.global.myGlobalFunction; note: you can't use import for global due to the nature of the binding process when importing members or namespaces. I find import global from @global; global.myGlobalFunction(42); more readable. If we can import module meta information why not import the global object too? The global should always exist so the binding checks will work, it's a module with a default export. Accessing any global property is via that object. No need to allow random identifiers floating around modules. B. On Oct 8, 2014, at 9:57 AM, Brian Di Palma off...@gmail.com wrote: On Wed, Oct 8, 2014 at 2:51 PM, caridy car...@gmail.com wrote: last time we discussed this, the conclusion was that `Reflect.global` is the way to go. more details here: https://gist.github.com/ericf/a7b40bf8324cd1f5dc73#how-do-we-access-the-global-object-within-a-module once realms landed, it will reflect `realm.global`. I guess import {myGlobalFunction, MyPolyfilledConstructor} from Reflect.global; then? ./caridy On Oct 8, 2014, at 8:52 AM, Andreas Rossberg rossb...@google.com wrote: On 8 October 2014 14:11, Brian Di Palma off...@gmail.com wrote: I didn't realize how limited in power these fast parsers actually were, they are basically lexers. No, that's not correct. They have to perform a full syntax check. That does not imply binding analysis, though, which is usually regarded part of the static semantics of a language, not its (context-free) syntax. (More by accident than by design, JavaScript so far didn't have much of a static semantics -- at least none that would rule out many programs, i.e., induce compile-time errors. Hence engines could get away with lazy compilation so well.) I'm doubtful that it would have a significant user perceivable effect though. I imagine modern browser engines perform a lot of work in parallel where they can. Unfortunately, parallelism doesn't help here, since this is all about the _initial_ parse (of every source), which has to happen before anything else, and so directly affects start-up times. One way around having an impact on current workloads is to only parse in this fashion for modules. Yes, see the earlier posts by Dave an myself. Didn't happen, though. As these modules would be stand alone fast parsing should be embarrassingly parallel. You can indeed parallelise parsing and checking of separate modules, but each individual task would still take longer, so there would still have been a potential overall cost. Yes hoisting is another complication, more bookkeeping, it will probably delay when an error can be raised. But would you not have to deal with it anyway? Can you not export a hoisted function? Yes, as I said, recursive scoping (a.k.a. hoisting) is neither a new nor a significant problem. Fully closed modules are as you said are probably too tedious - that can be dropped. It's more about making modules closed against user defined state as opposed to system defined state. Yes, but unfortunately, you cannot distinguish between the two in JavaScript -- globals, monkey patching, and all that lovely stuff. /Andreas ___ 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: Importing global into modules.
Does that mean that anything that is imported is frozen? You can't add properties to any binding you import? I've never heard of this restriction before. If that restriction doesn't exist then I'm not sure I see what issue this causes import { global } from this module; global in this case is an object and I was under the impression that you could add and remove properties to an object if you imported one. Providing an idiomatic way for modules to access the global seems good ergonomics. On Wed, Oct 8, 2014 at 4:00 PM, caridy car...@gmail.com wrote: Guys, anything that you import is going to be subject to the binding process, they are immutable values. In the other hand, Reflect.global is just the new global for scripts and modules, plain and simple. Today, many libraries are relying on `new Function()` to artificially access global, and that's wont work with CSP, therefore we need to provide a reliable way to access global from anywhere, not only from modules. /caridy On Oct 8, 2014, at 10:34 AM, Brian Di Palma off...@gmail.com wrote: On Wed, Oct 8, 2014 at 3:21 PM, caridy car...@gmail.com wrote: var myGlobalFunction = Reflect.global.myGlobalFunction; note: you can't use import for global due to the nature of the binding process when importing members or namespaces. I find import global from @global; global.myGlobalFunction(42); more readable. If we can import module meta information why not import the global object too? The global should always exist so the binding checks will work, it's a module with a default export. Accessing any global property is via that object. No need to allow random identifiers floating around modules. B. On Oct 8, 2014, at 9:57 AM, Brian Di Palma off...@gmail.com wrote: On Wed, Oct 8, 2014 at 2:51 PM, caridy car...@gmail.com wrote: last time we discussed this, the conclusion was that `Reflect.global` is the way to go. more details here: https://gist.github.com/ericf/a7b40bf8324cd1f5dc73#how-do-we-access-the-global-object-within-a-module once realms landed, it will reflect `realm.global`. I guess import {myGlobalFunction, MyPolyfilledConstructor} from Reflect.global; then? ./caridy On Oct 8, 2014, at 8:52 AM, Andreas Rossberg rossb...@google.com wrote: On 8 October 2014 14:11, Brian Di Palma off...@gmail.com wrote: I didn't realize how limited in power these fast parsers actually were, they are basically lexers. No, that's not correct. They have to perform a full syntax check. That does not imply binding analysis, though, which is usually regarded part of the static semantics of a language, not its (context-free) syntax. (More by accident than by design, JavaScript so far didn't have much of a static semantics -- at least none that would rule out many programs, i.e., induce compile-time errors. Hence engines could get away with lazy compilation so well.) I'm doubtful that it would have a significant user perceivable effect though. I imagine modern browser engines perform a lot of work in parallel where they can. Unfortunately, parallelism doesn't help here, since this is all about the _initial_ parse (of every source), which has to happen before anything else, and so directly affects start-up times. One way around having an impact on current workloads is to only parse in this fashion for modules. Yes, see the earlier posts by Dave an myself. Didn't happen, though. As these modules would be stand alone fast parsing should be embarrassingly parallel. You can indeed parallelise parsing and checking of separate modules, but each individual task would still take longer, so there would still have been a potential overall cost. Yes hoisting is another complication, more bookkeeping, it will probably delay when an error can be raised. But would you not have to deal with it anyway? Can you not export a hoisted function? Yes, as I said, recursive scoping (a.k.a. hoisting) is neither a new nor a significant problem. Fully closed modules are as you said are probably too tedious - that can be dropped. It's more about making modules closed against user defined state as opposed to system defined state. Yes, but unfortunately, you cannot distinguish between the two in JavaScript -- globals, monkey patching, and all that lovely stuff. /Andreas ___ 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: Importing global into modules.
On Wed, Oct 8, 2014 at 4:38 PM, caridy car...@gmail.com wrote: Brian, my point is that using import to get access to `global` (as you suggested) is confusing due to the nature of the import, remember the contract: to import something, someone else has to export it first :) The JS environment exports the global object. I don't think many developers will find code like that confusing and it's easy to learn and understand. It's just as complex as Reflect.global. Aside from that, we don't want to have a exclusive way of accessing globals for modules, they should be accessible (as reflective) from everywhere. It doesn't preclude Reflect.global, it's simply an idiomatic way to access the global in modules. I foresee a lot of const global = Reflect.global; at the top of modules in years to come. If the desire was there importing the global would also allow static errors on free variables. /caridy ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Importing global into modules.
Sorry, I meant free variables inside the module. The reason why I originally started this thread was to ask if importing global references or the global would be a way of adding static checks of free variables in modules. You are right that you can't check properties of the global. Hence the suggestions to either import the global and require module code to prepend global before accessing global properties. import global from @global; global.myGlobalFunction(); //may not exist just like normal global code. In this case only global is checked for existence so this should not require special logic in the module system. The other suggestion was to process an import global as a special module which does not have any binding checks performed on it. import {myGlobalFunction, MyPolyfilledConstructor} from @global; myGlobalFunction(); //may not exist just like normal global code. Either of the two approaches allows an easy upgrade path for ES5 code to ES6 modules and should allow the introduction of a ban on free variables in modules. I was curious if a ban on free variables in modules was worth considering and any of the approaches outlined above were feasible. B. On Wed, Oct 8, 2014 at 5:15 PM, caridy car...@gmail.com wrote: what do you mean by: If the desire was there importing the global would also allow static errors on free variables. If we ever decide to allow importing a reference to global from a module, it has to be a named import, and therefore, no static analysis can be applied to its members (since it is a shared, mutable object), what's the benefit then? ergonomic? I don't think so. /caridy On Oct 8, 2014, at 11:55 AM, Brian Di Palma off...@gmail.com wrote: On Wed, Oct 8, 2014 at 4:38 PM, caridy car...@gmail.com wrote: Brian, my point is that using import to get access to `global` (as you suggested) is confusing due to the nature of the import, remember the contract: to import something, someone else has to export it first :) The JS environment exports the global object. I don't think many developers will find code like that confusing and it's easy to learn and understand. It's just as complex as Reflect.global. Aside from that, we don't want to have a exclusive way of accessing globals for modules, they should be accessible (as reflective) from everywhere. It doesn't preclude Reflect.global, it's simply an idiomatic way to access the global in modules. I foresee a lot of const global = Reflect.global; at the top of modules in years to come. If the desire was there importing the global would also allow static errors on free variables. /caridy ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Importing global into modules.
Would these guarantees not enable more features to be added to the language? I mean if they are worthless guarantees then fair enough it's not worth considering. On Wed, Oct 8, 2014 at 5:37 PM, Domenic Denicola dome...@domenicdenicola.com wrote: Just use JSHint. -Original Message- From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Brian Di Palma Sent: Wednesday, October 8, 2014 12:29 To: caridy Cc: es-discuss@mozilla.org Subject: Re: Importing global into modules. Sorry, I meant free variables inside the module. The reason why I originally started this thread was to ask if importing global references or the global would be a way of adding static checks of free variables in modules. You are right that you can't check properties of the global. Hence the suggestions to either import the global and require module code to prepend global before accessing global properties. import global from @global; global.myGlobalFunction(); //may not exist just like normal global code. In this case only global is checked for existence so this should not require special logic in the module system. The other suggestion was to process an import global as a special module which does not have any binding checks performed on it. import {myGlobalFunction, MyPolyfilledConstructor} from @global; myGlobalFunction(); //may not exist just like normal global code. Either of the two approaches allows an easy upgrade path for ES5 code to ES6 modules and should allow the introduction of a ban on free variables in modules. I was curious if a ban on free variables in modules was worth considering and any of the approaches outlined above were feasible. B. On Wed, Oct 8, 2014 at 5:15 PM, caridy car...@gmail.com wrote: what do you mean by: If the desire was there importing the global would also allow static errors on free variables. If we ever decide to allow importing a reference to global from a module, it has to be a named import, and therefore, no static analysis can be applied to its members (since it is a shared, mutable object), what's the benefit then? ergonomic? I don't think so. /caridy On Oct 8, 2014, at 11:55 AM, Brian Di Palma off...@gmail.com wrote: On Wed, Oct 8, 2014 at 4:38 PM, caridy car...@gmail.com wrote: Brian, my point is that using import to get access to `global` (as you suggested) is confusing due to the nature of the import, remember the contract: to import something, someone else has to export it first :) The JS environment exports the global object. I don't think many developers will find code like that confusing and it's easy to learn and understand. It's just as complex as Reflect.global. Aside from that, we don't want to have a exclusive way of accessing globals for modules, they should be accessible (as reflective) from everywhere. It doesn't preclude Reflect.global, it's simply an idiomatic way to access the global in modules. I foresee a lot of const global = Reflect.global; at the top of modules in years to come. If the desire was there importing the global would also allow static errors on free variables. /caridy ___ 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: Importing global into modules.
I'm probably not understanding all the issues here but I'm also not explaining my suggestion well either. The way I see the two issues you raised is like this. 1) I think you mean that a parser wants to fail quickly if it comes across an identifier that was not previously declared as an import but that could be declared as one deeper in the module file? The simple solution to that problem is to not allow binding references before their import statements. 99.9% of modules will declare their imports at the top of the file anyway, most developers won't come across this restriction very often. It doesn't take away functionality, it's a useless degree of freedom and I can't think of any language where it's good practice to import/require etc anywhere but at the head of a module/class. I imagine these fast parsers work top down as the packets are streamed in from the network so this rule should work well for them? 2) I didn't explain this part well. I meant for the @global import to be a special one who's bindings will not go through the same checks that other modules do. In a browser importing global would return window. This should make it trivial to upgrade current code to ES6 modules while still allowing much stricter checks in modules. You would use tools that take the ES5 code and scan it for free identifiers and import them from @global. This then allows you to gradually move them all into ES6 modules. import * as global, {Date, XMLHttpRequest} from @global; All bindings provided by @global bypass the normal bindings checks. Think of it as a reverse use strict, currently to the do the right thing developers have to add an extra line at the top of all their scripts. With ES6 modules they should instead be required to add an extra line to do the wrong but temporarily necessary wrong thing. Adding this extra line is highly amenable to automation/tooling which developers will be using anyway when moving to ES6 modules. With time this line will be removed as their code is moved into modules or new versions of global classes are provided in standard modules. This would allow developers to still use Date as their constructor and not have it accidentally use the older version if a new one is added to standard modules. So by default an ES6 module starts of with a totally clean slate, it has no external state in its scope. Only if the developer chooses will the module be exposed to the madness of the global scope. Would this help macros or typing to be added to those modules with no access to the global? That would be a nice carrot to get developers to try and delete that line at the top of their module. B. On Fri, Oct 3, 2014 at 9:18 PM, Brendan Eich bren...@mozilla.org wrote: Brian Di Palma wrote: The recent thread on throwing errors on mutating immutable bindings touched upon the fact that there is no static unresolvable reference rejection in modules. I was wondering if that was down to needing to allow access to properties set on the global object? If that's the case why could you not just import the global into a module scope? Just like you import module meta data the module system could have a way of providing you the global object if you import it. That would mean that any reference that is accessed via the global import can't be checked but every other one can. Something like import * as global from @global; const myValue = global.myGlobalFunction(); //Special won't be checked can be mutated by everyone, big red flag in code reviews. function test() { x = 10; //Static error, we know this is not an access to a global x as it must be accessed via global. } Could this work? The problem this doesn't solve is the one Andreas Rossberg raised (at a past TC39 meeting, and just the other day here): browser-based implementations must parse lazily and super-fast, they cannot be presumed to be able to afford binding checks. Someone should go super-hack a binding checker that doesn't degrade page load perf, or other metrics. Absent such evidence, there are two strikes against what you propose: 1) performance effects of binding checking when parsing; 2) whether async script loads make global bindings unordered and so not generally worth trying to check. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Importing global into modules.
The recent thread on throwing errors on mutating immutable bindings touched upon the fact that there is no static unresolvable reference rejection in modules. I was wondering if that was down to needing to allow access to properties set on the global object? If that's the case why could you not just import the global into a module scope? Just like you import module meta data the module system could have a way of providing you the global object if you import it. That would mean that any reference that is accessed via the global import can't be checked but every other one can. Something like import * as global from @global; const myValue = global.myGlobalFunction(); //Special won't be checked can be mutated by everyone, big red flag in code reviews. function test() { x = 10; //Static error, we know this is not an access to a global x as it must be accessed via global. } Could this work? B. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: Quantifying Default Exports
It's using traceur and building the modules to CJS, the project uses other non transpiled CJS modules. The only thing traceur could do here is compile the imports into a check for the named export `default` and use that if it exists. If it doesn't then simply return the CJS module object. Here is the output from traceur https://github.com/briandipalma/global-compiler/blob/master/out/index.js The relevant line would be `var minimist = require('minimist');` For default import from a CJS module you'd need to output ` var minimist = require('minimist'); if (minimist.default) { minimist = minimist.default; } ` Is that what you think traceur should do? On Mon, Jul 21, 2014 at 2:34 PM, Juan Ignacio Dopazo jdop...@yahoo-inc.com wrote: On Saturday, July 19, 2014 1:53 PM, Brian Di Palma off...@gmail.com wrote: When an npm package exports a named identifier it's trivial to use it in an ES6 module. import { parse, print } from 'recast'; When on the other hand it sets its export on `module.exports` default exports provide no help at all. This sounds like an issue in your transpiler. Ideally CJS modules inside projects written using ES6 modules should be treated as modules that default export an object. CJS modules don't have the same static semantics as their ES6 counterpart, so they should be treated as mutable objects. An ES6 Loader would do the same when loading CJS modules. Juan ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: Quantifying Default Exports
Which shows the how the backward compatability argument for default export/imports doesn't stand up. If you want to import `module.exports` then use the the `module` form if you want named imports use the named form. Default import/exports are generating nothing more then complexity, confusion and not serving their intended goals. On Mon, Jul 21, 2014 at 3:18 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: similar discussion at systemjs https://github.com/systemjs/systemjs/issues/131 which boils down to if a CJS module imports an ES6 module that has a key named default, what should the default behavior be. On Mon, Jul 21, 2014 at 10:05 AM, Brian Di Palma off...@gmail.com wrote: It's using traceur and building the modules to CJS, the project uses other non transpiled CJS modules. The only thing traceur could do here is compile the imports into a check for the named export `default` and use that if it exists. If it doesn't then simply return the CJS module object. Here is the output from traceur https://github.com/briandipalma/global-compiler/blob/master/out/index.js The relevant line would be `var minimist = require('minimist');` For default import from a CJS module you'd need to output ` var minimist = require('minimist'); if (minimist.default) { minimist = minimist.default; } ` Is that what you think traceur should do? On Mon, Jul 21, 2014 at 2:34 PM, Juan Ignacio Dopazo jdop...@yahoo-inc.com wrote: On Saturday, July 19, 2014 1:53 PM, Brian Di Palma off...@gmail.com wrote: When an npm package exports a named identifier it's trivial to use it in an ES6 module. import { parse, print } from 'recast'; When on the other hand it sets its export on `module.exports` default exports provide no help at all. This sounds like an issue in your transpiler. Ideally CJS modules inside projects written using ES6 modules should be treated as modules that default export an object. CJS modules don't have the same static semantics as their ES6 counterpart, so they should be treated as mutable objects. An ES6 Loader would do the same when loading CJS modules. Juan ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- -Calvin W. Metcalf ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: Quantifying Default Exports
On Mon, Jul 21, 2014 at 3:31 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: that won't help if module.exports is a function That's exactly what `minimist` is, works just fine. https://github.com/substack/minimist/blob/master/index.js Overall the import/exports semantics of es6 and cjs modules would be compatible if mixing named and default exports was prohibited, but the ability to have both is hard to represent in cjs modules. Don't understand this, do you have some code examples? I can't see why that would be the case. On Mon, Jul 21, 2014 at 10:24 AM, Brian Di Palma off...@gmail.com wrote: Which shows the how the backward compatability argument for default export/imports doesn't stand up. If you want to import `module.exports` then use the the `module` form if you want named imports use the named form. Default import/exports are generating nothing more then complexity, confusion and not serving their intended goals. On Mon, Jul 21, 2014 at 3:18 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: similar discussion at systemjs https://github.com/systemjs/systemjs/issues/131 which boils down to if a CJS module imports an ES6 module that has a key named default, what should the default behavior be. On Mon, Jul 21, 2014 at 10:05 AM, Brian Di Palma off...@gmail.com wrote: It's using traceur and building the modules to CJS, the project uses other non transpiled CJS modules. The only thing traceur could do here is compile the imports into a check for the named export `default` and use that if it exists. If it doesn't then simply return the CJS module object. Here is the output from traceur https://github.com/briandipalma/global-compiler/blob/master/out/index.js The relevant line would be `var minimist = require('minimist');` For default import from a CJS module you'd need to output ` var minimist = require('minimist'); if (minimist.default) { minimist = minimist.default; } ` Is that what you think traceur should do? On Mon, Jul 21, 2014 at 2:34 PM, Juan Ignacio Dopazo jdop...@yahoo-inc.com wrote: On Saturday, July 19, 2014 1:53 PM, Brian Di Palma off...@gmail.com wrote: When an npm package exports a named identifier it's trivial to use it in an ES6 module. import { parse, print } from 'recast'; When on the other hand it sets its export on `module.exports` default exports provide no help at all. This sounds like an issue in your transpiler. Ideally CJS modules inside projects written using ES6 modules should be treated as modules that default export an object. CJS modules don't have the same static semantics as their ES6 counterpart, so they should be treated as mutable objects. An ES6 Loader would do the same when loading CJS modules. Juan ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- -Calvin W. Metcalf -- -Calvin W. Metcalf ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: Quantifying Default Exports
On Mon, Jul 21, 2014 at 4:16 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: I have a CommonJS module which exports a single function ```js //cj.js module.exports = function (){} ``` If I was to transform it into an ES6 module the best way to do so currently it so use a default export ```js //cj2es6.js export default function () {} ``` now say I want to import those from another commonjs module, importing the first one is easy, but when importing the second one slightly less so, how should the loader treat that default export, a easy solution for this case is to simply have default exports act the same as a module.exports But then what would you do about es6 modules that use default and named exports like the example at http://jsmodules.io/ which can be sumerized as ```js export default function mainThing(){} export function helper (){}; , if we return a default export if it exists then there is no way to access the named exports. As mentioned in the GitHub issue I don't see why you couldn't compile to ` module.export = function mainThing(){}; module.export.helper = function(){}; ` Allowing access to the default and named. So in that case it would make more sense to treat default as just another export name. But if we do that then that means that if we go back to our second example ```js //cj2es6.js export default function () {} ``` if that was to be treated that way then importing it from another commonjs module would be make it be equivalent to ```js //cj2es62cj.js exports.default = function (){} ``` In other words treating default as a regular name prevents you from losslessly converting commonjs in a backwards compatible way. Making named and default exports be mutually exclusive would mean that you could treat default export like module.exports. On Mon, Jul 21, 2014 at 10:45 AM, Brian Di Palma off...@gmail.com wrote: On Mon, Jul 21, 2014 at 3:31 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: that won't help if module.exports is a function That's exactly what `minimist` is, works just fine. https://github.com/substack/minimist/blob/master/index.js Overall the import/exports semantics of es6 and cjs modules would be compatible if mixing named and default exports was prohibited, but the ability to have both is hard to represent in cjs modules. Don't understand this, do you have some code examples? I can't see why that would be the case. On Mon, Jul 21, 2014 at 10:24 AM, Brian Di Palma off...@gmail.com wrote: Which shows the how the backward compatability argument for default export/imports doesn't stand up. If you want to import `module.exports` then use the the `module` form if you want named imports use the named form. Default import/exports are generating nothing more then complexity, confusion and not serving their intended goals. On Mon, Jul 21, 2014 at 3:18 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: similar discussion at systemjs https://github.com/systemjs/systemjs/issues/131 which boils down to if a CJS module imports an ES6 module that has a key named default, what should the default behavior be. On Mon, Jul 21, 2014 at 10:05 AM, Brian Di Palma off...@gmail.com wrote: It's using traceur and building the modules to CJS, the project uses other non transpiled CJS modules. The only thing traceur could do here is compile the imports into a check for the named export `default` and use that if it exists. If it doesn't then simply return the CJS module object. Here is the output from traceur https://github.com/briandipalma/global-compiler/blob/master/out/index.js The relevant line would be `var minimist = require('minimist');` For default import from a CJS module you'd need to output ` var minimist = require('minimist'); if (minimist.default) { minimist = minimist.default; } ` Is that what you think traceur should do? On Mon, Jul 21, 2014 at 2:34 PM, Juan Ignacio Dopazo jdop...@yahoo-inc.com wrote: On Saturday, July 19, 2014 1:53 PM, Brian Di Palma off...@gmail.com wrote: When an npm package exports a named identifier it's trivial to use it in an ES6 module. import { parse, print } from 'recast'; When on the other hand it sets its export on `module.exports` default exports provide no help at all. This sounds like an issue in your transpiler. Ideally CJS modules inside projects written using ES6 modules should be treated as modules that default export an object. CJS modules don't have the same static semantics as their ES6 counterpart, so they should be treated as mutable objects. An ES6 Loader would do the same when loading CJS modules. Juan ___ es-discuss
Re: Re: Quantifying Default Exports
Yep, that makes sense. Highly unlikely but still possible and could cause issues. No doubt you could complicate your compiler to deal with these edge cases but why force that? Yet more problems with default imports/exports. This feature doesn't seem worth its cost. On Mon, Jul 21, 2014 at 5:21 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: (woops hit reply instead of reply all) Because the `function mainThing(){}` might already have a method named helper or, more likely, the named export is something like call or bind. On Mon, Jul 21, 2014 at 12:06 PM, Brian Di Palma off...@gmail.com wrote: On Mon, Jul 21, 2014 at 4:16 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: I have a CommonJS module which exports a single function ```js //cj.js module.exports = function (){} ``` If I was to transform it into an ES6 module the best way to do so currently it so use a default export ```js //cj2es6.js export default function () {} ``` now say I want to import those from another commonjs module, importing the first one is easy, but when importing the second one slightly less so, how should the loader treat that default export, a easy solution for this case is to simply have default exports act the same as a module.exports But then what would you do about es6 modules that use default and named exports like the example at http://jsmodules.io/ which can be sumerized as ```js export default function mainThing(){} export function helper (){}; , if we return a default export if it exists then there is no way to access the named exports. As mentioned in the GitHub issue I don't see why you couldn't compile to ` module.export = function mainThing(){}; module.export.helper = function(){}; ` Allowing access to the default and named. So in that case it would make more sense to treat default as just another export name. But if we do that then that means that if we go back to our second example ```js //cj2es6.js export default function () {} ``` if that was to be treated that way then importing it from another commonjs module would be make it be equivalent to ```js //cj2es62cj.js exports.default = function (){} ``` In other words treating default as a regular name prevents you from losslessly converting commonjs in a backwards compatible way. Making named and default exports be mutually exclusive would mean that you could treat default export like module.exports. On Mon, Jul 21, 2014 at 10:45 AM, Brian Di Palma off...@gmail.com wrote: On Mon, Jul 21, 2014 at 3:31 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: that won't help if module.exports is a function That's exactly what `minimist` is, works just fine. https://github.com/substack/minimist/blob/master/index.js Overall the import/exports semantics of es6 and cjs modules would be compatible if mixing named and default exports was prohibited, but the ability to have both is hard to represent in cjs modules. Don't understand this, do you have some code examples? I can't see why that would be the case. On Mon, Jul 21, 2014 at 10:24 AM, Brian Di Palma off...@gmail.com wrote: Which shows the how the backward compatability argument for default export/imports doesn't stand up. If you want to import `module.exports` then use the the `module` form if you want named imports use the named form. Default import/exports are generating nothing more then complexity, confusion and not serving their intended goals. On Mon, Jul 21, 2014 at 3:18 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: similar discussion at systemjs https://github.com/systemjs/systemjs/issues/131 which boils down to if a CJS module imports an ES6 module that has a key named default, what should the default behavior be. On Mon, Jul 21, 2014 at 10:05 AM, Brian Di Palma off...@gmail.com wrote: It's using traceur and building the modules to CJS, the project uses other non transpiled CJS modules. The only thing traceur could do here is compile the imports into a check for the named export `default` and use that if it exists. If it doesn't then simply return the CJS module object. Here is the output from traceur https://github.com/briandipalma/global-compiler/blob/master/out/index.js The relevant line would be `var minimist = require('minimist');` For default import from a CJS module you'd need to output ` var minimist = require('minimist'); if (minimist.default) { minimist = minimist.default; } ` Is that what you think traceur should do? On Mon, Jul 21, 2014 at 2:34 PM, Juan Ignacio Dopazo jdop...@yahoo-inc.com wrote: On Saturday, July 19, 2014 1:53 PM, Brian Di Palma
Re: Re: Quantifying Default Exports
It doesn't seem an issue that requires the ES6 module spec to have something like default imports though. The compiler could output ` newModule({ default: require('minimist') }) ` and importers could do `import {default as minimist} from 'minimist';` Or you could have ` newModule({ minimist: require('minimist'); }) ` and `import {minimist} from 'minimist';` depending on how the compiler is configured/written. This is implementation detail of compilers and loaders of legacy systems as opposed to spec concerns. On Mon, Jul 21, 2014 at 6:50 PM, Guy Bedford guybedf...@gmail.com wrote: Yes this is a bug that can be fixed at the compiler level. As you say we can generate a wrapper when loading a non-ES6 module in ES6: newModule({ default: require('minimist') }) We then conditionally add this wrapper based on detecting if the import is an ES6 module. This is the same method we have for AMD compilations at the moment, which seems to have been working well. On 21 July 2014 10:17, John Barton johnjbar...@google.com wrote: On Mon, Jul 21, 2014 at 10:06 AM, Guy Bedford guybedf...@gmail.com wrote: In Brian's case we actually need default exports. This is because the dynamic loader can't pick up the code he has written right now in ES6. This is how he is loading a NodeJS module in ES6: module minimist from 'minimist'; In ES6 this means give me the Module object with getters to the exports. But unfortunately in Traceur this is compiling into: var minimist = require('minimist'); As a result the `module` syntax can possibly return him a 'function' or other non-Module object. You seem to be saying The traceur implementation of 'module' fails in this case. It seems to me that Traceur could generate code which would wrap functions in Module objects. That is, this is not a fundamental limit, just an unreported bug. Thus we have broken the ability to parse his code in the ES6 dynamic loader, as it is not capable of returning a non-Module object for a module import, which is pretty critical. Thus default export properties are critical to enabling this support path. I believe that Caridy's point is: fine, use dynamic linking. On 21 July 2014 09:51, Caridy Patino car...@gmail.com wrote: Interoperability should not be a decisive factor here, we have fallen into that trap before, the conclusion was to let Loader to handle those cases rather than trying to drive it from the perspective of the module syntax. Let's focus on what is best and what makes sense for the ES Modules, and keep the dynamic module systems out of the picture since we know we have a lot of flexibility with the loader to deal with those dynamic modules. /caridy On Mon, Jul 21, 2014 at 12:37 PM, Brian Di Palma off...@gmail.com wrote: Yep, that makes sense. Highly unlikely but still possible and could cause issues. No doubt you could complicate your compiler to deal with these edge cases but why force that? Yet more problems with default imports/exports. This feature doesn't seem worth its cost. On Mon, Jul 21, 2014 at 5:21 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: (woops hit reply instead of reply all) Because the `function mainThing(){}` might already have a method named helper or, more likely, the named export is something like call or bind. On Mon, Jul 21, 2014 at 12:06 PM, Brian Di Palma off...@gmail.com wrote: On Mon, Jul 21, 2014 at 4:16 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: I have a CommonJS module which exports a single function ```js //cj.js module.exports = function (){} ``` If I was to transform it into an ES6 module the best way to do so currently it so use a default export ```js //cj2es6.js export default function () {} ``` now say I want to import those from another commonjs module, importing the first one is easy, but when importing the second one slightly less so, how should the loader treat that default export, a easy solution for this case is to simply have default exports act the same as a module.exports But then what would you do about es6 modules that use default and named exports like the example at http://jsmodules.io/ which can be sumerized as ```js export default function mainThing(){} export function helper (){}; , if we return a default export if it exists then there is no way to access the named exports. As mentioned in the GitHub issue I don't see why you couldn't compile to ` module.export = function mainThing(){}; module.export.helper = function(){}; ` Allowing access to the default and named. So in that case it would make more sense to treat default as just another export name. But if we do that then that means that if we go back to our second example ```js //cj2es6.js export default function
Re: Re: Quantifying Default Exports
What utility is that exactly? They are easier to import in terms of typing? I would hope that with ES6 modules all a programmer would have to write is the name of the import and the IDE would auto insert the import statement. The sort of IDE support you would see for Java or C#, of course that will only work with named exports. If everything is default then the IDE can't help that much when it comes to auto complete and inserts. I think that issue has already been addressed by people pointing out that modules were written in the default style due to named exports being ugly in CJS. On Mon, Jul 21, 2014 at 11:30 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: Wasn't the original issue single exports and their demonstrated utility in node and AMD? On Jul 21, 2014 5:49 PM, John Barton johnjbar...@google.com wrote: There are two issues here: 1) Is 'default' essential? 2) Should the spec. explicitly define commonjs loading? Brian is claiming 1) no and 2) no. More important for me: does 2) require 1). Evidently not. jjb On Mon, Jul 21, 2014 at 1:34 PM, Brian Di Palma off...@gmail.com wrote: It doesn't seem an issue that requires the ES6 module spec to have something like default imports though. The compiler could output ` newModule({ default: require('minimist') }) ` and importers could do `import {default as minimist} from 'minimist';` Or you could have ` newModule({ minimist: require('minimist'); }) ` and `import {minimist} from 'minimist';` depending on how the compiler is configured/written. This is implementation detail of compilers and loaders of legacy systems as opposed to spec concerns. On Mon, Jul 21, 2014 at 6:50 PM, Guy Bedford guybedf...@gmail.com wrote: Yes this is a bug that can be fixed at the compiler level. As you say we can generate a wrapper when loading a non-ES6 module in ES6: newModule({ default: require('minimist') }) We then conditionally add this wrapper based on detecting if the import is an ES6 module. This is the same method we have for AMD compilations at the moment, which seems to have been working well. On 21 July 2014 10:17, John Barton johnjbar...@google.com wrote: On Mon, Jul 21, 2014 at 10:06 AM, Guy Bedford guybedf...@gmail.com wrote: In Brian's case we actually need default exports. This is because the dynamic loader can't pick up the code he has written right now in ES6. This is how he is loading a NodeJS module in ES6: module minimist from 'minimist'; In ES6 this means give me the Module object with getters to the exports. But unfortunately in Traceur this is compiling into: var minimist = require('minimist'); As a result the `module` syntax can possibly return him a 'function' or other non-Module object. You seem to be saying The traceur implementation of 'module' fails in this case. It seems to me that Traceur could generate code which would wrap functions in Module objects. That is, this is not a fundamental limit, just an unreported bug. Thus we have broken the ability to parse his code in the ES6 dynamic loader, as it is not capable of returning a non-Module object for a module import, which is pretty critical. Thus default export properties are critical to enabling this support path. I believe that Caridy's point is: fine, use dynamic linking. On 21 July 2014 09:51, Caridy Patino car...@gmail.com wrote: Interoperability should not be a decisive factor here, we have fallen into that trap before, the conclusion was to let Loader to handle those cases rather than trying to drive it from the perspective of the module syntax. Let's focus on what is best and what makes sense for the ES Modules, and keep the dynamic module systems out of the picture since we know we have a lot of flexibility with the loader to deal with those dynamic modules. /caridy On Mon, Jul 21, 2014 at 12:37 PM, Brian Di Palma off...@gmail.com wrote: Yep, that makes sense. Highly unlikely but still possible and could cause issues. No doubt you could complicate your compiler to deal with these edge cases but why force that? Yet more problems with default imports/exports. This feature doesn't seem worth its cost. On Mon, Jul 21, 2014 at 5:21 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: (woops hit reply instead of reply all) Because the `function mainThing(){}` might already have a method named helper or, more likely, the named export is something like call or bind. On Mon, Jul 21, 2014 at 12:06 PM, Brian Di Palma off...@gmail.com wrote: On Mon, Jul 21, 2014 at 4:16 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: I have a CommonJS module which exports a single function ```js //cj.js module.exports = function (){} ``` If I was to transform it into an ES6
Re: Re: Quantifying Default Exports
Great work on the analysis, very thorough. For what it's worth I disagree with 3) Default exports improve interoperability with legacy modules. Based on my experience default exports do not help interoperability with legacy module systems. I'm currently working on a global namespaced script code to ES6/CJS module compiler using node.js. The compiler is written in ES6 and I'm using CJS npm packages in the project. When an npm package exports a named identifier it's trivial to use it in an ES6 module. import { parse, print } from 'recast'; When on the other hand it sets its export on `module.exports` default exports provide no help at all. There is no export named `default` to import, so I'm forced to use the module form. module minimist from 'minimist'; Examples taken from https://github.com/briandipalma/global-compiler/blob/master/src/index.js Default imports/exports seem totally unnecessary to me. Nothing more then a distraction, providing no value but overhead. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: ES6 and legacy module compatibility
SystemJS seems the best approach at the moment. https://github.com/systemjs/systemjs/ The ES6 module loader shouldn't have any built in knowledge of these other specs. It should be up to us to use loaders that are patched to understand these legacy module systems. Or we could compile these modules to ES6 modules and consume them with the default loader. Legacy module system features like object-as-module could also be supported by these custom interoperability loaders. Most likely by having them export a well known identifier (the ones suggested were default, exports or _) or a compiler can be configured to add a provided name. ``` import {default as Emitr} from 'emitr'; import {exports as Emitr} from 'emitr'; import {_ as Emitr} from 'emitr'; ``` Note that this is what SystemJS is already doing with CommonJS modules, using default. So ``` import {default as Emitr} from 'emitr'; ``` Works right now. Or if you control all your legacy codebase you could just compile it to ES6 wholesale. B. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: ModuleImport
So sometimes someone can need it, so we must have good support? Is that how we operate these days? Imagine a large codebase which already has transitive cyclic dependencies. If the module system has poor support for them it might still work with them until one day a developer reordered the import statements. How would you feel if such a simple operation caused you issues? Or upgrading to the latest version of a popular utility toolchain like lo-dash could introduce an issue purely because the upgrade created a transitive cyclic dependency. And the fix for that would be to reorder your import statements and add comments in your module telling people not to change the order. Again, how would you feel? TC39 has decided to spare us all those special moments by including good cyclic dependency support. // I don't actually know how someone would even access the default exports from the module object Like so, ``` System.import(MyClass) .then(function (myClassModule) { myClassModule.default }); ``` Default import and exports are purely sugar over ``` import {default as MyClass} from 'MyClass'; ``` It saves you a few character typing out when importing from legacy module system. ``` import MyClass from 'MyClass'; ``` Those two are the same thing. From birth the brand new module system is going to have this superfluous appendage to support module systems that 10 years from now people will struggle to remember. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: ModuleImport
The arguments for and against supporting cyclic dependencies seem to be academic. I'm yet to see any evidence of their importance in practice nor proof they they are fundamental ... or not. Transitive cyclic dependencies. I'd say that's the case that was in the minds of the authors of the module system. In large codebases those can happen and a module system that does not handle them gracefully would be poor. Support for them is needed, and what CommonJS has is not good enough. They are acknowledged in the modules documentation for node http://nodejs.org/api/all.html#all_cycles This does not mean they are recommended, the same holds true for ES6 modules. It is an acceptance of the reality of complex and large codebases that sometimes cyclic dependencies can occur. It boils down to this. You can import a dependency in three ways import MyClass from 'MyClass'; import {MyClass} from 'MyClass'; module myClass from 'MyClass'; That's one too many ways for the simplest module system that fulfills all requirements. import MyClass from 'MyClass'; import {MyClass} from 'MyClass'; import * as myClass from 'MyClass'; Is not the fix. The confusion stemmed from the first production not the last. Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. B. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: ModuleImport
Static checking will be limited anyway. If you want to go this way you shoud use typescript. If you don't want static checking you should stick with ES3. Fixed that for you. Yes big projects are possible with JS, I work on them everyday. It would be nice if the language made them easier, that's what we are talking about. Big projects are possible with C, why bother with any other language? With sufficient rigor Assembly will do the trick. Just have good code reviews and test. ability to dynamically import modules in addition to static imports. IMO this should be packaged as an async API I think this is already possible using the loader. hooks for transpilers. This should also be an API Ditto. Usually, I obtain the same benefit running the tests (and more, test that were the product of TDD workflow) I can forsee many people writing tests where they configure the module loader to load mocks instead of true dependencies. This could result in tests passing while there is a breakage in the application. If the language can make some of these problems go away then we are better off. It's just like tests, code review and linting, it's another type of verification. I think that a possible compromise that can still make the ES6 module system more compatible with both AMD and CommonJS modules The ES6 module system is compatible with CommonJS and AMD, I'm happily mixing the two together with libraries like SystemJS https://github.com/systemjs/systemjs/ For example https://github.com/briandipalma/flux-es6/blob/master/src/Store.js The Emitr class here is imported from a CommonJS module It is important to focus the design on loader issues and keep things orthogonal. The Loader is quite solid and well designed, I've not heard any major issues with it. What does it have to do with this discussion? import {foo} from './foo'; var foo = require('./foo.js').foo; I though those two statements weren't comparable? The import statement can only be present at the module top level while the require can be written in any code block. That leaves it open to the random number require issues which makes static checking impossible. As you pointed out it's not a language standard so I'd imagine that's another reason why tooling is so weak. Rather than point towards type-checking, I think we should focus on the actual checks offered by the module design. It seems that these would come with a small cost quite unlike type-checking. Unless I'm misunderstanding Kevin I think we've both talking about exactly that. I guess people saw static and automatically added type. Just static checking of import and export bindings. A much smaller scope feature then static type checking. This discussion has veered off track, it's about a new ModuleImport form, which grew into questioning if default imports/exports was the real problem. I'd be interested in knowing if it's possible that instead of changing the ModuleImport form the default import/export idea could be postponed instead. It could be added in later if there really was need for it. As far as I can tell libraries like SystemJS can smooth over issues caused by importing from legacy module systems like CommonJS and AMD. Leaving default imports/exports an odd third way to import that was added based on some notion of backward compatability that wasn't needed. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: ModuleImport
I'm echoing Kevin here. I'd hope ES6 modules would offer me, a programmer working on large complex JS web apps, something more then what CommonJS/AMD offers. I work with codebases of 1K+ JS classes, 200K+ LOC and with many dependecies that are updated frequently. When our teams update depedencies the more static fast failures we can get compared to silent bugs the better. I will eat my hat if in 10 years people will be doing greenfield development using CommonJS/AMD instead of ES6 modules. Provide the language users with something *better* then what we have, don't just match it. I like CommonJS, npm, node as they offer great solutions given their constraints. This is the language level though, the expressive power and constraints are different. Knowing the name of a module export is not an issue, it's not an issue for people using global scripts or any other module systems/languages. I'd prefer a real module system. Especially considering that classes are being added and when you are building front end applications with a lot of state classes fit well. I can see many applications being mainly composed of modules with a single class exported and the most logical export name would be the classname. I've tried to use default exports for these situations and they don't seem to offer much value at all. import {MyClass} from './myclass'; The value of default exports seems low here. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: ModuleImport
Andreas, I hope you're not just getting my hopes up with the possibility of checking ModuleImports too. That would be great. I was disappointed that they weren't originally. Making module fs from 'fs'; fs.readFile(...); and import {readFile} from 'fs'; equivalent in terms of static checks is the right approach. If the cost of these improvements is not having default exports it seems acceptable. In essence we would have to write import {jquery} from 'jquery'; instead of import jquery from 'jquery'; The flexibility of not having to know the export identifier is worthless to me. I can't see how I could make use of a module without reading some documentation on it, which will show me the identifiers. Static checking and lazy binding should be value added features, not something I have to think about every time I import a module. I don't understand how you can make use of what you require without reading some sort of documentation or code. This will be an even smaller cost once tooling supports ES6 modules as it will allow autocompletion of imports statements. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: Rationale for dropping ModuleImport syntax?
Is there anything preventing the addition of a ModuleImport like affordance at a later stage (e.g. ES7)? I haven't done much development with ES6 modules but I've not found much use for that form when I have. Related to some other comments made in this thread, I think static verification errors are a great idea. I'd also like to echo the comments that ES6 modules seem well designed, looking forward to native implementations. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: Rationale for dropping ModuleImport syntax?
On Thu, Jun 12, 2014 at 6:37 PM, Chris Toshok tos...@gmail.com wrote: On Thu, Jun 12, 2014 at 3:46 AM, Brian Di Palma off...@gmail.com wrote: Is there anything preventing the addition of a ModuleImport like affordance at a later stage (e.g. ES7)? ModuleImport is the only way (in syntax) to achieve CommonJS `require` behavior on the consumer-side when a module author exclusively uses multiple exports. Its lack will force existing module maintainers to export as small a set as possible - likely either a single identifier - so that they can service the existing identifier-as-namespace convention CommonJS forces. Given that there's no real syntactic difference between single identifier export and default export, I would imagine default export would win since then you get: `import _ from 'underscore'` instead of import { _ } from 'underscore'`. I can see that being a valid path for certain modules to take. I'm not sure large utility packages will be as prevelant in future though. Once we have a standard module system it seems just as likely that these packages might break apart somewhat. There seems no reason to load all of underscore into a module for just one or two functions. The underscore web page itself divides the functions http://underscorejs.org/ We should also be wary of building cases on code from Parsers, I believe the unstructured switch statement was designed for parsers. It didn't turn out to be an optimal design for routine programming though. I was more wondering if there was anything preventing a module import statement from being added later, if it was found to be a requirement. I can't see any reason why it couldn't, that would also allow time for bikeshedding the syntax. Related to some other comments made in this thread, I think static verification errors are a great idea. I'd also like to echo the comments that ES6 modules seem well designed, looking forward to native implementations. I definitely agree. I think the semantics and specification are awesome. And having syntax at all is *huge* for tooling and aot/static compilers. The ModuleImport syntax can be bikeshedded until the cows come home. It's not important (to me). What's important is that there is syntax to get at its functionality, not imperative code. The imperative code given as an alternative is ugly, it probably won't gain many users. IMO the only real issue is the tight coupling between syntax used to import and syntax used to export. Why as a module consumer should the module author's choice dictate which syntax I'm forced to use? And why as a module author should the syntax my users want to use dictate how I have to export my module? If syntaxes were decoupled, ModuleImport could go away and we wouldn't lose the functionality, it would simply be `import _ from 'underscore'`. I like the idea but I can't imagine many people would welcome yet more changes to ES modules. I don't think it's outlandish, the possibility that a large enough portion of the community will decide on a single import syntax as best, and network effects will result in it going from best to only. -c ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: Rationale for dropping ModuleImport syntax?
On Thu, Jun 12, 2014 at 8:50 PM, Kevin Smith zenpars...@gmail.com wrote: I was more wondering if there was anything preventing a module import statement from being added later, if it was found to be a requirement. I can't see any reason why it couldn't, that would also allow time for bikeshedding the syntax. It could be added later, but to turn the question around: why should it be dropped? It has been part of the design for a very long time, it's currently used by many people working in the ES6 space, and it meets a semantic need. If you want to drop a feature this late in the game, then you need to show that it's one of the following: 1. Buggy 2. A footgun 3. Not useful 4. Future-hostile I don't see that it meets any of those requirements, do you? I have no strong opinions either way. I don't feel it's any of those things. The argument that was given was that people were confused by it and were using it like an `import` statement. I said to Eric via Twitter that if people were building incorrect compilers and modules then they will eventually learn the error of their assumptions. To me the argument didn't seem that strong, the native implementations will be correct and people will correct their broken code. I'm not supporting the removal. I simply don't think it's a catastrophe. Kevin ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: Rationale for dropping ModuleImport syntax?
On Thu, Jun 12, 2014 at 10:07 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: isn't the foot gun the difference between single and multiple exports, i.e. I thought it was imports that were being misused. People were writing module m from 'mymodule'; m(); So they treated `module` just like `import`. I'm not sure I see the logic in doing that. Did they not wonder why there were two ways to accomplish the exact same thing? As I said, I didn't find the reasoning compelling. to import underscore you'd use module _ from 'underscore' because it is multiple methods on an object but for jquery you'd have to use import $ from 'jquery' because the root object is a function instead of an object On Thu, Jun 12, 2014 at 8:50 PM, Kevin Smith zenpars...@gmail.com wrote: I was more wondering if there was anything preventing a module import statement from being added later, if it was found to be a requirement. I can't see any reason why it couldn't, that would also allow time for bikeshedding the syntax. It could be added later, but to turn the question around: why should it be dropped? It has been part of the design for a very long time, it's currently used by many people working in the ES6 space, and it meets a semantic need. If you want to drop a feature this late in the game, then you need to show that it's one of the following: 1. Buggy 2. A footgun 3. Not useful 4. Future-hostile I don't see that it meets any of those requirements, do you? I have no strong opinions either way. I don't feel it's any of those things. The argument that was given was that people were confused by it and were using it like an `import` statement. I said to Eric via Twitter that if people were building incorrect compilers and modules then they will eventually learn the error of their assumptions. To me the argument didn't seem that strong, the native implementations will be correct and people will correct their broken code. I'm not supporting the removal. I simply don't think it's a catastrophe. Kevin ___ 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: Re: Null iterable in for-of?
throw. Fast fail is better. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: detecting JS language mode for tools
In-Reply-To= 5B36C364-13FF-44AA-9B01-4ABC25AB4D65%40wirfs-brock.com Regarding the .jsm suggestion, a colleague suggested .es, no need for the m as you could say all ES files are modules. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: any toMethod() use case ?
This is sort of OT but not too much. I have a concern about how mixins will be implemented in ES. It concerns clashing property identifiers in mixins and the classes taking their behavior. By way of a simple example an Emitter could have a local property this.listeners for its own internal purposes. Likewise a class that mixes in Emitter could also have a local property this.listeners. I was wondering if the delayed Object.mixin implementation included some sort of sandboxing to deal with this case or if it was left to the discretion of the developer? I guess the obvious suggestion is to use Symbols in Emitters, does this mean sandboxing will not be a consideration for Object.mixin? You could imagine a new version of the Emitter introducing a new identifier that could clash and lead to tricky bugs especially if the mixin did not define the identifier until certain conditions were met.. On Tue, Dec 3, 2013 at 8:52 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Dec 3, 2013, at 12:10 PM, Andrea Giammarchi wrote: Thanks Allen, however you know which super will be and what that operation does once invoked, right? Isn't toMethod bringing scenarios where you don't know what that would do? Isn't that mixin unusable for any other kind of object that is not inheriting Map? The latter is the one that I don't get ... I can use toMethod for something that will simply break or not behave as expected, while what I'd like to do is to be sure that the Map method is used and nothing else. Nope. There is absolutely no dependency upon Map in the code I wrote. Each of the methods I showed have a dependency upon finding a like-named property up the prototype chain of the object it gets bound to (via toMethod) and implicitly assumes such properties correctly implement appropriate map-like behavior. They do not depend upon finding Map.prototype on that prototype chain or upon finding the built-in implementation of the corresponding methods. These assumptions are no more risky then the assumptions I would have been making if instead of a super call I had coded: return Map.prototype.has.call(this, key); When I code that I assume that, at runtime, a 'has' property will be found on Map.prototype, that the value of that property is a function, and that the function implements that contract that I'm expecting. Saying super(key) or even super.has(key) makes the same assumptions but is not tied to any one particular inheritance hierarchy. Allen ___ 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: Modules vs Scripts
You can statically analyze the module text and enumerate the complete imports and exports of the module without having to execute the module. The execution of the module will not dynamically increase it's imports/exports. For instance could you have a Math.random that decides if a dependency is required? On Nov 18, 2013 1:33 PM, Sam Tobin-Hochstadt sa...@cs.indiana.edu wrote: On Nov 18, 2013 7:17 AM, Brian Di Palma off...@gmail.com wrote: Correct me if I'm wrong David but module import/exports are not dynamic which allows tooling/IDEs to be more intelligent and programmers to easily understand what dependencies a module has/provides? Yes, that's correct, if I guess correctly at what you mean by dynamic. Sam On Sat, Nov 16, 2013 at 8:30 AM, David Herman dher...@mozilla.com wrote: On Nov 16, 2013, at 3:32 AM, John Barton johnjbar...@google.com wrote: Could someone help me understand why two goals for parsing JS is a good thing? Hm, it sounds like you've assumed a conclusion already. Let me try to explain anyway. Scripts are for synchronous loading and evaluation; modules are for asynchronous loading and evaluation. The former is not allowed to import, which triggers I/O. The latter is allowed to import. There was always going to have to be a syntactic split. But there's more. I'll be explaining at this week's TC39 meeting some more details about the intended model for browser integration. In short, declarative code based on modules will use the module tag (or script type=module, which will mean the same thing and allows polyfilling today). This is better than script async, which was a hopeless idea. This also works beautifully for fulfilling the promise of 1JS: a new, better initial environment in which to run top-level application code without requiring versioning. module var x = 12; // local to this module, not exported on global object import $ from jquery; // asynchronous dependency, NBD '$' in this // nope, because all globals are scoped to this module let y = 13; // yep, let works great because modules are strict /module Same number of characters as script, better semantics, better global environment, better language. If you're not excited about ES6 yet, get excited. :) Dave ___ 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: Weak callbacks?
Are these callbacks triggered for the garbage collection of any object or just weakrefs? They could be useful to help track down memory leaks, although the tooling in Chrome is quite good for that. On Wed, Nov 6, 2013 at 7:15 PM, Domenic Denicola dome...@domenicdenicola.com wrote: Thanks Mark for the education, especially on the pre- vs. post-morterm finalization distinction. I don't think I was specifically advocating for pre-mortem in my OP, since I didn't really understand the difference :P. Post-mortem finalization sounds quite reasonable. What do people think of introducing it into ECMAScript? ___ 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: ES6 Timeline
Thanks Rick, From my reading of that schedule we could hope to have ES6 features like modules and classes ready for use in production code (via something like traceur) by Q1 next year? The June/July/Dec 2014 dates are simply dot the i's and cross the t's milestones, standardisation bureaucracy? In other words we won't have significant changes to the language and we can finally start to integrate ES6 into production codebases? On Fri, Nov 1, 2013 at 1:23 PM, Rick Waldron waldron.r...@gmail.com wrote: On Fri, Nov 1, 2013 at 12:02 AM, Nathan Wall nathan.w...@live.com wrote: Hey guys, I really think you're all doing an awesome job with the development of the future of the language, especially all the work Allen's putting into the drafts. I'm really dying to start using some of these features. Last I heard (probably over a year ago), the plan was to have ES6 out by the end of this year... It still looks like there's a good bit of work to be done for things to be finalized. Are there any updates on when we can hope to have a finalized ES6? Schedule: https://github.com/rwaldron/tc39-notes/blob/48c5d285bf8bf0c4e6e8bb0c02a7c840c01cd2ff/es6/2013-03/mar-13.md#416-current-status-of-es6 Nathan ___ 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: ES6 Timeline
On Fri, Nov 1, 2013 at 3:55 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: There is still plenty of work to do to reach the Ecma standard stage in Dec 2014, but from a feature perspective ES6 should be done within the next 3 months. Excellent news, thanks for the summary. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Refutable destructuring
It looks to me like there are people who want a sort of ducktypeof operator. arg1 ducktypeof MyClass Which would return true if the shape of arg1 where the same as MyClass. If I wanted to write as a refutable pattern I could end up with a large block that may be repeated in several class methods. It would be nice to shorten that so that you could declare tersely that your methods require a specific shape to be passed in. On Aug 10, 2013 1:47 AM, Brandon Benvie bben...@mozilla.com wrote: On 8/9/2013 5:45 PM, Allen Wirfs-Brock wrote: and if we make U+2639 a special token that evaluated to throw TypeError we could say function foo( {a=☹ }) {} This would be awesome. __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: typeof extensibility, building on my Value Objects slides from Thursday's TC39 meeting
Would type annotations not be a cleaner way of achieving discrimination between types? Would these APIs be redundant if we had type annotations? On Mon, Aug 5, 2013 at 8:13 AM, Bruno Jouhier bjouh...@gmail.com wrote: From a dev standpoint what we need is a clean API to discriminate between types. Sometimes we want to discriminate between objects (mutable) and values (immutable), sometimes between functions and non functions, sometimes between numbers, strings and others, etc. And we don't want to have to write an extra test to exclude null from objects. As we cannot break the existing typeof and its little warts, could we introduce a new call, something like Object.typeInfo(x), that would return a little hash like: { type: int64, immutable: true, number: true, ... } { type: string, immutable: true, number: false, ... } { type: array, immutable: false, number, false, ... } The idea it to have boolean flags like immutable/number/... to categorize types. This way we can discriminate by testing a flag instead of having to test complex combinations of typeof, Array.isArray, etc. ___ 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: [module] dynaimic namespace/scope
Excellent point. I had forgotten all about polyfills. You could work around that issue by allowing augmentation of the @std module in some manner...in essence that's what a polyfill does. Your polyfill code would be loaded up first, it would augment the standard module and then your application code would execute with no issues. This would mean the standard module is not consistent with other modules so it's not a proposal I'm putting too much weight on. On Thu, Jul 11, 2013 at 6:26 PM, Brendan Eich bren...@mozilla.com wrote: Brian Di Palma wrote: That would require a tedious preamble for pretty much any bit of code you want to write. You can add an exemption for any code/classes/functions in @std modules. Beyond those cases I see no issue. Object detection is a (if not *the*) successful anti-versioning pattern in JS on the web. It typically depends on global properties that may or may not be present, accessed in the detection condition via window.foo or typeof foo but then bound in the not-detected consequent, and used later, without any object-property base-expression (dot) qualification. Object detection ought to be usable in a module, and IIRC this is another consideration informing the current design. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Maps and Sets, goodbye polyfill ?!
// ES6 function* entries(obj){ for (let key in obj) { yield [key, obj[key]]; } } cool, but why do we need that exactly ? The one suggestion I can make is that generators mean you don't have to calculate the entire answer up front. This is well demonstrated by Brandon's code examples. This could be a nice performance gain under certain circumstances. // ES3-5 version function entries(obj){ var keys = []; var index = 0; for (keys[index++] in obj); var total = index; index = 0; return { next: function(){ if (index total) { var key = keys[index++]; return { done: false, value: [key, obj[key]] } } return { done: true }; } }; } have you guys read this article ? where it talks about JS people not thinking about GC and RAM ? http://sealedabstract.com/rants/why-mobile-web-apps-are-slow/ I have read the article, I found it interesting. I was just wondering if the 'const' keyword would help give JS another small performance boost. As Andreas points out the major issue is that JS is highly dynamic, this can be very useful sometimes but for most code it's not required. Maybe if you mark everything as const or freeze/seal classes then maybe JS engines will optimize for that code. One issue that could help with is memory allocation for JS objects, maybe that will make it easier to know how much memory to allocate for a class, or JS object if it's marked as a const. I don't know for sure as I lack the knowledge, I do know that in ES6 code I will use const as my new var. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Maps and Sets, goodbye polyfill ?!
OK. So we have reached Peak JavaScript then. If people write JS code without triggering shape changes then the JIT should be able to produce code that can match a JVM? If there was something that I could do as a developer that could help the JIT I would do it. Would ES6 classes not make the creation of shapes a lot easier? From what I understand it takes time to figure out shapes/hidden-classes. Well I'm marking this object as a class, does that help? It would be interesting if engines provided feedback on when we developers break the optimistic optimizations. On Sat, Jul 13, 2013 at 9:43 AM, David Bruant bruan...@gmail.com wrote: Le 13/07/2013 10:21, Brian Di Palma a écrit : I was just wondering if the 'const' keyword would help give JS another small performance boost. Unlikely. Const can be almost statically inferred (no assignment to a given variable). The almost refers to cases where eval happens. Worst case, if there is no assignment, a variable can be optimistically optimized as const. If the value is changed via eval, then de-optimize (but in practice, eval is rare, so the optimistic optimization will be worth it) As Andreas points out the major issue is that JS is highly dynamic, this can be very useful sometimes but for most code it's not required. Maybe if you mark everything as const or freeze/seal classes then maybe JS engines will optimize for that code. JS engines already optimistically optimize assuming code remains stable (for objects, V8 has hidden classes, SpiderMonkey has the equivalent shape feature) and deoptimizes when the dynamic features are being used. It might be one of the reason why maps are better at being maps than objects (since objects seem to have been optimized for cases where they are stable) David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
I didn't suggest that strings as event type would block anyone, strings work fine. I asked for some consideration to be given to also being able to use a unique object as the type key. I gave some reasons, copied below. So in a modern IDE you could click on MY_EVENTS.PERMISSION_UPDATE and it would display the object which could contain the arguments the callback is provided with and a place to document the event. It might also improve minifying/refactoring and searching for occurrences of the event much easier then if it where a simple string. None of which are critical but could be handy when dealing with larger code bases and your event is simply called click. I'm not too wedded to the idea, but I can imagine that if you are building applications with hundreds of packages and modules it might be a safer/easier way to identify instances of your specific event listeners. On Thu, Jul 11, 2013 at 11:04 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: trivial like ... 2 weak maps + a set for a single event ? ```javascript obj.on(evt, handler); ``` .. internals ... ```javascript // wm as private internal generic WeakMap if (!wm.has(obj)) { // creates related WeakMap wm.set(obj, new WeakMap); } if (!wm.get(obj).has(evt)) { wm.get(obj).set(evt, new Set); } wm.get(obj).get(evt).add(handler); ``` I have the feeling it's very true in JS world nobody ever thinks about RAM and GC ^_^ That said, it becomes over complicated for non concrete reason/use case if we have strings since AFAIK WeakMap does not accept strings as key. For all this time the event type as string has blocked like ... nobody ever ? I wonder again what's the benefit then to instantly over complicate an API at this stage instead of looking around what worked already for everyone. Maybe it's me not seeing the power of objects as events. br On Thu, Jul 11, 2013 at 2:32 PM, Rick Waldron waldron.r...@gmail.com wrote: On Thu, Jul 11, 2013 at 4:45 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: I would simplify saying that symbols can be used as well as strings ? I don't see any usefulness into using an object as event type and I think if we start olready over-engineered/complicated this will never see the light in any spec which is a lost/lost if you ask me It's trivial if an Emitter uses something like [[MapData]] or [[WeakMapData]] as it's internal data property for event storage. Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Fwd: [module] dynaimic namespace/scope
This is still a dynamic error (a reference error, like Rick said), which I'm not really happy about. The only alternative I've thought of is changing such properties to non-configurable at compilation time of the module that references them. But that's a weirdly non-local effect, and is probably worse than the disease. There is the alternative that you error on all non explicitly imported variables. If this system were being designed in a green field environment I'd imagine that's how it would be built. I realize that means people would have to import {console} from std/console; for logging, but that's hardly such a crippling issue once proper IDE support exists for ES6 modules. I'd imagine auto complete will insert that at the top of your .js file if you are using it inside a module. Why allow global scope to leak into a new module? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [module] dynaimic namespace/scope
But if you try to modularize the code like: script async module mod { export function getNode1() { return node1 } export function getNode2() { return node2 } } /script div id='node1' / div id='node2' / then it may randomly work or fail with an error depending upon who wins the race. What seems like it should be a safe refactoring instead produces non-deterministic intermittent errors. The code would be export function getNode2() { return document.getElementById(node2); } Though which should be fine. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [module] dynaimic namespace/scope
That would require a tedious preamble for pretty much any bit of code you want to write. You can add an exemption for any code/classes/functions in @std modules. Beyond those cases I see no issue. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
I'm in favour of this standard class approach. I just hope that when discussing this people would also entertain a non-string event type. emitter.addListener( MY_EVENTS.PERMISSION_UPDATE, callback ); So in a modern IDE you could click on MY_EVENTS.PERMISSION_UPDATE and it would display the object which could contain the arguments the callback is provided with and a place to document the event. It might also improve minifying/refactoring and searching for occurrences of the event much easier then if it where a simple string. On Thu, Jul 11, 2013 at 2:37 AM, Rick Waldron waldron.r...@gmail.com wrote: On Wed, Jul 10, 2013 at 9:31 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: On Wed, Jul 10, 2013 at 6:16 PM, Rick Waldron waldron.r...@gmail.com wrote: I absolutely stand by championing such a standard module. then I stop here waiting for other opinions about championing an Emitter mixin/module/constructor in core. best regards I feel like we've made progress https://github.com/tc39/agendas/pull/6 Rick ___ 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: Automatically binding extracted methods
I suppose a special binding operator has already been discussed and discarded? const functionBoundToclassInstance = classInstance-methodName and everytime classInstance-methodName is called it gets returned the same function meaning references don't have to be stored for unsubscribing from listeners. On Fri, Jun 14, 2013 at 7:57 PM, Brendan Eich bren...@mozilla.com wrote: Alex Russell wrote: This, incidentally, is the sort of way I'd hoped we'd slot in soft-binding. I still do not know how to do soft binding with acceptable implementation cost. But anyway, this seems like very hard binding. How would you rebind |this|, ever? /be On Fri, Jun 14, 2013 at 11:45 AM, Axel Rauschmayer a...@rauschma.de mailto:a...@rauschma.de wrote: Thanks to proxies now having a separate trap for “invoke”, we can automatically bind methods on “get”. I’ve written down my thoughts here: http://www.2ality.com/2013/06/auto-binding.html Axel -- Dr. Axel Rauschmayer a...@rauschma.de mailto:a...@rauschma.de home: rauschma.de http://rauschma.de twitter: twitter.com/rauschma http://twitter.com/rauschma blog: 2ality.com http://2ality.com ___ es-discuss mailing list es-discuss@mozilla.org mailto: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 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [[Invoke]] vs [[Get]]
On Sun, Jun 9, 2013 at 4:18 PM, Tom Van Cutsem tomvc...@gmail.com wrote: No, we can't just blindly call GetValue in step 1 as that would lead to the get trap being invoked on a proxy (which is the wrong trap). Why can't we have the two traps trigger? I would imagine that proxies are meant to be consistent with getters/setters? So in this example obj.f() triggers the getter, yet if I understand what you're advocating it wouldn't trigger a [[Get]] trap? var obj = { get f() { console.info( getter called. ); return console.info.bind(console); } } obj.f( getter also called ) getter called. getter also called Surely if these names where to be consistent for proxies then a get trap followed by an invoke trap should be fired? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Standard modules - concept or concrete?
The standard modules wiki page ( http://wiki.ecmascript.org/doku.php?id=harmony:modules_standard ) is not clear as to whether what it describes is a concrete proposal and that ES6 will include it or it's purely a concept. The page does not seem to be linked/mentioned from any of the other module pages ( at least based on a cursory read of the main module pages ). Is this a prerequisite for static checks in modules ( forbid all globals in modules unless explicitly imported )? I'm sure the checks aren't as harsh, but I'd love such strictness as it can make tooling more powerful and code simpler to understand and follow. The idea that you can grab anything from the global object without first importing it seems wrong. Are standard modules the future of built-ins for ES? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [[Invoke]] vs [[Get]]
If you have a [[Get]] trap it seems wrong to skip it when you also have an [[Invoke]] trap. Maybe you should execute the [[Get]] first and feed its result into the [[Invoke]] one? obj.method(); I'd expect the [[Get]] to always have its say and not to be just ignored in a possibly dynamic fashion. On Sat, Jun 8, 2013 at 11:30 AM, Till Schneidereit tschneider...@gmail.com wrote: At the last TC39 meeting, an agreement was reached for proxies to support an Invoke trap. I'm currently implementing this trap in SpiderMonkey[1] and realized that there's one conceptual issue that has to be decided in the spec: Currently, the [[Get]] trap naturally handles method calls on the proxies, as these are gets followed by calls to the returned function value. With proxies also being able to trap [[Invoke]], things become less clear, with four possible options: 1. for method calls, only the [[Invoke]] trap is called 2. if an [[Invoke]] handler exists, it is called, otherwise a [[Get]] handler is called, if that exists 3. like 2., but additionally, if the [[Invoke]] handler doesn't return a callable value, the [[Get]] handler is called 4. like 3., but with reserved order of handler invocation: if a [[Get]] handler exists, it is called. If the result isn't callable, or [[Get]] isn't handled, an [[Invoke]] handler is called, if one exists The first of these options seems conceptually cleanest to me, but I do think that the other options (perhaps except for the last one) can be argued for to some extend, too: the abstract operation `Invoke`, via its step 5, `GetMethod`, contains a call to the [[Get]] operation, after all. [1]: https://bugzilla.mozilla.org/show_bug.cgi?id=878605 ___ 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: Standard modules - concept or concrete?
Good, I like the standard modules idea. On Sat, Jun 8, 2013 at 2:33 PM, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote: The global object will still be accessible in modules. Of course, you can create new module loaders with an empty global. Umm. It makes porting old code easier. If we could guarantee that any reference inside a module had to have an import definition I imagine IDEs and development concatenation tools would provide fast feedback when those rules are broken. Why would people use the standard modules if they can just access the global? Is it expected that developers import things like Date because it would be good practice? import { Date } from @std; or simply new Date(); I can imagine many people just taking option 2. Seem to make standard modules somewhat redundant, or at least it undermines them. I suppose then the static checks are only to check that a module imports the identifiers that another module exports, is that it? If we can grab anything from the global that means un-imported references can be used all over module code and the environment will just have to shrug its shoulders an accept it. No compile time error. Somewhat disappointed with that. So modules will be allowed to be polluted by the global state, not just build in globals but any possible user defined global state. The possibility of strengthening module consistency is off the table? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Standard modules - concept or concrete?
On Sat, Jun 8, 2013 at 7:07 PM, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote: I think you misunderstand. The requirement that modules not have free variables at compile time *includes* global references. I expect that development environments won't have a problem handling this or enforcing whatever properties you're looking for. I think I see what you're saying. Let me just see if I'm correct. At compile time any references in a module which are not explicitly imported but are language globals will not cause compile errors. Any references which aren't explicitly imported and aren't language globals will cause a compile error? So module test { new Date(); } is fine. While module test2 { $ } will throw an error unless you add the line import $ from jquery; even if jQuery was available in the global scope and had been loaded in by a normal script tag? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.values and/or Object.forEach ?
Surely the Map class would be used from now on for these use cases? It seems ideal. On Jun 7, 2013 7:21 PM, Rick Waldron waldron.r...@gmail.com wrote: On Fri, Jun 7, 2013 at 1:25 PM, Brandon Benvie bben...@mozilla.comwrote: On 6/7/2013 10:18 AM, Dean Landolt wrote: The for/of iterators solve this nicely. This is definitely something that comes up a lot though, and this seems like a very handy cowpath to pave. If it were spec'd I'd suggest the naming and argument values should align with the for/of variants. My impression was that the @dict module solves this as you suggest. import { keys, values, entries } from '@dict'; let obj = { a: 1, b: 2, c: 3 }; for (let key of keys(obj)) { // ['a', 'b', 'c'] } for (let value of values(obj)) { // [1, 2, 3] } for (let [key, value] of entries(obj)) { // [['a', 1], ['b', 2], ['c', 3]] } This is correct: https://github.com/rwldrn/tc39-notes/blob/master/es6/2012-11/nov-29.md#conclusionresolution-5 Rick __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://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
Fwd: Why is concise body for method definition dropped?
Meant to send the message to es-discuss! -- Forwarded message -- From: Brian Di Palma off...@gmail.com Date: Wed, Jun 5, 2013 at 9:12 PM Subject: Re: Why is concise body for method definition dropped? To: Brendan Eich bren...@mozilla.com Was there any desire to support Rust style expressions if enclosed within '{}' i.e. class C { method( x ) { x + x } } So the same as in Rust, the last value is returned if no ';' is used to turn the line into a statement? It's quite elegant and I would imagine is a safer approach? On Wed, Jun 5, 2013 at 4:38 PM, Brendan Eich bren...@mozilla.com wrote: Matthew Robb wrote: At one point I was under the impression that the following would produce an implicit return method: class x { method(x) x+x } We dropped it. Maybe Rick can find the meeting notes -- I'm short on time due to travel today. The problem is you must terminate with a ; or else the expression body may continue into what the user intended to be a subsequent property name, especially one of the form we considered (but ultimately rejected for now): class C { method(x) x+x [symbol]: 42 } If there was no syntax error, then ASI does not apply. Now we could reckon that [computed-property-name] is out, so we can put expression body back in -- but the future-fragility if not future-hostility stayed our hands from doing this. I think that's the right call, still. /be On Wed, Jun 5, 2013 at 8:07 AM, Rick Waldron waldron.r...@gmail.com mailto:waldron.r...@gmail.com wrote: On Wed, Jun 5, 2013 at 10:56 AM, Matthew Robb matthewwr...@gmail.com mailto:matthewwr...@gmail.com wrote: Does a concise body method still return by default? ArrowFunction offers implicit return in the unbraced form: let two = () = 1 + 1; two(); // 2 Whereas the braced form requires an explicit return, otherwise returning the default undefined. Rick /snip -- - Matthew Robb ___ 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: Harmony modules
Based on my understanding of modules ( so this may well be wrong ) where you want to use the module you would write import someThing from mymodulefile and inside mymodulefile.js, the file that exports the resource you want to use, you would do function someThing(){} export someThing; and mymodulefile can be a physical file on your server or it can be mapped to another resource by using the Loader.ondemand method. In the environment that runs the JS there is a mechanism for IO - it's the environment that provides loading capabilities. On Sun, Jun 2, 2013 at 12:14 AM, Jorge jo...@jorgechamorro.com wrote: On 01/06/2013, at 23:57, François REMY wrote: Arrow functions probably shouldn’t be used for this, this is not very readable. Yeah, arrow functions are grawlix-y per se, but I've come to admit that Brendan (et al) was (were) right: they're going to be a Good Part™. I think you should have a look at modules, this is what is expected to replace this pattern ;-) I understand node modules perfectly but everything I've seen in es-discuss about the modules proposal was almost incomprehensible (for me). Do you know of a harmony-modules-for-dummies doc or video that I can read/see to learn more? :-) How would I turn this IIFE into an inlined module? var myModule= (()={ //... return someThing; })(); Also, in node the modules are read synchronously from a disk drive, how can these new es6 modules deal with modules that have to be read from the network when is JS there's no means for IO? Thank you, -- ( Jorge )(); ___ 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: Module naming and declarations
. module novox/grid { export class GridDecorator { } } That will throw an error won't it? I've declared the same module identifier twice and that will trigger an error. I'd be forced to write module novox/grid/GridDecorator { export class GridDecorator { } } So my module identifier are namespaced by including the leaf node ( the class I'm exporting ). import { GridView } from novox/grid/GridView; Pity to have that redundancy but it seems we have no choice. Also must I have the module declaration in each class/file. I think not, correct? module novox/grid/GridDecorator { //I think this line is not required? export class GridDecorator { } } When I concatanate I will need to insert that line though? Yes, I wasn't planning to paste any jQuery code into any file I was thinking more about how our bundler would output the code. I know that multiple versions of libraries is an awful requirement but that's what some of the tier 1 banks have been asking for. They have large, seperate teams and they don't coordinate in any way... Also, if jquery imports something, and the name happens to collide with something you've declared in Metals, wouldn't jquery break? OK so what I think you mean is if one of our classes imports something and the names collide... That's not an issue for us, we enforce namespacing of our resources and so you can't have two resources with the same identifier. i.e. we blow up if you have two components with the same src directory structure or IDs in the XML/HTML resources. Or do you mean what happens if we use a 3rd-party library and they import something like import {MyClass} from novox/grid/GridView; Highly unlikely as we stick to the reverse domain, Java-like namespace approach. So novox would be either our company name or one of our clients. Not many OSS libraries would call their packages after banks I'd say. Not sure you could fix that beyond changing the actual source code of the library I'd guess? B. On Tue, Apr 30, 2013 at 6:11 PM, Jason Orendorff jason.orendo...@gmail.com wrote: On Mon, Apr 29, 2013 at 4:50 PM, Brian Di Palma off...@gmail.com wrote: I was wondering how versioning was expected to work in this module system. [...] Now in each teams code base JQuery is imported like so: import $ from jquery; That's great as long as they are developing separately from each other. What I'm wondering is how their components are meant to be integrated into a single app. The simplest thing would be to make a jquery module in your component: module megabank/metals/jquery { import $ from jquery-1.9; export $; } // other modules under megabank/metals/ would write: import $ from ./jquery; That's the way that's built in the system, and that's what I would probably do. Loaders are customizable, so one alternative is to add versioning to the system loader: https://gist.github.com/jorendorff/5489886 With nested modules maybe you could bundle them like so module Metals { module jquery { //jquery 1.9. } } Do you imagine the whole Metals module being in a single file, including jquery? Or would lexical modules be open, like C++ namespaces and Ruby classes? Or would they be put together some other way? Having to paste jquery code into your project seems unfortunate. You'd rather use the files unchanged, right? Also, if jquery imports something, and the name happens to collide with something you've declared in Metals, wouldn't jquery break? (Well, OK, the real jQuery doesn't import anything and is extremely careful about which global names it uses. But one goal of a module system is not to have to be quite so paranoid.) Closing thought: All use cases are welcome! That said, using multiple versions of a library in a project is icky enough that an occasional project-wide search-and-replace at the margin isn't much worse. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: class-private syntax in ES6 (was: ES6, ES7, ES8 and beyond. A Proposed Roadmap.)
My apologies, I didn't mean it as a rebuke ( although looking at what I wrote I can understand the thought ). I was a bit unsure about floating back up another email like this when it seemed people maybe weren't interested in the topic. Obviously I did an awful job at conveying that feeling. Consider myself chastened! Interesting gists, especially the use of WeakMap. B. On Sun, Apr 28, 2013 at 9:23 PM, Rick Waldron waldron.r...@gmail.com wrote: On Sun, Apr 28, 2013 at 3:16 PM, Brendan Eich bren...@mozilla.com wrote: Brian Di Palma wrote: Another mail that I expected to receive more attention that hasn't... @Brian, This is the second time you've opened a thread reply with a rebuke regarding (lack of) speedy of response. Just saying... For some reason my mail program doesn't thread your reply to my o.p. Here it is in the archive, FWIW: https://mail.mozilla.org/pipermail/es-discuss/2013-April/029969.html We're London based so we had attendants at JQueryUK and the announcement of private class state in ES6 was a surprise, a pleasant one but still surprising. Is it the case that the announcement was jumping the gun? Rembmer, my words were that I threw up a sketch -- not a final masterpiece, not the Mona Lisa. However as your meeting notes excerpts show, we still don't quite have consensus on classes _per se_, without including private syntax in ES6. This is an agenda item for the upcoming TC39 meeting. We should try to build on the work by Mark and Tom at http://wiki.ecmascript.org/doku.php?id=strawman:relationships and make progress, whether that work ends up in ES6 or ES7 for prudential reasons. Needless to say for programming with large code bases it would be excellent to have private state. Agreed! The introduction of class in ES6 should not be blocked (or postponed until ES7) by a lack of class (specific) private declaration form. I understand and appreciate Brendan's remarks re: double-blind consensus, but politely disagree with the notion that we _must_ produce a specific syntactic form when private state can be achieved with the use of a WeakMap or a Symbol: https://gist.github.com/rwldrn/5478221 I've always been an @-name supporter and have had a pending revisitation agenda item for the last two meetings, deferred in favor of the bigger fish we had to fry ;) Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
class-private syntax in ES6 (was: ES6, ES7, ES8 and beyond. A Proposed Roadmap.)
Another mail that I expected to receive more attention that hasn't... We're London based so we had attendants at JQueryUK and the announcement of private class state in ES6 was a surprise, a pleasant one but still surprising. Is it the case that the announcement was jumping the gun? Needless to say for programming with large code bases it would be excellent to have private state. From the meeting notes thought it does not seem as if this has been agreed to. YK: So, what is your proposal? MM: My proposal is the private symbols get postponed to ES7 WeakMap gets renamed to reflect the inverted thinking If we adopt the @ syntax in ES6, I want to be able to use a WeakMap on the right side ...Don't care so much about the renaming, but feel that it could add clarity to the feature RW: (Disagree based on experience teaching the concept) WH: no consensus on class without private symbols MM: Rick, can you find the history of this? RW: (recounts two meetings where Waldemar was not present, but a general consensus existing with the understanding that Waldemar would still have something to say. At Northeasten, Allen presented @-names, in which Waldemar found to sufficiently meet his privacy requirement for classes) ...Discussion around class private state as a whole. BE: We need to synthesize what's going into ES6. Waldemar claims this must include some way of adding class private state. STH: I would like to stop this conversation and allow myself time to think about this. BE: Done. Conclusion/Resolution Sam, Mark and Allen to work on relationships and varied representation in ES6. The '@' syntax is not the nicest but it does highlight private state which is probably a good thing. I'd happily type IAMTHEWALRUS if it gave me private state. Well not happily; but I'd still type it. From the notes it does not seem clear if a lack of private is enough to scupper classes altogether. That would seem an extreme step to take, surely private state can be added in ES7? B. Brendan Eich wrote: Mark S. Miller wrote: | Completing the class design | | at least high integrity and private state If I'm not mistaken, we need class-private syntax for classes to have ultimate double-blind consensus in ES6. See last meeting notes. At JQueryUK, I threw up a sketch in slides based on http://wiki.ecmascript.org/doku.php?id=strawman:relationships: class SkinnedMesh extends THREE.Mesh{ private identityMatrix, bones, boneMatrices; constructor(geometry, materials) { super(geometry, materials); this@identityMatrix = new THREE.Matrix4(); this@bones = []; this@boneMatrices = []; ... } ... } The TypeScript (CoffeeScript had it already, and more concisely via @) option to declare and initialize via a private prefix on one of constructor's parameters would be helpful to many developers: class Point{ constructor(private x, private y) {} add(other) { return Point(this@x + other@x, this@y + other@y); } ... } I hope we can agree to do this much for ES6, based on the relationships work, which I'd like to thank Tom and you for championing. At first I thought it was not helpful, but then the lightbulb went off ;-). ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Module naming and declarations
I've been following es-discuss for a short amount of time. I'm a JS dev working on a significant code base, this biases how I perceive ES6 issues. From my viewpoint by far the most important advancements provided by ES6, eclipsing all others, are modules and classes. This feeling is widely shared among the developers I work with. So I'm somewhat surprised at the lack of response to Andreas email. Firstly I agree with Andreas point about there being an issue with the naming and declaring of modules. | In the original module proposal, modules were declared via ordinary | lexical identifiers, but could also be imported from external sources | denoted by strings. In November, the proposal was changed to use | string-valued module ids for both. The motivation was to simplify | the language, and to provide better support for configuration and | concatenation. This seems an odd change to make, a backward one in fact. I presume that the aim of modules is to provide clean scopes/environments, to prevent global state pollution and to aid in structuring/separating code. Therefore you would wish modules to provide an abstract identifier as opposed to a concrete file path string as its identifier. module topLevelNamespace.subNamespace { export MyClass { } } | Nobody would suggest to use file paths in place of variable | identifiers internally. Yet, that is almost exactly what the proposal | does for modules! Indeed. Working on a large code base containing hundreds of JS classes I think it's cleaner to deal with abstract identifiers which to correspond to namespaces as opposed to file locations on disk. | As various discussions show, people want and expect scope chain | behaviour, and for very good reasons: e.g. nesting modules, confining | modules to local scope, convenient local names, etc. Yes. If we create private packages in our frameworks/libraries I see no reason for any end consumer to have access to these internal artifacts. This is all about working with large code bases, privacy and integrity are very helpful in those situations. | (The path semantics is inherited from legacy module frameworks | for JS, such as AMD. It is a fine solution under the constraints that | these frameworks have to operate in -- in particular, the inability to | extend syntax or add new primitives. However, for ES6 most of these | constraints don't apply, and there is no particular reason to limit | the design to making the same compromises.) To produce such a design purely to serve the needs of old module systems seems a poor choice to me. Over time the standard mechanism will eclipse all other module systems even if it provides no upgrade path for the old systems purely because it is the standard system. As long as it is not a totally broken design. The only time I would be willing to invest learning about the old module systems would be when I want to convert an old module to the new system so I can dump the old system. There is far more code that is not using modules than code that is. The focus should be on creating the best possible module system not the best possible system that smoothly accommodates AMD modules! | A custom loader can, in principle, perform arbitrary interpretation or | rewriting of URLs. In particular, this could be used to implement | interop to absolute repository paths a la AMD or Node, e.g. by | interpreting an amd: schema for importing AMD modules that are | relative to a separately configured base URL. In other words, you'd | write | |import M1 from a/b; // native ES6 import, relative path |import M2 from amd:c/d; // import of AMD module, relative to AMD base URL Schema handlers for non standard resources seems like an excellent idea. Neat, clean and easy to identify. I would support that, it could also be used to load non JS resources. Thank you Andreas for highlighting these niggles I do hope there is more interest in them then the lack of response indicates. - Brian Di Palma. On Wed, Apr 24, 2013 at 1:28 PM, Andreas Rossberg rossb...@google.com wrote: The module proposal has made good progress, thanks to the hard work by Dave Sam. I'm glad to see it close to the home stretch for the ES6 race (some healthy minor controversies on the side notwithstanding :) ). However, there is one central part of the design over which we still do not have agreement: the naming and declaration mechanism for modules. We did not yet have a serious discussion about it -- and I fully admit this being my fault as well, since despite my repeated criticism, I hadn't found the time to put that in a coherent form. I try to make up for that with this post. :) Summary is that I still (strongly) believe that adopting what's currently on the table would be a severe mistake, and that it's best to take a step back and discuss the motivation as well as alternatives. My sincere apologies for the excessively long post... ** The problem ** In the original
Re: Module naming and declarations
Sam, I hope that will be the case, that's why I mentioned that I've only been following es-discuss for a short amount of time. I wasn't sure about the speed of response to such a substantial argument. I waited a day to see if anyone was interested or if it generated a discussion. I agree that interoperability with older module systems is desirable and that it should not come at the cost of a better standard ES6 module system. B. On Thu, Apr 25, 2013 at 2:46 PM, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote: On Apr 25, 2013 4:00 AM, Brian Di Palma off...@gmail.com wrote: I've been following es-discuss for a short amount of time. I'm a JS dev working on a significant code base, this biases how I perceive ES6 issues. From my viewpoint by far the most important advancements provided by ES6, eclipsing all others, are modules and classes. This feeling is widely shared among the developers I work with. So I'm somewhat surprised at the lack of response to Andreas email. On this point, Andreas wrote a long email, which I'm sure he spent time on. A response deserves similar consideration. I'm sure you'll see some soon. Sam ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss