Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable writing code directly to be evaluated synchronously #402

Open
ByteEater-pl opened this issue Apr 13, 2024 · 9 comments
Open

Enable writing code directly to be evaluated synchronously #402

ByteEater-pl opened this issue Apr 13, 2024 · 9 comments

Comments

@ByteEater-pl
Copy link

ShadowRealm.prototype.evaluate as currently specified takes a string. This is sub-optimal.

If the ECMAScript code to be evaluated is contained in a string literal (likely to be much more common than any other case), occurrences of its delimiters (", ' or backtick) in it need escaping.

Editors and other tools are unable to detect in all cases that a string literal is intended to be passed to ShadowRealm.prototype.evaluate and provide proper support (for editors it would be syntax highlighting, completion suggestions, etc.).

It'd be therefore desirable to have a better syntactic alternative.

Module expressions come to mind, giving:

myRealm.evaluate(module {
	// some code
})

But modules are evaluated asynchronously. It'd probably be too confusing to carve out an exception for ShadowRealm.prototype.evaluate.

If only source code could be extracted from a module object! Not necessarily all of them. And possibly at some phase, not yet present in ECMA-262, or without sufficient API yet. A phase that module expressions feed into. If undesirable for normal modules, perhaps a subclass could be created for module expressions which provides a property or method wrapping what's inside the brackets as string.

@ByteEater-pl
Copy link
Author

ByteEater-pl commented Apr 13, 2024

A possibility (new idiom?):

myRealm.evaluate((() => {
	// some code
}).toString().slice(7, -1))

Much better than a string, although tools would still confuse scopes and e.g. consider identifiers in some code to refer to outer variables.

@ljharb
Copy link
Member

ljharb commented Apr 13, 2024

That won’t work, because the function could close over objects from the outer realm, including the global. A string, or a host-specific specifier like in Workers, is the only option.

@mhofman
Copy link
Member

mhofman commented Apr 13, 2024

I wouldn't say never on module loading being async. Technically a module expression would have its module graph already resolved, so we could imagine in the future a way to synchronously evaluate them in another realm. This is definitely for future proposals to figure out.

@ByteEater-pl
Copy link
Author

@ljharb, what do you mean that won't work? Yes, the function closes over whatever's referenced from outer scopes, but toString doesn't care, it only gets the expression used to define the function as string. The variable names are then interpreted in a different way inside the ShadowRealm.

@ByteEater-pl
Copy link
Author

Shorter alternative:

myRealm.evaluate(`(${() => {
	// some code
}})()`)

It nests the anonymous function scope, but in many cases that's probably OK. Additionally, it works just as well when // some code is just an expression and the brackets are omitted, whereas the former would require a change to e.g. slice(6).

@ljharb
Copy link
Member

ljharb commented Apr 13, 2024

@ByteEater-pl i'm confused, if it's converting the function to a string and evaling it, how is that any better than just accepting a string directly?

@ByteEater-pl
Copy link
Author

@ljharb, from my initial comment:

If the ECMAScript code to be evaluated is contained in a string literal (likely to be much more common than any other case), occurrences of its delimiters (", ' or backtick) in it need escaping.

Editors and other tools are unable to detect in all cases that a string literal is intended to be passed to ShadowRealm.prototype.evaluate and provide proper support (for editors it would be syntax highlighting, completion suggestions, etc.).

@ljharb
Copy link
Member

ljharb commented Apr 13, 2024

ah. that seems like https://github.com/hax/proposal-raw-string-literals, which was unable to achieve stage 1 - meaning, the committee didn't seem to think that problem was worth solving.

@ByteEater-pl
Copy link
Author

ByteEater-pl commented Apr 13, 2024

There is overlap. But here it's just about ECMAScript code, treated as such. Actually, obviating the need for escaping is a nice bonus for me, however my main motivation is to have tools, especially editors, handle the code as code (with coloring etc.), not as string literal.

If "Raw string literals" is ever revived, though, it might be worth generalizing, so that a hint for tools can be provided, indicating the language, with a predefined hint (say es) for ECMAScript and the rest implementation-defined. To wit:

const
	someECMAScript = LanguageHint.es@``requestLeave(2) // I would like to request `2 leave days`.``,
	someXML = LanguageHint.xml@``<p>In ECMAScript, <code>`</code> can be used to delimit multi-line strings.</p>``
	

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants