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

Throw when doing import defer * of a module with no exports #34

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

nicolo-ribaudo
Copy link
Member

@nicolo-ribaudo nicolo-ribaudo commented Mar 28, 2024

@guybedford Is this fix better than #33?

Closes #19

@@ -840,6 +843,7 @@ contributors: Nicolò Ribaudo
1. <del>For each String _required_ of _module_.[[RequestedModules]], do</del>
1. <ins>For each ModuleRequest Record _required_ of _module_.[[RequestedModules]], do</ins>
1. Let _requiredModule_ be GetImportedModule(_module_, _required_<ins>.[[Specifier]]</ins>).
1. <ins>If _required_.[[Phase]] is ~defer~ and _requiredModule_.GetExportedNames() is empty, throw a new *SyntaxError*.</ins>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: other linking errors due to missing exports are also syntax errors.

Copy link
Collaborator

@guybedford guybedford Mar 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typically named exports syntax errors apply to both the consumer and producer of a module, since on either side it is a syntax error not to define the correct export name.

In the case of defer, these are different though - the consumer has the intent of deferring execution, so it is not a syntax error if they don't realise the module has no exports. But from the perspective of the producer of the module being deferred it could be interpreted as a syntax error that they did not define export names to be deferred.

I do think perhaps the consumer use case wins here, in that a syntax error would be quite confusing to debug as a consumer using defer, while an explicit type error could make it clear that the "type of the module objet does not support defer".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why would it not be a valid use case to defer import of a side-effecting zero-export module?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be a valid use case, but the converse argument is yours in #19 (comment).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rofl indeed so.

is there a way to initiate the evaluation that's not accessing something on the namespace object? (since toStringTag and __esModule would be things we DONT want to trigger it)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔

maybe Object.keys(deferred) and other forms of reflection could trigger it, via the MOP hooks?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not actually sure if this would work or not, perhaps the iteration is not execution triggering?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now evaluation only happens during [[Get]]. It's possible to add it to more MOPs, but it makes it more difficult to teach why passing a ns object to some functions triggers evaluation and to other it doesn't.

Object.keys right now triggers evaluation only of non-empty namespaces, because it only calls [[Get]] if there are any own properties.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Object.keys doesn't call [[Get]] at all, i think? Just Object.values/entries do - Object.keys calls [[OwnPropertyKeys]] and [[GetOwnProperty]]. I would expect all three of those to trigger evaluation.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that would make sense to me, and I agree we shouldn't extend the behaviours unexpectedly here.

After some further thought I must also admit I'm coming around to the idea of permitting empty namespaces instead of throwing. Because it's an edge case, allowing it to work may be better for users than not.

@guybedford
Copy link
Collaborator

Thanks for adding this, I have a weak preference for this form. Seems sensible to leave this one open to discussion?

@nicolo-ribaudo nicolo-ribaudo mentioned this pull request Apr 1, 2024
10 tasks
@ByteEater-pl
Copy link

I'm against. It hurts consistency. Edge cases, even when they're pointless and advisable not to write, should behave the same, as much as possible, as if there were no sharp edge. It simplifies semantics, tools relying on semantics, spec size and teaching. It also saves special cases in code generation scenarios.

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

Successfully merging this pull request may close these issues.

No named exports edge case
4 participants