
Nix is an example of a language with first class imports, `import` is a plain function the returns the "module" which is just a record like any other. Based on my experience, it's not all that great. Of course it could be because the nix language itself is weak, with dynamic typing and no user defined data types. But the main effect is that it's hard to tell who imports what or where some value comes from, because import may syntactically occur in any expression, and then the module may be passed around arbitrarily far before being used. As opposed to haskell where you just look at the top of the file and a single step takes you to the definition. An advantage is that of course a "module" can just be a function which returns a module, which is similar to how I imagine ML functors being, except all in the value language. It's used to conveniently inject a bunch of variables into scope. Since there are no user-defined data types though, none of the traditional "define a hash map with built-in hash function" type stuff. I've (very) occasionally wanted a parameterized module in haskell, the closest analog is just a normal record, and you can then use RecordWildCards like a local import. It would be nice for DSLs if records and modules could be unified that way, so you could have both local imports and parameterized modules. I haven't really come up with a use for it outside of one particular DSL though. I gather there's a deep history for this in ML though, and I recall some dependently typed languages like Agda or Idris had unified modules and records to a greater degree than haskell. For GHC API, I have a program that uses it to implement a REPL which is then the main text-oriented UI. I originally wanted to use dynamic loading to be able to write and insert code at runtime, but never got that going. Instead it's reasonably fast to rebuild and relink and reload the program, which seems like a less finicky way to go about it, and I settle for the REPL which compiles fragments to modify the state, but are not themselves persistent unless I paste them into a module somewhere.