A quick introduction to Mathemagix Language

This document is a tutorial introduction to the Mathemagix language.

1.Variables and constants

Identifiers of variables are formed using letters, digits and the special characters _ and ?. Identifiers must start with a letter or _. Identifiers should match the regular expression [a-zA-Z_]+[a-zA-Z0-9_?]*.

To assign a value to a variable, we use the operator := :

Mmx]  
a1 := 1

Constant values can be assigned by the operator ==, and cannot be modified hereafter:

Mmx]  
a1_? == 2; a1_?

The operator == will be used for instance to define functions which definition should not be modified.

Mmx]  
cst: Int == 11111*111111

:

Mmx]  
mut: Int := 1010*1234

:

Below, we try to modify a constant and we get an error:

Mmx]  
cst := - cst

:: ,

cst := - cst

~~~

whereas modifying a variable is not a problem:

Mmx]  
mut := - mut

:

Mmx]  

2.Predefined basic types

In this section, we describe the basic types, which exist by default in the interpreter. For the other types provided by the extension packages, see their documentation.

2.1.Generic

The default type of an object is Generic and the corresponding variable type is Alias Generic:

Mmx]  
a := x

Mmx]  
type a

Mmx]  

2.2.Boolean

The usual boolean constant are true and false. The equality and inequality tests are = and !=.

Mmx]  
a = a

Mmx]  
a != a

To build boolean expression, we use the operators and, or and the negation operator ! :

Mmx]  
a = b and a != c

Mmx]  
a = b or a != c

Mmx]  
!( a = b or a != c)

Constants, functions or operators with an argument of type Boolean in its signature:

Mmx]  
help Boolean

Boolean
(Class)

Available functions

! : Boolean -> Boolean

!= : (Boolean, Boolean) -> Boolean

!= : (Int, Int) -> Boolean

!= : (Double, Double) -> Boolean

!= : (Literal, Literal) -> Boolean

!= : (Compound, Compound) -> Boolean

!= : (Function, Function) -> Boolean

!= : (Macro, Macro) -> Boolean

!= : (Generic, Generic) -> Boolean

!= : (Vector (Generic), Vector (Generic)) -> Boolean

!= : (Document, Document) -> Boolean

!= : (Dynamic, Dynamic) -> Boolean

!= : (List (Generic), List (Generic)) -> Boolean

!= : (Port, Port) -> Boolean

!= : (Executable (Void), Executable (Void)) -> Boolean

!= : (Executable (Generic), Executable (Generic)) -> Boolean

!= : (Executable (Reference (Generic)), Executable (Reference (Generic))) -> Boolean

!= : (Syntactic, Syntactic) -> Boolean

!= : (Table (Generic, Generic), Table (Generic, Generic)) -> Boolean

!= : (String, String) -> Boolean

!= : (Module, Module) -> Boolean

!= : (Exception, Exception) -> Boolean

!= : (Generator (Generic), Generator (Generic)) -> Boolean

.busy? : Port -> Boolean

.error? : Port -> Boolean

.input_port? : Port -> Boolean

.output_port? : Port -> Boolean

<= : (Vector (Generic), Vector (Generic)) -> Boolean

<= : (String, String) -> Boolean

<= : (Double, Double) -> Boolean

<= : (Int, Int) -> Boolean

< : (Vector (Generic), Vector (Generic)) -> Boolean

< : (String, String) -> Boolean

< : (Double, Double) -> Boolean

< : (Int, Int) -> Boolean

= : (Boolean, Boolean) -> Boolean

= : (Int, Int) -> Boolean

= : (Double, Double) -> Boolean

= : (Literal, Literal) -> Boolean

= : (Compound, Compound) -> Boolean

= : (Function, Function) -> Boolean

= : (Macro, Macro) -> Boolean

= : (Generic, Generic) -> Boolean

= : (Vector (Generic), Vector (Generic)) -> Boolean

= : (Document, Document) -> Boolean

= : (Dynamic, Dynamic) -> Boolean

= : (List (Generic), List (Generic)) -> Boolean

= : (Port, Port) -> Boolean

