>>>> 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