Static Module Resolution

# Kevin Smith (13 years ago)

Thanks Dave, for writing your blog post - it definitely cleared up some things for me (macros in particular). If there were no module systems already in place, I would definitely agree with static resolution. However, it seems to me that ES6 modules (in whatever form they take) are going to have to coexist and interoperate with pre-ES6 modules that export dynamically.

Consider this scenario in a server-side environment like Node:

// main.js
import g from "./legacy.js";

// legacy.js
exports.g = function() { return "hello world"; }

The exports of "legacy.js" are dynamic: there's no way to know that "g" is exported until we execute the script. In order to avoid a compile-time binding error in "main.js", we have to know that "g" is exported from "legacy.js". And in order to do that, we have to execute "legacy.js".

So we have a situation where "legacy.js" must be executed PRIOR TO INITIALIZING "main.js". This violates the order-of-execution semantics for both ES6 modules and for Node modules (and all "require"-based module systems, for that matter).

If this logic is correct (is it?), then I don't see how pure static module resolution is practical.

# John J Barton (13 years ago)

On Sat, Jun 30, 2012 at 11:24 AM, Kevin Smith <khs4473 at gmail.com> wrote:

Thanks Dave, for writing your blog post - it definitely cleared up some things for me (macros in particular). If there were no module systems already in place, I would definitely agree with static resolution. However, it seems to me that ES6 modules (in whatever form they take) are going to have to coexist and interoperate with pre-ES6 modules that export dynamically.

Consider this scenario in a server-side environment like Node:

// main.js
import g from "./legacy.js";

// legacy.js
exports.g = function() { return "hello world"; }

The exports of "legacy.js" are dynamic: there's no way to know that "g" is exported until we execute the script. In order to avoid a compile-time binding error in "main.js", we have to know that "g" is exported from "legacy.js". And in order to do that, we have to execute "legacy.js".

So we have a situation where "legacy.js" must be executed PRIOR TO INITIALIZING "main.js". This violates the order-of-execution semantics for both ES6 modules and for Node modules (and all "require"-based module systems, for that matter).

Just define the order of execution between ES6 and pre-ES6 to run legacy.js first.

The pre-ES systems mostly rely on running the 'outer' function as a meaning of 'declaring' exports. So when you load AMD modules the define() call runs and recursively loads dependents. Similarly require('legacy.js') has to run the line you wrote above so the exports.g is defined by the time we return.

Working out the mix and migration strategies is important.

If this logic is correct (is it?), then I don't see how pure static module resolution is practical.

One part of your logic is flawless: we can't have pure static module resolution if some of the modules are based on pre-ES dynamic logic. However, that does not say anything about ES modules.

jjb

# David Herman (13 years ago)

On Jun 30, 2012, at 11:46 AM, John J Barton wrote:

On Sat, Jun 30, 2012 at 11:24 AM, Kevin Smith <khs4473 at gmail.com> wrote: So we have a situation where "legacy.js" must be executed PRIOR TO INITIALIZING "main.js". This violates the order-of-execution semantics for both ES6 modules and for Node modules (and all "require"-based module systems, for that matter).

Just define the order of execution between ES6 and pre-ES6 to run legacy.js first.

Thanks John, you beat me to it -- basically, I agree the interop story isn't worked out enough (in part because when we started working on this there weren't as many dynamic modules around!).

I suspect it might need to be differentiated syntactically, though; I'm not sure there's any way to detect automatically that legacy.js is not an ES6 module but an old-style script. And I'm not sure you want to infer that anyway, if the semantics is going to be subtly different.

Working out the mix and migration strategies is important.

Agreed.

# Kevin Smith (13 years ago)

Just define the order of execution between ES6 and pre-ES6 to run legacy.js first.

You'd have to detect (before execution) whether a script was "ES6" or not, which is not practical, AFAICT.

But even if you could, then simply upgrading "legacy.js" to use ES6 modules would change the order of execution, which could cause observable differences of behavior in the program.

# John J Barton (13 years ago)

On Sat, Jun 30, 2012 at 12:03 PM, Kevin Smith <khs4473 at gmail.com> wrote:

Just define the order of execution between ES6 and pre-ES6 to run

legacy.js first.

You'd have to detect (before execution) whether a script was "ES6" or not, which is not practical, AFAICT.

