Appendix A: Import Syntax

You've already seen some import syntax, but now you'll see all the options available.

If you recall Chapter 1, there was this example code:

(;module:
  lux
  (lux (codata io)
       [cli #+ program:]))

Here, we can see flat imports, nested imports and more specialized import syntax.

Flat is simple: you just mention the name of a module and all of its exported definitions will be locally imported in your module.

This may cause some issues if you import 2 definitions with the same name from different modules, or if you get a definition from one module, but then write your own definition with the same name in your code.

In those circumstances, the compiler will complain, saying that you can't re-define X; where X is the name of the definition.

It might be harder to figure out what you're re-defining, so you might want to avoid flat imports outside of the lux module to avoid potential clashes; or get acquainted with the Lux documentation to know what is defined where.

Also, nested imports can be done in more than one way.

We've already seen (lux (codata io)), but that can also be done like (lux codata/io), or like (lux/codata io), or even like lux/codata/io.

In all cases, you would get a flat import.

Oh, and you can also use these variations when dealing with the specialized imports.

And speaking of those, lets see what other options they give us.

(lux [cli #+ program:])

This ones gives lux/cli the shorter cli alias, plus it locally imports the program: macro.

Everything else inside that module would remain hidden.

(lux [cli #- program:])

That one would do the opposite.

Everything inside lux/cli but program: would be locally imported.

(lux [cli #*])

This third alternative would locally import everything (just like a flat import), while also giving lux/cli the shorter cli alias.

Oh, and for #+ and #- you can give it more than one parameter. For example:

(lux [cli #+ program: run Monad<CLI>])

Now that we've mentioned a monad, I should also point out that you can open structures inside your imported modules right there on the import syntax, and you can even use different prefixes for different structures.

(lux [cli #+ program: run "CLI/" Monad<CLI> "" Functor<CLI>])

Here, I'm opening 2 structures (with different prefixes).

This import will give me access to the CLI/wrap and map functions, coming from the CLI/Monad and the CLI/Functor respectively.

And, just like for #+ and #-, you can provide multiple parameters after the prefix texts.

You may be wondering if you can combine #+ and #- the same way as the prefixes, but you can only pick one of #+, #- or #*, and (if present) they must always show-up before the opening prefixes.


You can also have custom aliases with the specialized syntax by giving a text format before the name of the module.

(lux ["my-cli" cli])

In this example, the alias will be my-cli, so my-cli;program: will access the program: macro.

Alternatively:

(lux ["my-;" cli])

By using the semicolon, I can refer to the name of the module, thereby accomplishing the same goal.


Finally, I would like to point out that absolute addressing of module paths isn't the only option.

Lux also supports relative addressing by using . or .. at the start of a module path.

For example, if you have the following directory structure:

  • foo
    • bar
    • baz
      • quux

Where each name may refer to a .lux file and (potentially) to a directory housing other .lux files; if you're located in the baz module, you could have the following import statement:

(;import lux
         (.. [bar])
         (. [quux]))

Thereby accessing both your sibling module, and your child module.

The quux module could also have the following import statement:

(;import lux
         ["dad" ..])

So, as you can see, relative paths are well supported within Lux import syntax.

However, you must remember that you may only use the relative path syntax at the beginning of a module path, and at no point afterwards.


There is an older syntax for specialized imports that is still available, but I won't explain it here since it does pretty much the same as this new syntax, but with higher verbosity.

You may encounter it if you read the source code of the standard library some day.

results matching ""

    No results matching ""