Skip to content

Latest commit

 

History

History
80 lines (48 loc) · 3.52 KB

modules.adoc

File metadata and controls

80 lines (48 loc) · 3.52 KB

Modules

A module is the compilation unit for Frege. It constitutes a name space for the enclosed definitions. Compiled modules can be imported from other modules to access the exported types, type classes and functions.

Note
Currently, all items not declared private can be accessed from other modules.

When module foo.A imports module bar.B we say that foo.A depends on bar.B and on all modules that bar.B depends on. A module must not depend on itself.

A source file defines exactly one module.

Module Names

A module name consists of a number of identifiers separated with dots. The last or only component must start with an uppercase letter.

Compilation of a module results in a Java class whose fully qualified name matches the module name.

Given
module org.desperate.programmers.Foo where { ... }

will result in the following Java code:

package org.desperate.programmers;
public class Foo { ... }

It is customary to use lowercase identifiers for the package part, that is, only the last component of a Frege module name should start with an uppercase letter.

Note
Because of the way the JVM works, it is only possible to reference classes in the unnamed package from classes that are also in the unnamed package. It is therefore not recommended to use simple module names for library modules.

Magic Module Names

If the first component of a module name starts with an uppercase letter, that letter gets replaced with it’s lowercase associate and the extra component frege is prepended to the module name.

Example
import Data.List
Translation
import frege.data.List

Prelude

The module name Prelude is an abbreviation for frege.Prelude.

Module Definition

  module ::= DOCUMENTATION* moduleheader?  '{' definitions+ '}'
  moduleheader ::= 'module' modulename 'where'

When the module header is missing, the compiler inserts

module Main where

When the module header is missing and the first token that follows the optional documentation comments is not an opening brace, the lexical analyzer will assume layout mode starting at column one.

Integration with other JVM Languages

It is sometimes desirable that compilation of a Frege module produces a class that extends another JVM class, or implements some interfaces. Usually, this requires also glue java code.

To achieve this, there is the native module directive, that can occur as top level definition. There must be at most one such directive per module.

Syntax
module-directive ::= 'native' 'module'
       ('type' typeApp)?
       ('interface' typeApp (',' typeApp)*)?
       'where' '{' java code '}'

The type after the type keyword must denote a native type. The compiler will create a class that claims to extends this type. (Hence this native type must actually be a Java class.)

The types after the interface keyword must all denote native types. The compiler will create a class that claims to implement those interfaces.

Necessary glue code can be written in curly braces after the where keyword. The curly braces should be given explicitly, to avoid insertion of semicolons.

The java code is parsed as a sequence of tokens that are simply replicated in code generation. Because of this, avoid the Java -- operator, as this would be interpreted as the start of a line comment.

Observe that the types to extend or implement are given as Frege types! This means, appropriate native definitions must be in scope.