`module Intro: ``sig end`

For a more comprehensive documentation, a list of examples, and an
exposition of the MGS motivations and background, please visit the
URL `http://mgs.lami.univ-evry.fr`

. This chapter is only a survival
guide and does not cover the specificities of the MGS
language. Refer to the chapter `Collections`

and `Functional`

for a
presentation of the core concepts of MGS.

MGS is a untyped functionnal language that enables the case-based
definition of functions on *collections*. These functions are
called *transformation*. The language includes also imperatives
features like globale variables.

A collection is an aggregate of values structured by topological
relationships. See the chapter `Collections`

in this documentation
for more details about topological collections. See the chapter
`Functional`

for more details about the notion of transformations.

**The top-level read-eval-print loop:**
The MGS interpreter reads its input, parses the stream of characters
to recognize an expression, evaluates the expression and prints the
result. To force the end of an expression, one may use the
terminator

`;;`

(the double semi-column). In this manual pages, we
often omit the terminator and the examples of expression must be
completed by the `;;`

. In addition, when using the interpreter on a
standard unix terminal, the input are buffered (by unix) and a final
carriage-return must be entered to complete the input.
The top-level accepts expression and also *commands*. Commands
are order directed to the interpreter and are not part of the MGS
programming language. Commands always begin with a `!`

. Type the
command

`!help;;`

at the top level to have a list of the available commands.
**Identifier:**
identifiers come in *simple* or *quoted* form. A quoted
from is a string of characters that begins with a quote `'`

. Quoted
identifiers are predefined variables. The value of a quoted
identifier cannot be changed. A simple identifier is a string of
characters that does not begin with a quote. Simple identifier can
be used by the programmer as the name of a global variable, as the
name of a function parameter or as the name of a variable introduced
by a let.

The quote of a quoted name can often be omitted. Indeed, when a
simple identifier is encountered, the evaluation process looks first
if a value is attached to this identifier. If not, the evaluation
process looks if the corresponding quoted name is defined. So
expression `sin(0.77)`

is interpreted as `'sin(0.77)`

until the
variable `sin`

is defined. When this variable is defined, it is
still possible to access the sin function using the (full) quoted
name `'sin`

.

**Global and let variables and their imperative assignation:**
Some identifiers refer to an imperative variable. Such variables
are global to the program or visible only in a scope introduced by a
let construct.

The `:=`

operator is used to change the value of a global variable:

`a := 3`

links the variable identified by `a`

to the value `3`

until the next
affectation. The reference to a global variable that has not been
previously affected returns a special value called `<undef>`

. The
evaluation of the expression:
` an_identifier_not_previously_used;; `

returns `<undef: uninitialized var: an_identifier_not_previously_used >`

.
In contrary to the usual handling of let variables in
functional languages, the variables introduced by a let can be
assigned in MGS. For example:
`let x = 1 in x:=x+2`

is a valid expression that returns `3`

. The same let can be used to
introduce several local variables:
`let x = 1 and y = 2 in x+y`

The scoping rules are the standard ones: the variable `x`

introduced
by the let is not usable in the expression defining the value of `y`

and both `x`

and `y`

are unknown outside the `in`

clause.
**Functions:**
Function are first-class value that can be given as argument to
another function or returned as the value of a function application.
Functions are defined in a syntax similar to the
usual lambda-calculus. For example, `\x.x`

defines the identity
function. The application of a function to its argument needs
parenthesis:

`(\x.x)(3)`

denotes the application of the identity to the argument 3.
*All functions in MGS are curryfied*. However, there are some
shortcuts to make the notation more lighter: `\x.\y.x(y)`

can be simplified in

`\x,y.x(y)`

In the same spirit, the application of a function `f`

to two (or
more) arguments can be written
`f(1,2, ...)`

instead of the more heavier `f(2)(3)...`

. Beware that the
`1, 2, 3`

is an expression that builds a
sequence of 3 elements. In function application, the comma is
interpreted in favor of the application to multiple arguments. To
force the application of a function to a sequence build with the
comma operator, parenthesis can be used:
`f(1, 2, 3)`

denotes the application of function `f`

to three arguments while:
`g((1, 2, 3))`

denotes the application of the function `g`

to one argument which is
an expression that build a sequence, and
`h((1, 2, 3), 4)`

denotes the application of the function `h`

to two arguments (the
first is a list and the second is the integer `4`

).
To give a name to a function, we can use the *let* construct that
binds locally an identifier to a value, or the *assignment*
that changes the value linked to a global imperative variable. For
example

`let id = \x.x in (id(id))(3) `

returns `3`

because `id(id)`

is equivalent in the scope of the let,
to the expression `(\x.x)(\x.x)`

which evaluates to the identity
function. Outside the `in`

clause, the identifier `id`

is unknown.
The `:=`

operator can used to give a global name to a function:

`id := \x.x`

links the identity function to the identifier `id`

until the next
assignment. There is a short-cut used to define a function and
simultaneously to link it to a global identifier:
`fun id(x) = x`

is equivalent to
`id := \x.x`

The shortcut for the handling of multiple arguments is also
provided:
`fun f(x, y, z) = x + y*z`

A function defined with the `fun`

construct is called a `fun`

