basilisp icon indicating copy to clipboard operation
basilisp copied to clipboard

Basilisp's require always requires all parent namespaces

Open chrisrink10 opened this issue 6 months ago • 0 comments

Basilisp's require mechanism is built on top of Python's importlib. Specifically, calling (require 'some-ns.child) delegates the importing logic to importlib.import_module("some_ns.child") which ultimately makes uses the Basilisp finder/loader to find and load files. This allows us to use a lot of existing Python machinery for caching and loading and also allows Python files to easily import Basilisp code so long as the Basilisp library is available in their environment.

However, because of how Python's packages and modules work, importlib.import_module always attempts to import parent namespaces (modules) before loading the requested namespace because in Python the children of a namespace are set as attributes on the parent so the parent must be loaded. On the other hand, Clojure namespaces are purely organizational and there is no defined hierarchical relationship between "parent" and "child" namespaces. In Clojure, requiring some-ns.child will not force some-ns to be loaded first.

The specific solution for how we handle this is not clear to me because importlib does not actually allow loaders or finders to override this portion of the import logic.

The most obvious potential solution is lazily loading modules. The builtin lazy loading mechanism assumes it's dealing with a standard Python module, so we would likely need to create a custom lazy loader for Basilisp.

Further discussion in #957

chrisrink10 avatar Aug 16 '24 19:08 chrisrink10