As Dave suggests, my gut feeling is that we don't want // main.js import g from "./legacy.js"; to mean "legacy.js" can be ES6 or not. It's ES6 or it's an error.

However, let's consider your proposal anyway. Let's read main.js and parse it. // main.js import g from "./legacy.js"; Now we know we need legacy.js, so we fetch it and parse it. Does it form an ES6 module? Go with it. No? Ok fallback and execute it using compatibility rules. This could include looking for clues that tell us this is an AMD or node file. We know this mode is a hack, we only need it to be good enough to push modules over the hump.

But even if you could, then simply upgrading "legacy.js" to use ES6 modules would change the order of execution, which could cause observable differences of behavior in the program.

yes, modules change the order of execution. I doubt we can hope for "simply upgrading". However, I don't think it necessarily follows that interoperation is impossible and that is much more important.

jjb

# Andreas Rossberg (13 years ago)

On 30 June 2012 22:38, John J Barton <johnjbarton at johnjbarton.com> wrote:

As Dave suggests, my gut feeling is that we don't want // main.js import g from "./legacy.js"; to mean "legacy.js" can be ES6 or not. It's ES6 or it's an error.

However, let's consider your proposal anyway. Let's read main.js and parse it. // main.js import g from "./legacy.js"; Now we know we need legacy.js, so we fetch it and parse it. Does it form an ES6 module? Go with it. No? Ok fallback and execute it using compatibility rules. This could include looking for clues that tell us this is an AMD or node file. We know this mode is a hack, we only need it to be good enough to push modules over the hump.

Almost any old JS file (except for one containing 'with' I think) forms a legal ES6 module body -- it's just not going to export anything.

So as Dave said, you'd probably need an explicit import-side distinction to differentiate.

# Kevin Smith (13 years ago)

So as Dave said, you'd probably need an explicit import-side distinction to differentiate.

Like just using good-ol' require instead of import? : )

Ideally, the interop solution would make upgrading to ES6 module syntax transparent on the import side. But that's going to require dynamic modules (or perhaps some kind of static/dynamic hybrid).

It seems that we're in a situation where either interop or "static-ness" are going to suffer. Isaac, as a Node developer and architect, what is your take on this situation?

Note that the same trade-off exists on the browser-side. "Forward-compatible" modules on the client are going to necessitate dynamic modules as well. James, what is your take?

# Brendan Eich (13 years ago)

Kevin Smith wrote:

Like just using good-ol' require instead of import? : )

Not in the browser. Again, for like the umpteenth time, without a pre-processor, require is not equivalent to import. You have to put the continuation in a callback passed to require.

If your point is that given downrev browsers, web developers will use only one method, that's not clear:

  1. Use require taking a callback. This is not popular, as Isaac said, Node.js ran screaming from it to synchronous require because of its lack of usability.

  2. Use require with a pre-processor. But given a build-step of this complexity, see 3.

  3. Use an ES6 -> ES5 compiler. Some very big sites are already doing

this, I'm not sure whether I can name them all but they open source their tools. Google Traceur is just one example.

Coding for ES5 and ES6 by hand is costly, but there will be ES6-only environments (a future Node.js release, for one).

On the web browser content side, one could choose any of the above, but the only one that both gives early error checking and stands to become the next-generation standard is (3).

Ideally, the interop solution would make upgrading to ES6 module syntax transparent on the import side. But that's going to require dynamic modules (or perhaps some kind of static/dynamic hybrid).

We've been around this block for over two years. There is no such hybrid unless you add a special form such as import, or |require("...")| at top level, and that can't be done backward-compatibly using only functions (i.e., a library shim, AKA a polyfill). You'd need a preprocessor, in which case why not (3)?

It seems that we're in a situation where either interop or "static-ness" are going to suffer. Isaac, as a Node developer and architect, what is your take on this situation?

Interop of Node.js modules is good due to synchronous require. Interop across Node and browser is not so good, due to among other problems lack of sync. require on the browser side.

Therefore in any evolutionary path from here, interop is going to suffer on the browser side. (1) and (2) have enough usability problems that people still use ad-hoc concatenation and <script>-based techniques.

Note that the same trade-off exists on the browser-side. "Forward-compatible" modules on the client are going to necessitate dynamic modules as well. James, what is your take?