= : (Executable (Void), Executable (Void)) -> Boolean

= : (Executable (Generic), Executable (Generic)) -> Boolean

= : (Executable (Reference (Generic)), Executable (Reference (Generic))) -> Boolean

= : (Syntactic, Syntactic) -> Boolean

= : (Table (Generic, Generic), Table (Generic, Generic)) -> Boolean

= : (String, String) -> Boolean

= : (Module, Module) -> Boolean

= : (Exception, Exception) -> Boolean

= : (Generator (Generic), Generator (Generic)) -> Boolean

>= : (Vector (Generic), Vector (Generic)) -> Boolean

>= : (String, String) -> Boolean

>= : (Double, Double) -> Boolean

>= : (Int, Int) -> Boolean

> : (Vector (Generic), Vector (Generic)) -> Boolean

> : (String, String) -> Boolean

> : (Double, Double) -> Boolean

> : (Int, Int) -> Boolean

alias : Boolean -> Alias (Boolean)

atom? : Vector (Generic) -> Boolean

atom? : List (Generic) -> Boolean

batch_mode? : Literal

compound? : Generic -> Boolean

contains? : (Vector (Generic), Generic) -> Boolean

contains? : (List (Generic), Generic) -> Boolean

contains? : (Table (Generic, Generic), Generic) -> Boolean

contains? : (Table (Generic, Generic), Tuple (Generic)) -> Boolean

debug_mode? : Literal

defined? : Generic -> Boolean

directory? : String -> Boolean

ends? : (String, String) -> Boolean

false : Literal

file? : String -> Boolean

file_exists? : String -> Boolean

finite? : Double -> Boolean

flatten : Boolean -> Syntactic

follow_link : (String, Boolean) -> String

infinite? : Double -> Boolean

list? : Generic -> Boolean

literal? : Generic -> Boolean

math_mode? : Literal

nan? : Double -> Boolean

nil? : Vector (Generic) -> Boolean

nil? : List (Generic) -> Boolean

quiet_mode? : Literal

source_column : (Generic, Boolean) -> Int

source_exists? : Generic -> Boolean

source_line : (Generic, Boolean) -> Int

starts? : (String, String) -> Boolean

table? : Generic -> Boolean

texmacs_mode? : Literal

time_mode? : Literal

true : Literal

type? : Generic -> Boolean

type_mode? : Literal

vector? : Generic -> Boolean

wait : (Port, Int) -> Boolean

xor : (Boolean, Boolean) -> Boolean

Mmx]  

2.3.Strings

Strings can be braced into double quotes " … ". Inside such a string a double quote must be blackslashed. In order to avoid blackslashing one can use the stronger string delimiters /" … "/.

Mmx]  
s1 := "This is a string"

"This is a string"

Mmx]  
s2 : String := "Print \"foo\" "

"Print "foo" "

Not that in this definition, we specify that the variable s2 is of type String.

Mmx]  
s2 := /" Print "foo" "/

" Print "foo" "

The concatenation of strings can be done by the operator ><

Mmx]  
s3 := s2 ><" and \"fii\" "

" Print "foo" and "fii" "

It is also possible to use the in place concatenation operator << on a variable:

Mmx]  
s2 <</" and "fuu" "/

" Print "foo" and "fuu" "

The length of a string is given by the operator #

Mmx]  
#s1

Search forward the position of a substring. If it is not found, the result is , otherwise it returns the position of the first character.

Mmx]  
search_forwards (s2, "Print", 0)

Mmx]  
replace(s2, "fuu", "haha")

" Print "foo" and "haha" "

Constants, functions or operators, with an argument of type String in its signature:

Mmx]  
help String

String
(Class)

Available functions

!= : (String, String) -> Boolean

# : String -> Int

$color : (String, Document) -> Document

$font : (String, Document) -> Document

$font_size : (String, Document) -> Document

$magnification : (String, Document) -> Document

$tm : (String, Tuple (Document)) -> Document

$with : (String, String, Document) -> Document

$with : (String, String, String, String, Document) -> Document

$with : (String, String, String, String, String, String, Document) -> Document

