###### tags: `S-Juvix` # On a Modular Image System: Or How I got multiple conflicting packages to live under the same image. Rough thoughts. We have two concepts: 1. Module 2. Package Modules are modules we all know and love. Namely it acts like the UNIX filesystem. Packages describe your project state, what projects we import etc. All code exists inside both a Module and a Package. Thus in our Project `Juvix`, we may be in a module `Core`. We can on the fly swap what module we are in. `(in-module :Core.Theory)` This means we are in the Project `Juvix` still and now the module is `Core.Theory`. Projects can import other Projects, thus we can import an `Array` package. This `Array` package defines out the module `Prelude.Array`, which lives in the `Base`'s `Prelude` module. By importing the `Array` package we've added to the standard library of our project. If there exists another package that defines out the module `Prelude.Array` we would get a conflict and be told to rename either one (thus we can rename the new one to `Prelude.SpecialArray`, or any other recovery schema). Little did we know, `Prelude.Array` used some packages that defined out `Core.Theory`. This is quite unfortunate as our codebase has `Core.Theory`. With the concept of packages, this is no problem, as we do not bring into our resolution scope the `Array` package's package. Thus there is no conflict in `Core.Theory`. Only the modules defined in the `Array` package will be brought into scope with the default import function. ## Implementation issues One big issue with mixing package names is that we can't simply link the same version of a library together. If two packages rely on `Base.1.1.1.1`, and one package extends it with `Array` and another does not, a naive resolution system may have to allocate links back to the original, as one `Prelude` from base has `Prelude.Array` but the other does not. However if we utalize functional programming, we can keep the base `Prelude` around in `Package.Base`, and when we import it into scope it'll just functionally copy the tree over. When another package hits it, it'll just do tree merging. This has some issues I need to flesh out 1. Updating the standard library - We should be pinned to a version with a hash 2. Updating a library while in a package - It should know what package we are in, and then update our pinned package to it 3. When do we generate out Hashes to refer to packages Some Notes: - We mutate the image when we change a defn. A lot more thought should be had on this, and how much functional sharing loses us, but this technique should work.