8.15.0.5

1.9 Namespaces🔗ℹ

A dotted module import as convert.fahrenheit_to_celsius or class field accessors as Posn.x and Posn.y demonstrate the use of hierarchical names. Other hierarchical names provided by rhombus include List.length and List.cons via List (where lists will discussed more in Lists):

> List.length(["a", "b", "c"])

3

Use the namespace form to create a namespace without creating a separate module. The identifier after namespace is bound as a namespace, and export provide forms within the namespace body determine the bindings that can be accessed from the name with the . operator.

namespace geometry:

  export:

    tau

    Complex

  def pi = 3.14

  def tau = 2 * pi

  class Complex(real, imag)

> geometry.tau

6.28

> geometry.pi

pi: identifier not provided by geometry

> geometry.Complex(0, geometry.tau)

geometry.Complex(0, 6.28)

A name defined with namespace can be used with import, but the name must be prefixed with . to distinguish it from a module path. Also, import can be used in nested blocks generally, such as a block created with block or def:

> block:

    import:

      .geometry open

    Complex(0, tau)

geometry.Complex(0, 6.28)

def also_pi:

  import:

    .geometry open

  tau/2

> also_pi

3.14

Naturally, namespaces can be nested further, either by exporting an existing namespace or by nesting namespace forms.

namespace subject:

  export:

    geometry

    english

  namespace english:

    export:

      greeting

    def greeting = "Hello"

> subject.english.greeting

"Hello"

> subject.geometry.tau

6.28

> block:

    import:

      .subject open

    geometry.tau

6.28

A . can be used in an import form as a shorthand to reach a nested binding without making intermediate bindings visible.

> block:

    import:

      .List open

    length(["a", "b", "c"])

3

An existing namespace can be extended by using a dotted name in a definition, such as defining geometry.e in a context where geometry is a namespace. The extension does not mutate the namespace; it merely extends the bindings that are available in the scope of the extending definition.

> block:

    def geometry.e = 2.71

    geometry.e

2.71

> geometry.e

e: identifier not provided by geometry

When a namespace is exported, any extensions of the namespace visible at the export site are also exported. Multiple extensions of a namespace can be imported into a context as long as the extensions do not conflict, which is partly a result of the rule that the same name can be imported into a context multiple times as long as the binding is always the same.