* : (String, String) -> String

.[] : (String, Int, Int) -> String

.[] : (Port, String) -> Port

.error : Port -> String

<< : (Alias (String), String) -> Alias (String)

<< : (Port, String) -> Port

<= : (String, String) -> Boolean

< : (String, String) -> Boolean

= : (String, String) -> Boolean

>< : (String, String) -> String

>= : (String, String) -> Boolean

> : (String, String) -> Boolean

alias : String -> Alias (String)

as_double : String -> Double

as_int : String -> Int

as_literal : String -> Literal

as_string : Literal -> String

as_string : Double -> String

as_string : Int -> String

as_string : Syntactic -> String

as_string : Exception -> String

as_string_hexa : Int -> String

current_file : Literal

directory? : String -> Boolean

ends? : (String, String) -> Boolean

error_port : String -> Port

eval_system : String -> String

exception : (String, Generic) -> Exception

file? : String -> Boolean

file_exists? : String -> Boolean

flatten : String -> Syntactic

flatten_as_cpp : Generic -> String

flatten_as_mmx : Generic -> String

follow_link : (String, Boolean) -> String

get_directory : String -> String

get_env : String -> String

get_extension : String -> String

input_file_port : String -> Port

input_string_port : String -> Port

last_modified : String -> Double

literal_string : Literal -> String

locase_first : String -> String

locase : String -> String

output_file_port : String -> Port

path_name : (String, String) -> String

pipe_port : String -> Port

quote : String -> String

read : (Port, Int) -> String

relative_name : (String, String) -> String

replace : (String, String, String) -> String

resolve_name : (String, String) -> String

search_backwards : (String, String, Int) -> Int

search_forwards : (String, String, Int) -> Int

socket_client_port : (String, Int) -> Port

socket_server_port : (String, Int) -> Port

source_begin : Generic -> String

source_end : Generic -> String

source_error : (String, Generic) -> String

source_file : Generic -> String

source_string_unindented : Generic -> String

source_string : Generic -> String

source_underlined : Generic -> String

starts? : (String, String) -> Boolean

strip_directory : String -> String

strip_extension : String -> String

system : String -> Int

unquote : String -> String

upcase_first : String -> String

upcase : String -> String

user_boot_file : Literal

write : (Port, String) -> Generic

Mmx]  

2.4.Machine integers

An integer literal is a sequence of digits, possible preceded by a minus sign. It matches the regular expression [-]?[0-9]+. Examples: 123456789123456789, -123.

Mmx]  
a := 2

The usual arithmetic operators +, -, * are available:

Mmx]  
a+3; a-5; a*a

as well as the inplace operators +=, -=, *= :

Mmx]  
a += 1; a *= 2; a -= 3

Mmx]  
5 div 2

Mmx]  
5 mod 2

The default type for integers is Int. It corresponds to machine type int.

Mmx]  
type(1)

Constants, functions or operators, with an argument of type Int in its signature:

Mmx]  
help Int

Int
(Class)

Available functions

!= : (Int, Int) -> Boolean

# : Vector (Generic) -> Int

# : Compound -> Int

# : String -> Int

# : List (Generic) -> Int

# : Table (Generic, Generic) -> Int

* : (Int, Int) -> Int

+ : (Int, Int) -> Int

.[] : (Vector (Generic), Int) -> Generic

.[] : (Alias (Vector (Generic)), Int) -> Alias (Generic)

.[] : (Vector (Generic), Int, Int) -> Vector (Generic)

.[] : (Compound, Int) -> Generic

.[] : (String, Int, Int) -> String

.[] : (List (Generic), Int) -> Generic

.[] : (Alias (List (Generic)), Int) -> Alias (Generic)

.[] : (List (Generic), Int, Int) -> List (Generic)

.can_read : Port -> Int

.can_write : Port -> Int

<= : (Int, Int) -> Boolean

< : (Int, Int) -> Boolean

= : (Int, Int) -> Boolean

>= : (Int, Int) -> Boolean

> : (Int, Int) -> Boolean

^^ : (Generic, Int) -> Tuple (Generic)

abs : Int -> Int

