Lexical structure


A Timber program may contain two kinds of comments:


A Timber program consists mainly of definitions that give meaning to names. There are six separate namespaces in Timber:

Names are simple or qualified; the latter are used to disambiguate names defined in different modules.

Simple names

Simple names come in two lexically distinct forms, identifiers and operators.

An identifier consists of a letter followed by zero or more letters, digits, single quotes and underscores. The initial letter must be upper case for constructors, type constructors and module names, and must be lower case for variables, selectors and type variables. The following lexically correct identifiers are keywords of the language and may not be used as names:

action    after     before    case      class
data      do        default   else      elsif
forall    if        import    in        instance  
let       module    new       of        private
request   result    struct    then      type      
typeclass use       where       

An operator is a sequence of one or more symbol characters. The symbol characters are defined by enumeration: :!#$%&*+\<=>?@\^|-~. An operator starting with : is a constructor; otherwise it is a variable. Only variables and constructors have operator forms; the other four namespaces contain only identifiers. The following lexically correct operators are keywords and may not be used as names:

.    ..   ::   :=   =    \    \\   |    <-   ->   --

An identifier may be used as an operator by enclosing it in backquotes; `elem` is an operator. Conversely, an operator may be used as an identifier by enclosing it in parentheses; (+) is an identifier.

Names Possible namespaces
Color, T3, T_3, T_3' constructors, type constructors, module names
x, env, myTable, a', x_1variables, selectors, type variables
+, #=#, @@variables
:, :++:constructors
#3ILLEGAL; mixture of operator and identifier symbols.

Precedence and associativity

The precedence and associativity of operators are determined by their syntax. The operators in the following table are listed in decreasing precedence, i.e. an operator that appears in a later row binds less tightly. Function application, denoted by juxtaposition, binds tighter than all operators.
Operators Associativity
* / `div` `mod`Left
+ -Left
: ++Right
== /= < > <= >=None
>> >>=Left
For an operator that is not listed in the above table, the precedence is determined by first deleting all characters except +-*/<>. If what remains is

The operators in the table above are defined in the Prelude, but can be redefined in user modules, except for the following three exceptions:

Qualified names

Timber modules are used to manage namespaces. In this mechanism, simple names are extended to qualified forms, where the simple name is prefixed by the name of the module where it is defined. To allow several modules with the same name in a system, module names themselves may be qualified.

A qualified module name is a sequence of simple module names interspersed with periods, such as Data.Functional.List. The module name (given in the module header) is here just List, but the full name must be used by importing clients and is also used by the Timber installation to store and retrieve modules in the file system. Exactly how this is done is installation-dependent.

Imagine a module Dictionary, which defines among others the names insert and |->. An importing module may refer to these names using the qualified forms Dictionary.insert and Dictionary.|-> in order to avoid possible name conflicts. See the modules page for more information on import and use of other modules.The simple name that is the suffix of a qualified name decides if the name is an operator or an identifier and if it is a constructor or not.

A qualified name may not be used at a defining occurrence, only when a name is used. (The module prefix is uniquely determined by the module name, hence superfluous in the definition.)