to define a function: such function can have optional arguments.
Predefined functions, i.e. functions that are "magically" defined
when one enters the MGS top-level, have all a quoted name that
cannot be redefined. For example, `fun 'f(x) = x`

, `'f := ...`

or
`let 'f = ...`

are incorrect expressions and are rejected (at the
parsing phase).

Some predefined functions have a special infix syntax, like the
operator `+`

: the syntax

`1+2`

is an alias for the expression
`'add(1, 2)`

There is another way to define functions:
*transformation*. Visit the `Functional`

chapter for a
description of transformations.

**Recursion:**
The name of a named function can be used in the definition of this
function. This allows the direct expression of the recursion. For
example:

`fun fact(x) = if x < 1 then 1 else x*fact(x-1) fi`

defines the standard factorial function.
**Variable capture and imperative feature:**
The partial application of the anonymous function `\x,y.x+y`

to the
argument `1`

returns a function that can be used to compute the
successor

`let succ = (\x,y.x+y)(1) in succ(2)`

returns `3`

. It is customary to say that the argument `x`

that refers
to the value `1`

is captured in the function `\y.x+y`

and the result
is a In contrary to the usual handling of let variable in functional languages, in MGS the variable introduced by a let can be assigned. In conjonction with the capture of variables, this features enables intersting behaviors. For example:

`f := let x = 1 in \z.x:=x+z`

is a valid expression. The global variable `f`

is linked to a
cloture that embeeds the let variable `x`

. Each time the
function `f`

is called, the store associated to `x`

is updated. So
`f(10)`

returns the value `11`

and a consecutive call `f(10)`

returns
`21`

.
**Optional arguments of a named function:**
not yet described

**Iteration of the function application:**
not yet described

**Tracing a function:** the call to a named function `f`

can be
traced using the command `!trace f`

or the expression `trace("f")`

(this function takes a string as argument. The command `!untrace f`

or
the function `untrace("f")`

can be used to cancel the trace of
`f`

. See the function the definition of the function `trace`

in the
`System`

chapter. Only named function can be traced, however this
includes predefined functions.

**Switch statement:** the keyword `switch`

can be used to avoid a
lot of nested `if ... then ... else ... fi`

constructions. The use
of `switch`

looks very similar as its equivalent construction in C:

`switch exp`

` case scl_1 : exp_1`

` ...`

` case scl_n : exp_n`

` default : exp_d`

`endswitch`

compares the evaluation of the expression `exp`

with each scalar
`scli`

in the order given the user, and returns the evaluation of
the associated expression `exp_i`

. If no `scl_i`

matches with `exp`

the `default`

expression `exp_d`

is evaluated and returned. The
`default`

case is optional ; the returned default value is

`<undef: macro: make_switch: switch default case>`

The expression `exp`

is evaluated only one time, at the beginning
of the evaluation of the `switch`

construction. In fact, a `switch`

is a syntactic sugar for:

`let new_id = exp in`

` if (new_id == scl_1) then exp_1`

` else if ...`

` else if (new_id == scl_n) then exp_n`

` else exp_d fi ... fi fi`

**Exception handling:** the structures `raise ...`

and ```
try ...
with ...
```

allows the use of exceptions in MGS. The syntax looks
like the Ocaml one.

To raise an exception, the keywords `raise`

has to be used as
following:

`raise `symbol`

The exception is identified by an MGS symbol (see the chapter
`Scalar`

for details), here ``symbol`

. A sequence of arguments can
be associated with these exceptions:

`raise (`symbol arg_1, arg_2, ...)`

where parentheses can be added around the arguments.

These exceptions can be caught using a `try ... with ...`

structure :

`try exp`

`with`

` | `symbol1 (arg1_1, ...) -> exp_1`

` | `symbol2 (arg2_1, ...) -> exp_2`

` ...`

where the first pipe is optional. If the expression `exp`

raises
an exception, the exception value is
matched against the list ``symbol1, `symbol2, ...`

. If the raised
exception corresponds to ``symbol_i`

, `exp_i`

is evaluated where the
free variables `arg_1, ...`

are replaced by the arguments of the
exception. Note the number of arguments has to matched for an
exception to be caught. For example :

`try`

` raise (`S 1,2,3)`

`with`

` | `S (x,y) -> x*y`

` | `S (x,y,z) -> x+y+z ;;`

returns `6`

.

**The rest of the online-documentation:**
the on-line documentation is divided in several chapters:

`Intro`

is this short introduction to MGS.`System`

describes the system-related functions: input/output, process spawning, etc.`Collections`

introduces the notions of collections in MGS. In this chapter, only the overall structure of the collections types is described, as well as generic functions that can handle any collection types. Each specific type of collection are described in a dedicated chapter.`Scalar`

covers the scalar types and the related functions. Scalar type corresponds to indecomposable values. Example of scalar type are integer, boolean or function.`Math`

lists the arithmetic operators and the mathematical constants and functions`Functional`

introduces some functional constants and the specification of transformations, which are a special kind of functions that act on collections.`Record`

describes the record collection type.`Monoidal`

describes the set, multiset and sequence collection types.`GBF`

describes collections defined by a uniform neighborhood. Arrays are a special kind of GBF.`Graph`

describes the graph collection type.`Delaunay`

describes the delaunay collection type.`Chain`

describes the (forthcoming) abstract chain complex collection type.