alias : Int -> Alias (Int)

as_int : Double -> Int

as_int : String -> Int

as_string : Int -> String

as_string_hexa : Int -> String

count : Int -> Generic

decrease_exponent : (Double, Int) -> Double

div : (Int, Int) -> Int

exit : Int -> Generic

flatten : Int -> Syntactic

literal_integer : Literal -> Int

max : (Int, Int) -> Int

min : (Int, Int) -> Int

mod : (Int, Int) -> Int

wait : Int -> Int

2.5.Double

By default, the floating point literals are converted to Double types. A floating literal is a sequence of digits with a decimal point inside and an optional exponent. It matches the regular expression [-]?[0-9]+[.][0-9]+[[eE][-]?[0-9]+]?.

Note that 0. is not permitted, one must write 0.0;

Mmx]  
2.1

Mmx]  
2.1*3

Mmx]  
2.3/2-1

Mmx]  
type(1.1)

Mmx]  
help Double

Double
(Class)

Available functions

!= : (Double, Double) -> Boolean

* : (Double, Double) -> Double

+ : (Double, Double) -> Double

/ : (Double, Double) -> Double

<= : (Double, Double) -> Boolean

< : (Double, Double) -> Boolean

= : (Double, Double) -> Boolean

>= : (Double, Double) -> Boolean

> : (Double, Double) -> Boolean

^ : (Double, Double) -> Double

abs : Double -> Double

alias : Double -> Alias (Double)

arccos : Double -> Double

arcsin : Double -> Double

arctan : Double -> Double

as_double : String -> Double

as_int : Double -> Int

as_string : Double -> String

ceil : Double -> Double

cos : Double -> Double

decrease_exponent : (Double, Int) -> Double

exponent : Double -> Int

exp : Double -> Double

finite? : Double -> Boolean

flatten : Double -> Syntactic

floor : Double -> Double

increase_exponent : (Double, Int) -> Double

infinite? : Double -> Boolean

last_modified : String -> Double

literal_floating : Literal -> Double

log : Double -> Double

magnitude : Double -> Double

max : (Double, Double) -> Double

min : (Double, Double) -> Double

nan? : Double -> Boolean

next_above : Double -> Double

next_below : Double -> Double

precision : Double -> Int

round : Double -> Double

rounding_error : Double -> Double

sin : Double -> Double

sqrt : Double -> Double

square : Double -> Double

tan : Double -> Double

trunc : Double -> Double

In order to have access to extended arithmetic (Integer, Rational, Floating,…), one can use the package numerix. In this case, the integer literals will yield numbers of type Integer, based on gmp integers:

Mmx]  
use "numerix"; type(1)

For more details on the package numerix, see here.

Mmx]  

2.6.Syntactic type

The Syntactic type can be used to produce document outputs, represented as lisp-type expressions. It is automatically parsed by TeXmacs to display these outputs.

Mmx]  
type_mode?:=true

:

Mmx]  
'x

:

Mmx]  
'(f (x, y, z))

:

Mmx]  
'(f (x, y, z)) [2]

:

Mmx]  
$document ("Some ", $with ("color", "red", "red"), " text.";
           "Pythagoras said ", $math ('(a^2 + b^2 = c^2)), ".")

Some red text.
Pythagoras said .

:

Mmx]  

3.Compound types

3.1.Vectors

Vectors are sequence of elements, stored in an array and with a direct access through their index. Their type is parametrized by the type of the elements. The default type is Vector Generic.

Mmx]  
v := [1,2,3]

The indices start from 0 :

Mmx]  
v[0]+v[1]+v[2]

The length of a vector is given by the prefix operator #:

Mmx]  
#v

The concatenation of vectors is performed by the operator ><:

Mmx]  
w := v >< [4,5]

The inplace concatenation of vectors is done by the operator <<:

Mmx]  
v << [1,2]

The classical operations car, cdr, cons on lists are available also on vectors:

Mmx]  
[car(v), cdr(v), cons(3,v)]

Mmx]  
reverse v

Mmx]  
contains?(v,1)

Mmx]  
help Vector(Generic)

Vector (Generic)
(Class)

Available functions

!= : (Vector (Generic), Vector (Generic)) -> Boolean

# : Vector (Generic) -> Int

* : (Vector (Generic), Vector (Generic)) -> Vector (Generic)

* : (Generic, Vector (Generic)) -> Vector (Generic)

* : (Vector (Generic), Generic) -> Vector (Generic)

+ : (Vector (Generic), Vector (Generic)) -> Vector (Generic)

+ : (Generic, Vector (Generic)) -> Vector (Generic)

+ : (Vector (Generic), Generic) -> Vector (Generic)

.[] : (Vector (Generic), Int) -> Generic

.[] : (Alias (Vector (Generic)), Int) -> Alias (Generic)

.[] : (Vector (Generic), Int, Int) -> Vector (Generic)

/ : (Vector (Generic), Vector (Generic)) -> Vector (Generic)

/ : (Generic, Vector (Generic)) -> Vector (Generic)

/ : (Vector (Generic), Generic) -> Vector (Generic)

<< : (Alias (Vector (Generic)), Vector (Generic)) -> Alias (Vector (Generic))

<= : (Vector (Generic), Vector (Generic)) -> Boolean

< : (Vector (Generic), Vector (Generic)) -> Boolean

= : (Vector (Generic), Vector (Generic)) -> Boolean

>< : (Vector (Generic), Vector (Generic)) -> Vector (Generic)

>= : (Vector (Generic), Vector (Generic)) -> Boolean

> : (Vector (Generic), Vector (Generic)) -> Boolean

[] : Tuple (Generic) -> Vector (Generic)

^ : (Vector (Generic), Vector (Generic)) -> Vector (Generic)

alias : Vector (Generic) -> Alias (Vector (Generic))

append : Tuple (Vector (Generic)) -> Generic

apply : (Generic, Vector (Generic)) -> Generic

arccos : Vector (Generic) -> Vector (Generic)

arcsin : Vector (Generic) -> Vector (Generic)

arctan : Vector (Generic) -> Vector (Generic)

arguments : Compound -> Vector (Generic)

argv : Literal

as_compound : Vector (Generic) -> Compound

as_vector : Compound -> Vector (Generic)

atom? : Vector (Generic) -> Boolean

big_add : Vector (Generic) -> Generic

big_mul : Vector (Generic) -> Generic

car : Vector (Generic) -> Generic

cdr : Vector (Generic) -> Vector (Generic)

components : Compound -> Vector (Generic)

cons : (Generic, Vector (Generic)) -> Vector (Generic)

contains? : (Vector (Generic), Generic) -> Boolean

contents : Module -> Vector (Generic)

cos : Vector (Generic) -> Vector (Generic)

dot : (Vector (Generic), Vector (Generic)) -> Generic

exp : Vector (Generic) -> Vector (Generic)

find : (Vector (Generic), Generic) -> Int

flatten : Vector (Generic) -> Syntactic

foreach : (Generic, Tuple (Vector (Generic))) -> Generic

help_filtered : (Vector (Generic), Function) -> Vector (Generic)

insert : (Vector (Generic), Generic) -> Vector (Generic)

lambda_do : (Vector (Generic), Executable (Generic)) -> Executable (Generic)

log : Vector (Generic) -> Vector (Generic)

map : (Generic, Tuple (Vector (Generic))) -> Generic

nil? : Vector (Generic) -> Boolean

reverse : Vector (Generic) -> Vector (Generic)

sin : Vector (Generic) -> Vector (Generic)

sort : Vector (Generic) -> Vector (Generic)

sort : (Vector (Generic), Generic) -> Vector (Generic)

sqrt : Vector (Generic) -> Vector (Generic)

square : Vector (Generic) -> Vector (Generic)

tan : Vector (Generic) -> Vector (Generic)

vector : Tuple (Generic) -> Vector (Generic)

Mmx]  

3.2.Tuples

Tuples are written inside (). Elements are separated by ,.

Mmx]  
v := (1,2,3)

Note the associativity of tuples:

Mmx]  
(1,(2,3))

