>>>> I agree wholeheartedly with these.  In fact, I'd go further on (2), and 
>>>> say "Anything that can be done declaratively can also be done 
>>>> imperatively, using ES5 syntax".

      >>Like most principles, I think these are reasonable to keep in mind but 
not absolute. In particular, I see no sensible way to claim that generators can 
be "done imperatively" in the old language.

My understanding of generators was naively that they are syntactic sugar for 
defining an iterator.  From that perspective, iterators are the interoperable 
runtime mechanism that needs to be available in ES5 syntax, and being just 
duck-typed objects with next(), this appears to be okay.

Re-reading the generators proposal, I was concerned at first that somehow the 
semantics of the syntactic desugaring might be taking dependencies on the 
internal properties of the generator objects when consumed in a generator, such 
as in a "yield* other".  However, it looks like even there, the semantics are 
in terms of the public API on the object, so that a user defined object that 
provides next/send/throw/close can correctly interoperate.

So I was wrong about iterators being the general interoperable runtime 
mechanism, but next/send/throw/close objects appear to be fully iterable and 
consumable in generators.   Is that right?  If so, it seems safe to consider 
generators as sugar for producing objects whose visible behavior could have 
been built independently.  And interoperation appears to work cleanly in both 
directions using these objects.



      >>>> I hope, and believe, there are actually not very many new runtime 
capabilities being added in ES.next that don't already have proposed libraries. 
 I do think there will need to be some rationalization of the goal to use 
built-in modules with the reality of ES5-syntax consumers of these libraries.  
I'm not sure whether module loaders currently provide a way to do this that 
would feel accessible.

      >> I agree, but I think this could be done with a minimum of global 
namespace pollution. For example, let's say we only make the Harmony 
SystemLoader available to legacy code. That would be enough for ES5 code to:
      - get access to new standard Harmony modules, such as "@name"
      - get access to a Harmony evaluator via SystemLoader.eval
      - get access to user-created Harmony modules
      And it wouldn't require overloading the Object constructor -- from here 
until eternity -- with a bunch of short-term backwards-compatibility cruft.

I generally like the idea of this.  It may indeed be able to provide convenient 
and object-detectable ES5 access to new library/runtime functionality.  
Reducing the global namespace pollution is certainly a good goal.  This would 
require that the syntax for loading these standard modules from ES5 is simple 
and can be implemented efficiently.  I haven't yet been able to intuit from the 
module_loaders page what is needed to accomplish each of the above though.  For 
example, if it is the case that loading the "@name" module required putting all 
my code in a callback passed to SystemLoader.load, that feels like it might be 
too heavy.  Do you have examples of what each of these would look like given 
the current proposal?


      >> But still, I agree with Allen that we should strive where possible to 
shoot for the goal of making dynamic/reflective analogs of static constructs. 
For example, Luke has mentioned that he'd like an ability to dynamically 
construct module instance objects. I think this is a good goal. But not so much 
for legacy code to have access to it, as for the ability for meta-level code to 
dynamically interact with base-level code. For example (using totally made-up 
API's, please don't bikeshed the names):
          childLoader = parentLoader.create(....);
          childLoader.registerModule("m", childLoader.buildModule({
              x: 42,
              f: function() { ... }
          });

Great - agreed that this is a really valuable addition to module_loaders.  A 
few questions on the example: (1) why is a child loader needed? (2) any 
particular reason why the buildModule and registerModule are separated?  (3) 
Would this allow declaring module dependencies for the new module?  As one 
comparison, the require.js module definition syntax is simpler in terms of 
APIs, but also requires an extra closure due to module dependencies, which may 
also be needed in the model above:

    define("m", [], function() {
        return {
            x: 42,
            f: function() { ...  }
        }
    });

ASIDE: It still feels a bit odd to see ES5 syntax running on ES.next runtime 
referred to as 'legacy'.  For one thing, it doesn't even exist yet!  But there 
will be an enormous userbase in this situation beginning in a few years, and 
probably for many years to come.  Opting into ES6 syntax requires opting into 
at least strict mode breaking changes and a new script tag.  In contrast, every 
piece of existing JavaScript code on the web will have the opportunity to 
object-detect and leverage targeted new runtime functionality.  Module_loaders 
in particular seems to have a ton to offer to ES5 syntax, by providing a 
standard means for module definition and consumption for existing JavaScript 
code, which can be shimmed out to a slower JS implementation where not 
available.

Luke



_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to