> <\body> Constants are defined using the keyword >: <\mmx-code> welcome: String \ == "Welcome to Mathemagix!"; ok? \ \ \ : Boolean == sunny? and warm?; Mutable variables can be defined and modified using the keyword >, as in the following example: <\mmx-code> i: Int := 1; while i \= 10 step i := i + 1 do \ \ mmout \\ 10 \\ " * " \\ i \\ " = " \\ 10 * i \\ lf; The skope of a variable corresponds to the innermost block delimited by > and > in which the variable is defined. For instance: <\mmx-code> i: Int == 1; if cond? then { \ \ i: Int == 2; \ \ foo (i, i); } mmout \\ i \\ lf; // i contains 1 at this point Global variables admit the entire file as their skope. More complex scoping rules which apply in the case of multiple file projects or in presence of modules will be discussed in the . Regular identifiers should match the regular expression >. That is, the names of constants, variables, function names, macros and types should <\itemize> only contain letters, digits and the special characters , and >; and start with a letter or or . In addition, it is customary to use lowercase identifiers for constants, variables and functions, and to capitalize the first letter of each word in identifiers for types ( or ). Moreover, identifiers for boolean variables and predicates are usually suffixed by . Besides regular identifiers, supports various special identifiers, such as for addition. These will be discussed in more detail in the . The declaration of functions will be discussed in more detail in the chapter about functions. Simple function declarations admit the following syntax: <\mmx-code> function_name (arg_1: Type_1, ..., arg_n: Type_n): Ret_Type == body; For instance: <\mmx-code> cube (n: Int): Int == n*n*n; It should be noticed that this declaration is actually equivalent to the following declaration of as a \Pfunction constant\Q: <\mmx-code> cube: Int -\ Int == (n: Int) :-\ (n*n*n: Int); As in the case of ordinary variables, functions can be mutable: <\mmx-code> foo (n: Int): Int := n*n; foo := (n: Int) :-\ (n*n*n: Int); The > statement can be used to exit the function with a given return value. For instance: <\mmx-code> search_index (item: Int, v: Vector Int): Int == { \ \ for i: Int in 0..#v do \ \ \ \ if v[i] = item then return i; \ \ return -1; } provides the keyword >>> for the declaration of macros. Since names of types can sometimes be rather long, macros are often used in order to abbreviate them. For instance: <\mmx-code> POL ==\ Polynomial Rational; p: POL == polynomial (1, 2, 3); Since such abbreviations are usually local to a file, it is customary to declare all macros at the start of the file and to use the > keyword in order to keep them private to the file. For instance: <\mmx-code> include "numerix/rational.mmx"; include "algebrabix/polynomial.mmx"; include "algebrabix/matrix.mmx"; \; private { \ \ POL ==\ Polynomial Rational; \ \ MAT ==\ Matrix Rational; } \; // new routines on rational polynomials and matrices It is also customary to capitalize all letters in names of macros. <\remark> Macros with arguments are not yet supported by the compiler, but planned. Conditional statements are of one of following two forms>>> <\code> <\mmx-code> if condition? then then_body if condition? then then_body else else_body The bodies of the then-part and the else-part can either be single instructions or blocks of instructions braced into .... For instance, we may write <\mmx-code> if done? then { \ \ clean_up (); \ \ return; } <\mmx-code> fib (n: Int): Int == { \ \ if i \= 1 then return 1; \ \ else return fib (n-1) + fib (n-2); } Notice that the -- construct can also be used as an expression: <\mmx-code> mmout \\ "Take a " \\ (if warm? then "shirt" else "jacket") \\ lf; It often occurs that a list of actions has to be undertaken depending on the value of some expression. This kind dispatching can be achieved using the >> instruction which has the syntax <\mmx-code> match expression with match_body where is a sequence of cases of the following form:>> <\mmx-code> case case_pattern do case_body For instance: <\mmx-code> fib (n: Int): Int == \ \ match n with { \ \ \ \ case 0 do return 1; \ \ \ \ case 1 do return 1; \ \ \ \ case _ do return fib (n-1) + fib (n-2); \ \ } This is a simple example of the general mechanism of pattern matching, which will be discussed in more details in the . Loops are constructed as follows:> <\mmx-code> loop_modulator_1 ... loop_modulator_n do loop_body where the loop modulators are among one of the following five types:>>>>> <\indent> <\mmx-code> for variable: T in values for instruction while condition? until contition? step instruction A simple example of how to use the - modular is the following: <\mmx-code> for i: Int in 1 to 10 do \ \ mmout \\ i \\ " * " 10 \\ " = " \\ i * 10 \\ lf; The expression is an example of a \Pgenerator\Q. For more information on such objects, we refer to the . The - loop is equivalent to the following one which uses the , and modulators: <\mmx-code> for i: Int := 1 while i \= 10 step i := i + 1 do \ \ mmout \\ i \\ " * " 10 \\ " = " \\ i * 10 \\ lf; The modulator (without ) is really syntactic sugar: the above code is essentially the same as <\mmx-code> i: Int := 1; while i \= 10 step i := i + 1 do \ \ mmout \\ i \\ " * " 10 \\ " = " \\ i * 10 \\ lf; except that the scope of the variable is bound to the body of the loop when using the modulator. Similarly, the modulator could have been moved to the body of the loop: <\mmx-code> for i: Int := 1 while i \= 10 do { \ \ mmout \\ i \\ " * " 10 \\ " = " \\ i * 10 \\ lf; \ \ i := i + 1; } However, this way of writing things is slightly longer and less readable. Furthermore, this kind of rewriting becomes less straightforward in presence of instructions (see below). The condition of the modulator is tested each time before executing the body of the loop. By contrast, the condition of the modulor is tested only at the end of the loop. For instance, in the following loop, the body is executed at least one time: <\mmx-code> until i \ 10 do { \ \ mmout \\ "i= " \\ i \\ lf; \ \ i := i + 1; } It should also be noticed that modulators of the same type can very well be used several times. For instance, the following loop will output the numbers , and : <\mmx-code> v1: Vector Int == [1, 2, 3]; v2: Vector Int == [4, 5, 6]; for x1: Int in v1 for x2: Int in v2 do \ \ mmout \\ x1 * x2 \\ lf; In this last example, even though and are not of type , there exists a prefix operator from to which allow us to write and . The execution of a loop can be interrupted using the > instruction. As soon as a instruction is encountered, execution will resume at the end of the loop. For instance, the following loop will only output the numbers one until five: <\mmx-code> for i: Int in 1 to 10 do { \ \ if i = 6 then break; \ \ mmout \\ i \\ lf; } In a similar way, the > instruction interrupts the execution of the body of the loop, but continues with the execution of the next cycle. For instance, the following code will display all numbers from one to ten, except for the number six: <\mmx-code> for i: Int in 1 to 10 do { \ \ if i = 6 then continue; \ \ mmout \\ i \\ lf; } Exceptions in are handled using a conventional try-catch mechanism. This mechanism resides on three keywords: <\itemize> The \P\Q> instruction with one argument of an arbitrary type is used in order to raise an exception of type . The \P\Q> instruction protects the block of instructions against exceptions, by allowing the user to provide exceptions handlers for exceptions of various types. Any number of \P\Q> instructions can occur at the end of the . Whenever an exception of type occurs, it is handled by the corresponding exception handler . Exceptions which could not be catched are propagated further outwards. A typical example of a safe routine for printing values of a partially defined function is <\mmx-code> print_values (f: Double -\ Double): Void == { \ \ for x: Double in -5.0 to 5.0 do { \ \ \ \ try { \ \ \ \ \ \ y: Double == f x; \ \ \ \ \ \ mmout \\ x \\ "\\t" \\ y \\ lf; \ \ \ \ \ \ catch (err: String) { \ \ \ \ \ \ \ \ mmout \\ x \\ "\\t" \\ err \\ lf; \ \ \ \ \ \ } \ \ \ \ } \ \ } } A typical example of a corresponding partially defined function is <\mmx-code> foo (x: Double): Double == { \ \ if x \= -2.0 then return x + 2.0; \ \ if x \= \ 2.0 then return x - 2.0; \ \ raise "out of range"; } Applying on yields the following output <\compact> <\indent> <\verbatim> -5 \ \ \ \ \ -3 -4 \ \ \ \ \ -2 -3 \ \ \ \ \ -1 -2 \ \ \ \ \ 0 -1 \ \ \ \ \ out of range 0 \ \ \ \ \ \ out of range 1 \ \ \ \ \ \ out of range 2 \ \ \ \ \ \ 0 3 \ \ \ \ \ \ 1 4 \ \ \ \ \ \ 2 5 \ \ \ \ \ \ 3 Standard libraries usually raise errors of the type > instead of . For this reason, one might wish to replace the type of by . In that case the routine should be replaced by <\mmx-code> foo (x: Double): Double == { \ \ if x \= -2.0 then return x + 2.0; \ \ if x \= \ 2.0 then return x - 2.0; \ \ raise exception ("out of range", x); } The second argument of > allows the user to specify a reason for the exception, such as an offending value or a line in the source code which triggered the exception. supports two types of comments. Short comments start with > and extend to the end of the physical line: <\mmx-code> class Complex (R: Ring) { \ \ re: R; \ // real part of the complex number \ \ im: R; \ // imaginary part of the complex number \ \ ... } Long multi-line comments should be braced into >> and can be nested: <\mmx-code> y == hacked_function x; /{ FIXME: \ \ This is a dangerous hack /{ which occurs only on the first of april }/ \ \ A skilled extraterrestian should be able to fix it }/ . If you don't have this file, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.> >