You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, a module works by returning a value that will be that module's "module value":
local f:
42
{ :f @f }
This is for the most part an acceptable way of doing things. One problem is that it hinders circular imports from being handled gracefully, since the exported object isn't available until after the importing has finished.
There are several possible solutions to this. One of my favourite involves creating an extra scope for modules, that counts as a global scope when writing. That is, modules are no longer allowed to mess with the global scope. If a module attempts to set a global variable, it is exported instead. (An extra scope is inserted so that we still can use module locals.)
# m.deja
f:
42
# some other file
!import!m
!. m!f # prints 42
This way, we can change the compiler code like this:
diff --git a/vm/compiler.deja b/vm/compiler.deja
index e10a24c..0c7cbd3 100644
--- a/vm/compiler.deja+++ b/vm/compiler.deja@@ -802,18 +802,19 @@ local make-bytecode opcodes literals:
!compile-string src
!write dst
-!use mname:+!use mname env:
!find-module mname
if dup:
!compile swap over
else:
drop
- !run-file-in { :(name) mname }+ !run-file-in env
local :loaded {}
!import m:
if not has loaded m:
- set-to loaded m !use m+ set-to loaded m dup { :(name) m }+ !use m
m @loaded! m
tail-call @local
This changes the signature of !use but oh well.
Alternatives considered:
Before running a module, set its corresponding value in loaded to some special sentinel object. When entering !import, check for that sentinel. If an import cycle was found, raise an error. By far the simplest solution to implement, but it would prevent some valid ways to organize modules from being usable.
Using a module local dictionary called export. This is a bit more finicky and verbose.
Make !import do a tail-call on set instead of on local. That way, modules imported in sub-modules are automatically exported. However, this results in inconvenient syntax and would likely only violate the Law of Demeter anyway.
Use a proxy object as sentinel. This means code can keep looking like the first example, while supporting the functionality of the main proposal. A disadvantage would be the need to implement proxy objects for a very specific and narrow purpose. Also, backwards compatibility is not a concern for Déjà Vu right now.
Disadvantages of implementing this LIT:
Parts of the VM need to be rewritten to accommodate for the extra scope inserted, as well as providing a mechanism for locking the global scope.
Module values can no longer be anything other than dictionaries.
The text was updated successfully, but these errors were encountered:
Currently, a module works by returning a value that will be that module's "module value":
This is for the most part an acceptable way of doing things. One problem is that it hinders circular imports from being handled gracefully, since the exported object isn't available until after the importing has finished.
There are several possible solutions to this. One of my favourite involves creating an extra scope for modules, that counts as a global scope when writing. That is, modules are no longer allowed to mess with the global scope. If a module attempts to set a global variable, it is exported instead. (An extra scope is inserted so that we still can use module locals.)
This way, we can change the compiler code like this:
This changes the signature of
!use
but oh well.Alternatives considered:
loaded
to some special sentinel object. When entering!import
, check for that sentinel. If an import cycle was found, raise an error. By far the simplest solution to implement, but it would prevent some valid ways to organize modules from being usable.export
. This is a bit more finicky and verbose.!import
do a tail-call onset
instead of onlocal
. That way, modules imported in sub-modules are automatically exported. However, this results in inconvenient syntax and would likely only violate the Law of Demeter anyway.Disadvantages of implementing this LIT:
The text was updated successfully, but these errors were encountered: