Idioms

Reasons for various idioms in the codebase

The document to see the rational for any of our idioms

Qualified Imports

Throughout the codebase every import except the standard library is imported qualified. This allows us the flexibility of having common naming patterns between modules.

Some of the more obvious ones are

  • T

  • op

  • of<Type>

  • to<Type>

  • etc.

Further we often import our modules with long names, like Namesymbol for Juvix.Library.NameSymbol.

Consider the following example if we have short qualification names.

  import qualified Juvix.Library.NameSymbol as N


  ... 100+ lines of logic ...


  foo :: N.T -> Symbol -> Symbol
  foo ns symb = N.toSymbol <> symb


  ... more lines of logic ...

In complicated logic where we have over a dozen imports, it's quite taxing to see N.toSymbol, as what is this N? However it becomes very clear if we saw NameSymbol.toSymbol

  import qualified Juvix.Library.NameSymbol as NameSymbol


  ... 100+ lines of logic ...


  foo :: NameSymbol.T -> Symbol -> Symbol
  foo ns symb = NameSymbol.toSymbol <> symb


  ... more lines of logic ...

Further it makes our standard idioms of to<Type> (toSymbol) become a bit harder to reason about, what is going to Symbol in this instance? We'd be forced to have names like N.NameSymboltoSymbol, essentially removing any standardization of module's and ensuring that we import everything unqualified.

Module.T

Most modules contain a type T within them. For example we have NameSymbol.T. The T represents the quintessential type of the module. The decision is a consequence of having long qualified names for each module imported.

Consider the following scenario where we did not make this choice, and instead had the full name.

  import qualified Juvix.Library.NameSymbol as Namesymbol


  ... 100+ lines of logic ...


  foo :: NameSymbol.NameSymbol -> Symbol -> Symbol
  foo ns symb = NameSymbol.toSymbol <> symb


  ... more lines of logic ...

Here we are quite tempted to import the module as unqualified for this one type, as it's obvious what we mean! Further, it might encourage short import names like N which we discuss in the previous section.

The name T over Ty or any other variant comes from OCaml where they name all their types T. This in OCaml has practical benefits for their module functors which expect the module to have some principled type T to be generic over. This has the side effect that principled functions and types are named consistently throughout modules, which helps us get more of an intuition about the code without having to ask what is the point of any particular module.

Capability

Capability is our replacement for MTL in the codebase. See the article linked below for a detailed explanation of the benefits over MTL.

More can be read in our sub article below


Capability

Further expanding upon why we chose capability