It's no use pretending we have some great module story on the web browser side, with which to preserve "interop". We don't have any such story.

All credit to James for working with the existing semantic tools in the language, but when there is a semantic gap, TC39's job is to consider filling it.

"Interop" in general needs some compilation step because of the differences among all of ES5, ES6, Node.js's sync. require vs. the browser's async.

"Interop" meaning no new semantics signified by new syntax is a false economy and something the Harmony agenda explicitly rejected. "No new syntax" was ES3.1's mantra and we left that behind in founding Harmony:

esdiscuss/2008-August/006837

# Brandon Benvie (13 years ago)

What is needed is more of an export adapter than watering down of import side syntax. In the Node world it is quite common to find files that server nothing more than the role of some kind of adapter, that simply includes a bunch of stuff and exports it directly with no modification except names. There's no reason the same concept doesn't hold for requiring stuff on the one end and exporting it using es6 modules out the other end. The form this takes in the browser is a slightly modificied "adapter version" of some existing file that adds a few lines at the beginning or end of the file that does the dirtywork.

# Kevin Smith (13 years ago)

Not in the browser. Again, for like the umpteenth time, without a pre-processor, require is not equivalent to import. You have to put the continuation in a callback passed to require.

I was just joking that if a legacy script needed to be distinguished on the import side, then we might just as well use Node's current "require" for the purpose. I wasn't trying to say anything about browsers in that statement.

It's no use pretending we have some great module story on the web browser

side, with which to preserve "interop". We don't have any such story.

Fair enough.

# Kevin Smith (13 years ago)

What is needed is more of an export adapter than watering down of import side syntax. In the Node world it is quite common to find files that server nothing more than the role of some kind of adapter, that simply includes a bunch of stuff and exports it directly with no modification except names. There's no reason the same concept doesn't hold for requiring stuff on the one end and exporting it using es6 modules out the other end.

Good - something like this, then?

// adapter.js
export var legacy1 = require("./legacy1"),
  legacy2 = require("./legacy2"),
  legacy3 = require("./legacy3");

// program.js
import { legacy1, legacy2, legacy3 } from "adapter.js";

Generally then, using this strategy we'd only be able to "import" directly from ES6 modules. For pre-ES6 modules, we'd have to use require.

Is that right?

# Brendan Eich (13 years ago)

Kevin Smith wrote:

Not in the browser. Again, for like the umpteenth time, without a
pre-processor, require is not equivalent to import. You have to
put the continuation in a callback passed to require.

I was just joking that if a legacy script needed to be distinguished on the import side, then we might just as well use Node's current "require" for the purpose. I wasn't trying to say anything about browsers in that statement.

Ok -- node.js and only node.js context was far from clear in your reply, or upstream in the thread.

It would be an unhappy thing to hear Nodesters say "I'm all right, Jack" meaning: synchronous require for us, and the devil take the browser. It was good to hear Isaac affirm that synchronous require was a compromise with Node's "never block" principle motivated by require() usability and the startup vs. non-startup runtime tradeoff.

For my part, I would never say that Node should move to ES6 modules on any definite schedule. Rather, my point is that whatever works for Node because of synchronous require does not carry over to the browser, and therefore Harmony designers have to look at both embeddings.

# Brandon Benvie (13 years ago)

That's the concept. I don't know about it being the only way, but it sure seems like a pretty simple way that preempts any of the other issues mentioned. Just requiring a bridge any time you shift from legacy module systems (and any inclusion changes that extend from there) to es6.

# Kevin Smith (13 years ago)

This solution is less ideal than being able to use import for legacy modules, but gets mad points for simplicity.

The next question is this: what will happen if "require" is used to load an ES6 module (specifically, a module that contains import statements)?

Dave, is it possible to create an effectively synchronous loader using the Loader API?