Mmx]  
v:= [1,2]; (v,((v)))

Mmx]  
help Tuple(Generic)

Tuple (Generic)
(Class)

Available functions

() : Tuple (Generic) -> Tuple (Generic)

.() : (Compound, Tuple (Generic)) -> Generic

.() : (Literal, Tuple (Generic)) -> Generic

.[] : (Literal, Tuple (Generic)) -> Generic

.[] : (Table (Generic, Generic), Tuple (Generic)) -> Generic

.[] : (Alias (Table (Generic, Generic)), Tuple (Generic)) -> Alias (Generic)

[] : Tuple (Generic) -> Vector (Generic)

^^ : (Generic, Int) -> Tuple (Generic)

compound : Tuple (Generic) -> Compound

contains? : (Table (Generic, Generic), Tuple (Generic)) -> Boolean

list : Tuple (Generic) -> List (Generic)

reset : (Alias (Table (Generic, Generic)), Tuple (Generic)) -> Generic

set : (Table (Generic, Generic), Tuple (Generic), Generic) -> Generic

vector : Tuple (Generic) -> Vector (Generic)

Mmx]  

3.3.Iterators

a to b means the range [a,b], while a..b stands for the half open range [a,b).

Mmx]  
(1 to 4)

Mmx]  
1 .. 4

Note that 1..4 or 1 to 4 are not tuples but iterators, that can be used to produce sequences:

Mmx]  
[1..6]

Mmx]  
[i*i | i in 1 to 10]

Double iterators are also possible when matrix types are available:

Mmx]  
use "algebramix"; [i+j | i in 0 to 9 || j in 0..10]

Mmx]  

4.Tables

Tables allow to store the association between keys of one type and values of another type. They are defined by providing a default value. In the following example, the default value is 1:

Mmx]  
t := table(1);
Mmx]  
t[1]  := -3; t[34] :=  2

Mmx]  
t[0]

Mmx]  
contains? (t,2)

Mmx]  
help Table(Generic,Generic)

Table (Generic, Generic)
(Class)

Available functions

!= : (Table (Generic, Generic), Table (Generic, Generic)) -> Boolean

# : Table (Generic, Generic) -> Int

.[] : (Table (Generic, Generic), Generic) -> Generic

.[] : (Alias (Table (Generic, Generic)), Generic) -> Alias (Generic)

.[] : (Table (Generic, Generic), Tuple (Generic)) -> Generic

.[] : (Alias (Table (Generic, Generic)), Tuple (Generic)) -> Alias (Generic)

= : (Table (Generic, Generic), Table (Generic, Generic)) -> Boolean

alias : Table (Generic, Generic) -> Alias (Table (Generic, Generic))

contains? : (Table (Generic, Generic), Generic) -> Boolean

contains? : (Table (Generic, Generic), Tuple (Generic)) -> Boolean

flatten : Table (Generic, Generic) -> Syntactic

reset : (Alias (Table (Generic, Generic)), Generic) -> Generic

reset : (Alias (Table (Generic, Generic)), Tuple (Generic)) -> Generic

set : (Table (Generic, Generic), Generic, Generic) -> Generic

set : (Table (Generic, Generic), Tuple (Generic), Generic) -> Generic

table : Generic -> Table (Generic, Generic)

Mmx]  

The default type for tables used in the interpreter is Table(Generic,Generic).

5.Control flow

5.1.Conditionals

The condition construction is as follows:

if condition then block1 [else block2]

where condition is any expression that evaluates to a boolean. block1 and block2 are either one instruction or a block of instructions braced into {}. The [] (here the else part) means that the expression is optional.

Mmx]  
if true then 1

:

Mmx]  
if a = b then 1 else 2

:

Mmx]  
if i = 0 then { 
  x := 1; y := 2
} else { 
  z := 3; mmerr << "error" 
}

:

Mmx]  

5.2.Loops

Loops are constructed as follows:

[for E1] [while E2] [until E3] [step E4] do block

The block is an instruction or a sequence of instructions delimited by {}. break exits the loop, and continue goes to the next step of the loop.

Mmx] 
for i in 1..3 do mmout << i << " ";

