Mar 31, 2023 | gga

VMs — Modules

There are a few guiding principles behind the design of Indu. Keep the language small with only a few constructs is one. Encourage building programs by assembling small pieces into larger is another.

The second of those principles requires that Indu support modules. It does that with the include from <uri> construct. The first requires that the implementation of these modules either re-uses or replaces an existing construct. This is a challenge to get right as there aren’t a lot of good examples of modules. Most languages just use simple textual replacement: from C’s #include to Ruby’s require. OCaml’s modules are well-regarded, however, as they are first-class and allow parameterisation.

How should Indu provide module-like constructs without the support of a type system as required by OCaml’s Functor approach, and with more structure than simple text pasting? The approach I have taken is to re-use mixins.

The top-level of every Indu source unit implicitly defines an unnamed object. When one source unit includes another source unit, the object defined by the second is mixed into the one defined by the first. There are two implications.

  1. As mixins already support parameters, include could be parameterised. This could parameterise the included module. That would give something a lot like OCaml’s Functors.

  2. This provides no support for name clashes. Any names included from one module will be overwritten by any identical names defined in the current module.

The first would require some new syntax to add parameters to an include:

include from /indu/blog with (title: "overwatering")

The second could be dealt with by convention: if every source unit defined a single object and put all constructs in there. But, that means if you ever want to include a module it’ll need to be one structured like that. And clashes will still occur. And it means that you wouldn’t be able to use an existing application as a module: it’d needed to be separated into an application source unit and a module source unit first.

And convention means another thing to learn, which means one more barrier to getting started.

The answer is to include some syntax to name the module that is being included. Construct an object with that name, as an attribute of the current top-level module, and mixin the included module there. The syntax is obvious.

include Blog from /indu/blog with (title: "overwatering")

These two enhancements (parameters for includes and named includes) are not yet implemented, so I’ve not been able to see how they have turned out. The only issue I can imagine is that API documentation is a little harder to write

This piece originally appeared on Giles Edwards-Alexander's personal blog, as VMs — Modules


Gain early access

Complete our brief survey to gain access to our beta launch and secure a discounted "Founder" price for life. Your feedback will help shape the future of Pandita and influence future product features.

Gain access