let syncLoader = new Loader(parent, {

  fetch: function(relURL, baseURL, request, resolved) {
    let src = fetchSourceFromDisk(resolved);
    request.fulfill(src); // Fulfill in same turn of the event loop
  }

}

syncLoader.load("abc");

// Is ABC ready at this point?
let ABC = syncLoader.get("abc");
# Brendan Eich (13 years ago)

Kevin Smith wrote:

This solution is less ideal than being able to use import for legacy modules, but gets mad points for simplicity.

The next question is this: what will happen if "require" is used to load an ES6 module (specifically, a module that contains import statements)?

Dave, is it possible to create an effectively synchronous loader using the Loader API?

let syncLoader = new Loader(parent, {

  fetch: function(relURL, baseURL, request, resolved) {
    let src = fetchSourceFromDisk(resolved);
    request.fulfill(src); // Fulfill in same turn of the event loop
  }

}

syncLoader.load("abc");

// Is ABC ready at this point?
let ABC = syncLoader.get("abc");

This came up at the March TC39 meeting. Oliver Hunt of Apple pointed out that we do not want a sync (as in block rendering) footgun from <script>

tags, a la sync XHR. See

esdiscuss/2012-March/021872

Quoting

DaveH proposal: Bifurcate grammar so that scripts (whether in<script>

tags or in files included from those) cannot contain static module load statements, not even in syntactically nested modules. Modules can include such statements but can only be parsed via dynamic loads. <script>

System.load("interp.js", function(m) {...}); </script>

interp.js contains: module stack = "stack.js"; export function evaluate(...) {...}

stack.js contains: export class Stack {...}

The body of an eval would be treated like a script body, not a module body. This avoids the tarpit of dealing with synchronous i/o in eval.

--- end quote ---

Again, sync loading is anathema in the browser. Any require usage must be (1) callback-based, or else (2) based on a preprocessor (if not full CPS-transforming compiler).

In case (1), let's say the underlying system (AMD) uses XHR and eval. The March meeting's resolution would throw an early error (early in the eval's phase structure, later in the script's phase structure) on any import syntax in the eval'ed program.

In case (2), the require dependency is loaded before runtime, one way or another. If the compiler generates ES6, no problem. If it generates ES5, also no problem (ES6 -> ES5 compilation entails compiling import into

something like what require compiles to).

# Kevin Smith (13 years ago)

Sorry, I keep forgetting to be explicit about limiting my (possibly abstruse) remarks to the node case.

I'm interested in figuring out whether it's possible for a legacy node module to "require" an ES6 module. If so, it would make it easier to gradually upgrade to ES6 modules.

In order for that to work, we'd need to create a custom ES6 loader that is "effectively" synchronous, as illustrated in that code example.

Another way to put the question: is it possible to create a loader that performs all phases of loading (resolving, fetching, compiling, importing, execution) before returning from "load()"?

# David Herman (13 years ago)

On Jul 2, 2012, at 7:19 AM, Kevin Smith wrote:

Dave, is it possible to create an effectively synchronous loader using the Loader API?

Yes, I would certainly want to allow this. I also figure there's nothing wrong with a host environment choosing to add additional synchronous API's to the System loader, like System.require().

IOW, the point isn't to disallow synchronous I/O from JS, but to make the standardized API asynchronous and admit the possibility of non-standard synchronous extensions.

# Aymeric Vitte (13 years ago)

Forgot to copy the list...

-------- Message original -------- Sujet: Re: Static Module Resolution Date : Tue, 03 Jul 2012 09:27:50 +0200 De : Aymeric Vitte <vitteaymeric at gmail.com>

Pour : Brendan Eich <brendan at mozilla.org>

Copie à : Kevin Smith <khs4473 at gmail.com>

Le 02/07/2012 20:09, Brendan Eich a écrit :

Again, sync loading is anathema in the browser. Any require usage must be (1) callback-based, or else (2) based on a preprocessor (if not full CPS-transforming compiler).

In case (1), let's say the underlying system (AMD) uses XHR and eval. The March meeting's resolution would throw an early error (early in the eval's phase structure, later in the script's phase structure) on any import syntax in the eval'ed program.

In case (2), the require dependency is loaded before runtime, one way or another. If the compiler generates ES6, no problem. If it generates ES5, also no problem (ES6 -> ES5 compilation entails compiling import into something like what require compiles to).

/be

All this is logical, today we have the situation of scripts (sync) loading scripts (async) which is not really nice to handle, the debate here was about compatibility between require and import, now what about normal scripts (ie non modules), why can't we have in the module proposal (or somewhere) just the possibility to load code and eval it (in browsers and server side environments) ? ie why should I be obliged to transform my script into a module and have to maintain both, or more if I want to insure perfect compatibility ? The question is trivial and not entirely related to modules or ES but since modules are considered, why not adding this possibility now ?

# Jason Orendorff (13 years ago)

On Tue, Jul 3, 2012 at 2:29 AM, Aymeric Vitte <vitteaymeric at gmail.com>wrote:

why can't we have in the module proposal (or somewhere) just the possibility to load code and eval it (in browsers and server side environments) ? ie why should I be obliged to transform my script into a module and have to maintain both, or more if I want to insure perfect compatibility ? The question is trivial and not entirely related to modules or ES but since modules are considered, why not adding this possibility now ? mail.mozilla.org/listinfo/es-discuss

Well, under the current proposal, you can say: System.load(url, function () {}, function () {});

This will basically just load the given url and run it, asynchronously. (The code is treated as a module, but IIUC the only difference that makes is that global variables and functions it defines won't pollute the global environment by default -- which seems like a good thing.)

# Aymeric Vitte (13 years ago)

This is not exactly what I would like to do, I would like to decide where I want to run it and when (whether it's sync or async), the global environment can be protected by strict mode now if you don't eval within it.

Basically I would like to have :

var code=download(url); //download("./my_server_secret_script.js") //download("http://www.public_script.com/well_known_public_script.js")

eval(code); //sync or asynch

The problem with the loader proposal is that you need a callback and it only extends the global scope, so the loader does not know the surrounding environment where it is called, example :

console.log(global);//global

var callback=function() { var window=some window; //not a global var System.load('script.js',function() {console.log(res)}; //script.js --> var res=window.document.body //crash }

Real example here: Ayms/node-gadgets/blob/master/lib/gadgets.js , section :

window=dom(page,null,options); document=window.document; document.onload=function() { var EWA = require('ewa').EWA; var ewa = new EWA(!!params.gadget,!!params.price,params.search?params.search:false,ew,params.nbmax?params.nbmax:100);

'ewa' was a normal script that was transformed into a module (even if on server side I could have loaded it and eval it (but with a callback), let's consider the same case where I need a public script into the browser), and 'window' and 'document' had to become "super" global vars to make it work

Using System.load I don't have to transform the script into a module but I still need to make 'window' and 'document' global vars, and I have now to use a callback

Then why not just a System.download(url) ?

Note : the above case is the exact real life representation of what I am trying to describe here : gist.github.com/2995641

Le 03/07/2012 21:06, Jason Orendorff a écrit :

# Sam Tobin-Hochstadt (13 years ago)

On Wed, Jul 4, 2012 at 6:12 AM, Aymeric Vitte <vitteaymeric at gmail.com> wrote:

This is not exactly what I would like to do, I would like to decide where I want to run it and when (whether it's sync or async), the global environment can be protected by strict mode now if you don't eval within it.

Basically I would like to have :

var code=download(url); //download("./my_server_secret_script.js")

//download("http://www.public_script.com/well_known_public_script.js")

eval(code); //sync or asynch

The problem with the loader proposal is that you need a callback and it only extends the global scope, so the loader does not know the surrounding environment where it is called, example :

console.log(global);//global

var callback=function() { var window=some window; //not a global var System.load('script.js',function() {console.log(res)}; //script.js --> var res=window.document.body //crash }

Real example here: Ayms/node-gadgets/blob/master/lib/gadgets.js , section :

  	window=dom(page,null,options);
  	document=window.document;
  		document.onload=function() {
  			var EWA = require('ewa').EWA;
  			var ewa = new

EWA(!!params.gadget,!!params.price,params.search?params.search:false,ew,params.nbmax?params.nbmax:< span class="mi">100);

'ewa' was a normal script that was transformed into a module (even if on server side I could have loaded it and eval it (but with a callback), let's consider the same case where I need a public script into the browser), and 'window' and 'document' had to become "super" global vars to make it work

Using System.load I don't have to transform the script into a module but I still need to make 'window' and 'document' global vars, and I have now to use a callback

Then why not just a System.download(url) ?

I'm slightly confused about what you want here.

If you just want the ability to download code, and then eval it using the loader mechanism, that's already there -- just use XHR to get the code, and then call System.eval(...).

If you want the ability to fetch the source the way that the loader would do it, and then not actually load the code, we could potentially add that, but it's tricky for recursive cases -- would you want all the relevant code, or just the specified module?

Or do you want something else than this?

Finally, I don't see why your example doesn't work exactly as:

document.onload(function() { System.load("ewa.js", ...); })
# Aymeric Vitte (13 years ago)

It's confusing maybe because what I am requesting is very very basic compared to modules/loader complexity and maybe I did mix it with an example not so basic.

I just want something that loads the code and then I decide what to do with it. Indeed on browser's side it would be like a cross-domain xhr, this does not exist but since modules will exist into browsers too, why not including this possibility ?

You are right, System.load("ewa.js", ...) would work, I did not say the contrary but to make it work I need to define 'window' and 'document' as global vars, I don't like it a lot if I care about separating contexts and then I have a problem if I want to have several 'window' and 'document', and I have to use a callback (I know everything is based on async but in some cases it's quite complicate to handle, then if things can be sync that's not a bad thing)

Simply, something like :

{ var window=window1; var code=System.download('ewa.js'); eval(code); //or whatever I like to do }

{ var window=window2; var code=System.download('ewa.js'); eval(code); //or whatever I like to do }

Le 04/07/2012 15:39, Sam Tobin-Hochstadt a écrit :

# Sam Tobin-Hochstadt (13 years ago)

On Wed, Jul 4, 2012 at 10:08 AM, Aymeric Vitte <vitteaymeric at gmail.com> wrote:

It's confusing maybe because what I am requesting is very very basic compared to modules/loader complexity and maybe I did mix it with an example not so basic.

I just want something that loads the code and then I decide what to do with it. Indeed on browser's side it would be like a cross-domain xhr, this does not exist but since modules will exist into browsers too, why not including this possibility ?

You are right, System.load("ewa.js", ...) would work, I did not say the contrary but to make it work I need to define 'window' and 'document' as global vars, I don't like it a lot if I care about separating contexts and then I have a problem if I want to have several 'window' and 'document', and I have to use a callback (I know everything is based on async but in some cases it's quite complicate to handle, then if things can be sync that's not a bad thing)

I don't understand your comment about window and document. They are already globals in browser JS environments.

As for async, there are a variety of ways to make it easier, but we are not going to add synchronous IO as part of the module system. The run-to-completion semantics of JS are non-negotiable.

# Aymeric Vitte (13 years ago)

I don't understand your comment about window and document. They are already globals in browser JS environments.

Please, take some time to read again my previous posts, I am refering to both server side's and browser's env, with 'window' and 'document' that are familiar as examples, but these could be 'mylocalvar1' and 'mylocalvar2' in both (and in my server side examples 'window' and 'document' are not supposed at all to be in fine globals)

As for async, there are a variety of ways to make it easier

No, the only way to ease your life is to define a lot of things as globals which some people like myself might not want to do, same as var script_=document.createElement('script') callbacks, modules are reproducing the same

I don't know if you develop everyday async code handling multiple asyncs stuff but it becomes all the time very quickly a nightmare

, but we are not going to add synchronous IO as part of the module system. The run-to-completion semantics of JS are non-negotiable.

Then the sync xhr is absurd ?

The "non-negotiable" word reminds me some famous vendor not implementing the sync xhr for obscure purposes (not blocking the app or something like this), I did not check since that time but I would bet they finally implemented it

It is really needed and looks so simple, do we have to live forever with the xhr limitations or can this simple thing be included ? (I understand it does not follow the global logic of modules/loaders but there might be a way)

# Brendan Eich (13 years ago)

Aymeric Vitte wrote:

Then the sync xhr is absurd ?

It's a botch that developers avoid, else they jank the user interface. We've been over this. Are you seriously defending it?

SyncXHR is anti-precedent.

# Aymeric Vitte (13 years ago)

Le 06/07/2012 03:17, Brendan Eich a écrit :

Aymeric Vitte wrote:

Then the sync xhr is absurd ?

It's a botch that developers avoid , else they jank the user interface.

Yes, as far as you can or as far as you want to avoid unnecessary complication, for example projet [1] is loading quite a lot of things using xhr and scripts (which are loading others), the priority was to load the user interface as fast as possible (offline feature, etc), then most of the loadings are async but the sync xhr could not be avoided (easy way sometimes but as far as I remember not using it could lead to situations that looked unresolvable)

We've been over this. Are you seriously defending it?

Do we have a survey of the use of sync against async ? I think it would show that sync is much more used (wrongly or easy way again, but...). The possibility to have a sync xhr remains usefull, but I see that I will be opposed strong arguments (could not find previous discussions about it).

If not possible, could we have at least a System.download(url,callback), as simple as just loading the url content and not caring about what is inside ? So we have an alternative to creating globals or linking to globals

[1] : www.blimpme.com/mobile

# Russell Leggett (13 years ago)

On Fri, Jul 6, 2012 at 7:30 AM, Aymeric Vitte <vitteaymeric at gmail.com>wrote:

Le 06/07/2012 03:17, Brendan Eich a écrit :

Aymeric Vitte wrote:

Then the sync xhr is absurd ?

It's a botch that developers avoid , else they jank the user interface.

Yes, as far as you can or as far as you want to avoid unnecessary complication, for example projet [1] is loading quite a lot of things using xhr and scripts (which are loading others), the priority was to load the user interface as fast as possible (offline feature, etc), then most of the loadings are async but the sync xhr could not be avoided (easy way sometimes but as far as I remember not using it could lead to situations that looked unresolvable)

We've been over this. Are you seriously defending it?

Do we have a survey of the use of sync against async ? I think it would show that sync is much more used (wrongly or easy way again, but...).

I completely disagree with this. Most developers without the knowledge/skill to know why sync is bad are just going to use a library like jQuery - which uses async. I'm not aware of any major library that uses sync as a default for their ajax api or uses sync in their own code.

# Aymeric Vitte (13 years ago)
Do we have a survey of the use of sync against async ? I think it
would show that sync is much more used (wrongly or easy way again,
but...).

I completely disagree with this. Most developers without the knowledge/skill to know why sync is bad are just going to use a library like jQuery - which uses async. I'm not aware of any major library that uses sync as a default for their ajax api or uses sync in their own code.

  • Russ

I am not refering to libraries but to developers/sites that indeed are using libraries and then feel (usually wrongly) necessary to extend it with unofficial/not good libraries or their own and then add some stuff around that usually is sync, as far as I saw debuging node-dom or looking at usual web sites

# Russell Leggett (13 years ago)

On Fri, Jul 6, 2012 at 10:58 AM, Aymeric Vitte <vitteaymeric at gmail.com>wrote:

Do we have a survey of the use of sync against async ? I think it would show that sync is much more used (wrongly or easy way again, but...).

I completely disagree with this. Most developers without the knowledge/skill to know why sync is bad are just going to use a library like jQuery - which uses async. I'm not aware of any major library that uses sync as a default for their ajax api or uses sync in their own code.

  • Russ

I am not refering to libraries but to developers/sites that indeed are using libraries and then feel (usually wrongly) necessary to extend it with unofficial/not good libraries or their own and then add some stuff around that usually is sync, as far as I saw debuging node-dom or looking at usual web sites

I'm not saying people don't do it, I was saying that the percentage is likely far smaller than you claim. Perhaps I'm deluding myself. Anyway, I don't think we should cater to something that is considered bad practice. As Brendan has said, lets lead the horses away from the rotting vegetables with better carrots.

# Aymeric Vitte (13 years ago)

OK, then are there objections to the async System.download(url,callback) ?

Le 06/07/2012 17:09, Russell Leggett a écrit :

# Sam Tobin-Hochstadt (13 years ago)

On Fri, Jul 6, 2012 at 12:51 PM, Aymeric Vitte <vitteaymeric at gmail.com> wrote:

OK, then are there objections to the async System.download(url,callback) ?

This is just a version of XHR, but with a different cross-origin policy? Or the same cross-origin policy? The latter seems useless, and the former unlikely.

# Aymeric Vitte (13 years ago)

Le 06/07/2012 18:52, Sam Tobin-Hochstadt a écrit :

On Fri, Jul 6, 2012 at 12:51 PM, Aymeric Vitte <vitteaymeric at gmail.com> wrote:

OK, then are there objections to the async System.download(url,callback) ? This is just a version of XHR, but with a different cross-origin policy?

Yes

and the former unlikely.

Why ? (Same origin policy ???) You said in a previous post :

"If you want the ability to fetch the source the way that the loader would do it, and then not actually load the code, we could potentially add that"