1 2

Mmx] 
i := 0; while i < 5 do { mmout << i << " "; i := i + 1 }

0 1 2 3 4

Mmx]  
// do mmout << "no end "; // This loop has no end

6.Functions

6.1.Function definition

A function definition is done as follows:

name (arg1: type1, arg2: type2, …): returned_type ==  block

The block is either one instruction or several instructions in between { }. Mathemagix also provides a syntax for lambda expressions:

lambda (arg1: type1, arg2: type2, …): returned_type do

Notice that any of the type specifications can be omitted, in which case the type is assumed to be Generic.

Mmx]  
f (x: String) :String == return x><x

:

Mmx]  
f("ab")

"abab"

:

A function is called in the usual way: foo(arg1, arg2,…).

If foo is unitary then () can be omitted, but note that foo a b c is equivalent to foo(a(b(c))). Function call is always by value.

6.2.Polymorphism

In the following definition, no type are specified so that the input and output type Generic are assumed:

Mmx]  
f (x) == { 
  a :Generic == x*x;  
  return a 
} 

:

When a function has only one argument, the parenthesis () can be omitted.

Mmx]  
f 3.1

:

The same name f is used for the definition of two functions of types lambda: Int Int, lambda: Generic Generic. The polymorphism of f is resolved by the type of its argument:

Mmx]  
f "xx " 

"xx xx "

:

Mmx]  
f 2.1

:

Local variables have to be declared with a type and an initial value:

Mmx]  
 add_naive (a: Vector Generic) == { 
   c : Generic := 0; for x in a do c := c + x; 
   return c;
 }

:

Mmx]  
add_naive([1,2,3])

:

6.3.Method definitions

The definition of a postfix function is preceded by the keyword postfix. The name of the function should start with a .:

Mmx]  
 postfix .sq(i : Int) : Int == { return i*i }

:

Mmx]  
3.sq

:

Mmx]  
postfix .m (a: Int) (b: Int) : Double == { return 1.0*a*b }

:

Mmx]  
3.m(3)

:

6.4.Functional programming

Mmx]  
fib (n: Int): Int ==
  if n <= 1 then 1 else fib (n-1) + fib (n-2)

:

Mmx]  
[fib n | n in 1..10]

:

Mmx]  
shift (x: Int) (y: Int): Int == x + y

:

Mmx]  
shift 3

:

Mmx]  
(shift 3) 4

:

Mmx]  
map (shift 3, [ 1 to 20 ])

:

Mmx]  

6.5.Parameterized types

Any function definition can be preceded by quantifiers forall() or exists().

forall (R) gcd (p: Polynomial(R), q: Polynomial(R)): Polynomial(R) == {…}

6.6.Exceptions

Mmx]  
risky (x: Int): Double == {
  if x = 5 then raise "not in domain";
  return 1 / (x - 5);
}
try {
  for i in 1 to 10 do mmout << i << " -> " << risky i << "\n";
  catch (err: String) { mmout << "error: " << err << "\n"; }
};

->

->

->

->

-> error: not in domain

Mmx]  

7.Macros

A macro corresponds to a syntactic definition. No type is needed:

Mmx]  
square x ==> x*x

:

Mmx]  
square 2.1

:

Mmx]  
square 2

:

Mmx]  
disc(a,b,c) ==> b*b - 4*a*c 

:

Mmx]  
disc (1,2,3.001)

:

Macros can be usefull to define short and convenient names for types for instance:

Mmx]  
VG ==> Vector Generic

:

Mmx]  
f(a : VG) == car a

:

Mmx]  
f ([1,2])

:

Mmx]  

8.Class definition

Mmx]  
class Color == {
  mutable { r: Double; g: Double; b: Double; }
  constructor grey (x: Double) == {
    r == x; g == x; b == x; }
  constructor rgb (r2: Double, g2: Double, b2: Double) == {
    r == r2; g == g2; b == b2; }
}
Mmx]  
rgb (1, 0, 0)

:

Mmx]  
flatten (c: Color): Syntactic ==
  syntactic ('rgb (as_generic flatten c.r,
                   as_generic flatten c.g,
                   as_generic flatten c.b));
Mmx]  
rgb (1, 0, 0)

:

Mmx]  
mix (c1: Color, c2: Color, a: Double): Color ==
  rgb (a * c1.r + (1-a) * c2.r,
       a * c1.g + (1-a) * c2.g,
       a * c1.b + (1-a) * c2.b);
Mmx]  
mix (rgb (1, 0, 0), grey (0.5), 0.5)

:

Mmx]  

9.Type conversions

The operator :> can be used to convert a given type to another, provided that the corresponding function downgrade is defined. We show here an example of an explicit conversion from a class Alpha_color to the class Color:

Mmx]  
class Alpha_color == {
  mutable { c: Color; a: Double; }
  constructor alpha_color (c2: Color, a2: Double) == { c == c2; a == a2; }
};
Mmx]  
alpha_color (rgb(0,0,1), 0.5)

:

Mmx]  
downgrade (ac: Alpha_color): Color == mix (ac.c, rgb(1,1,1), ac.a);
Mmx]  
alpha_color (rgb(0,0,0), 0.6) :> Color

:

In order to define implicit conversions from a type to another, one can use the function updgrade:

Mmx]  
upgrade (x: Double): Color == grey x;

We use implicitely in the instruction below to convert 1.0 to a Color type:

Mmx]  
mix (1.0, rgb (0, 1, 0), 0.2)

:

Mmx]  
mix (0.8, 0.2, 0.4)

:

Mmx]  
postfix .greyed (c: Color): Color == (c.r + c.g + c.b) / 3;
Mmx]  
rgb (1, 0, 0).greyed

:

Mmx]  

10.Ports

There is an output stream, which is called mmout. It can be used with the operator << to print strings:

Mmx]  
mmout

:

Mmx]  
mmout << "Hello\n";

Hello

Mmx]  
i := 3; mmout<<"The square of "<<i<<" is "<<i*i<<"\n"; 

The square of is

The error stream, used to catch error message, is mmerr:

Mmx]  
mmerr <<"An error message";

Output streams can also be defined from files. Here we add a string the the file toto.txt:

Mmx]  
output_file_port ("toto.txt") << "Hi there\n";

and we load the contents of this file as a string:

Mmx]  
load ("toto.txt")

"Hi there\n"

:

11.Handling file

Here are some usefull command to read and save contents in files. The command to read a Mathemagix file and to evaluate it is include:

Mmx] 
include "example.mmx"

The command to save a String in a file is save:

Mmx]  
save ("tmp.txt", "A string is stored in the file \n in two lines");

If now, you want to recover the content of a file, you can use the command load:

Mmx]  
load "tmp.txt"

"A string is stored in the file \n in two lines"

:

The files in a directory can be recovered by the command load_directory. The result is a vector of strings, which corresponds to the name of a file or a subdirectory:

Mmx]  
load_directory "."

:

To check if a file or a directory exists, one can use the predicate readable?

Mmx]  
readable? "tmp.txt"

:

The function use allows to load and use the types and functions exported in an external dynamic library:

Mmx] 
use "numerix"

If this example, the library libmmxnumerix.so should be in the loading path.

Mmx]  

12.Environment

Several functions are available to interact with the environment. To get the value of a variable defined in the environment, one can use get_env:

Mmx] 
get_env "PWD"

Mmx] 
set_env ("DISPLAY", "arthur:0")

To run a command in this environement, one can use the function system:

Mmx]  
system "ls"

emacs_mode.en.tm

how_to.en.tm

index.en.tm

installation.en.tm

quick_start.en.tm

shell.en.tm

shell_tutorial.en.tm

syntax.en.tm

tmp.txt

toto.txt

:

Mmx]  

13.Comments

Comments starting with // extend to the end of the physical line. Such a comment may appear at the start of a line or following whitespace or code, but not within a string literal. Multi-line comments must be braced into /{ … }/ and can be nested.

x := 1; // Assign 1 to x.

y := 2;
/{ This
   is multi-line
   comment about y.
}/
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License. If you don't have this file, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.