Introduction to the syntax of Tycoon by examples


Note:

The following demo scripts are useful to learn the most basic Tycoon expressions by cutting & pasting the examples into the Tycoon toplevel. Use the switch 'do set printTL true;' to see the output of the compiler.

Values, types, bindings

a) Values:

   ok;
   true;
   99;
   'c';
   "hello world";
   tuple 1 "hello world" end;
   tuple let fst = 1  let snd = "hello world" end;
   {tuple let fst = 1  let snd = "hello world" end}.snd;
   array 1 2 3 end;
   99 + 2;
   99 + 2 * 3;
   {99 + 2} * 3;
   99 + {2 * 3};
   fun(i :Int) :Int i;
   {fun(i :Int) :Int i}(99);
b) The above values are typed:

   :Ok;
   :Bool;
   :Int;
   :Char;
   :String;
   :Tuple :Int :String end;
   :Tuple fst :Int  snd :String end;
   :Array(Int);
   :Fun(i :Int) :Int;
   :Fun(:Int) :Int;
c) Create bindings of identifiers to the values and types above, e.g. 'let i = 99' or 'Let T = Int'

d) Naming and scoping:

   let a = 99;
   a;
   let b = "hello world";
   a + b;
   let c = a;
   a + c;
   let a = 1; (* does the value of c change? *)
   a + c;
   let b = 2; (* note binding of b above! *)
   a + b;
e) Block structured scoping:

   begin "hello" end;
   let a = 10;
   begin let a = "hello" end;
   a; (* which binding of a is used? *)
   let a = begin "hello" end;
   a;
   let c = 
      begin
         let a = 1
         let b = a + a
         a
      end;
   (* what's the value of a and what's the value of c? *)
   a; c;

More Values: Tuples, arrays, functions, ...

a) Tuples:

   let x =
      tuple
         let fst = 1
         let snd =
            tuple
               let a = "hello"
               let b = fst
            end
      end;
   x.fst;
   x.snd;
   x.snd.a;
   x.a;
   x.snd.b;
   x.fst.a;
b) Arrays:

   let a = array 2001 101 x.fst end;
   a[0];
   a[1];
   a[3];
   extent(a); (* size of an array *)
   x[0];
   extent(x);
   let b = array
              array 1 2 3 end
              array end
              array 2002 102 6 end
           end;
   extent(b);
   extent(b[0]);
   extent(b[1]);
   b[0][1];
   b[1];
   let c = array 1 'z' end;
   let c = array
              array 1 2 3 end
              array 'x' 'y' 'z' end
           end;
   let c = array end;
c) Booleans:

   let a = true;
   let b = not(true);
   (* strict and non-strict and/or: *)
   a /\ b;
   a \/ b;
   let x = array 'x' end;
   let i = 1;
   {i < extent(x)} /\ {x[i] == 'x'};
   {i < extent(x)} andif {x[i] == 'x'};
   {i <= extent(x)} andif {x[i] == 'x'};
   i < extent(x) andif x[i] == 'x';
   not(i >= extent(x) orif x[i] != 'x');
   (* -- Equality: *)
   1 == 1;
   true != false;
   'x' == 'x';
   "xyz" == "xyz";
   let a = 'x';
   a != 'x';
   tuple 1 end == tuple 2 end;
   tuple 1 end == tuple 1 end; (* !!! *)
   array 1 end == array 1 end;
d) Functions:

   fun() 1;
   {fun() 1}();
   fun() :String  1;
   let f() = 1;
   f;
   f();
   (* different syntactical possibilities to define a function: *)
   let f() = 1;
   let f = fun() 1;
   let f() :Int = 1;
   let f = fun() :Int  1;
   let f :Fun() :Int = fun() 1;
   let f() :Int = 'c';
   let f :Fun() :Int = fun() 'c';
   f()();
   (* higher order functions: *)
   let f() = fun() 1;
   f;
   f();
   f()();
   let f()() = 1;
   let id(i :Int) = i;
   let add1(i :Int) = i+1;
   let g(h(:Int) :Int  x :Int) = h(x);
   g(id 4);
   g(add1 4);
   g(id 4 5);
   g(id 'z');
   (* currying: *)
   let add(x :Int)(y :Int) :Int = x + y;
   add(1);
   add(1)(2);
   let add1 = add(1);
   add1;
   add1(2);

Values of an imperative universe

a) Conditionals:

   if true then "then" else "else" end;
   let a = 99;
   if true then let a = 1 else let b = 2 end;
   (* what is the value of a? *)
   a; b;
   if false then "then" end;
   if true then 1 else "hello" end;
   if 1 then true end;
   if 1 == 2 then 1 elsif 1 == {2-1} then 2 else 3 end;
b) Loops:

   loop if true then exit end end;
   let var a = 1;
   loop
      a:= a+1
      if a == 100 then
   exit
      end
   end;
   let x = loop exit end;
   x;
   for i = 1 upto 10 do
      i * i
   end;
   for i = 10 downto 1 do
      i * i
   end;
c) Mutable bindings:

   let var a = 99;
   a;
   let b = a;
   let var c = a;
   a:= 100;
   a; b; c;
   c:= 200;
   a; b; c;
   b:= 300;
d) Variable parameters:

   let f(var x :Int) =  x:= x+1;
   let var a = 99;
   f(a);
   a;
   let b = 1;
   f(b);
   f(let var x = 100); 
e) Variant tuples:

   Let Color =
      Tuple
         name :String
         case redCase
         case greenCase with
            intensity :Int
      end;
   let redObject = 
      tuple_case redCase of Color with
         let name = "red color"
      end;
   let greenObject =
      tuple_case greenCase of Color with
         "green color"
         10
      end;
   redObject.name;
   redObject.intensity;
   greenObject.intensity;
   redObject?redCase;
   redObject?greenCase;
   greenObject!greenCase.intensity;
   redObject!redCase.intensity;
   redObject!greenCase.intensity;
   case redObject
      when redCase then "red"
      when greenCase then "green"
   end;
   case red
      when greenCase then "green"
   end;
   case redObject
      when greenCase then "green"
      else "else"
   end;
   case of redObject
      when redCase then "red"
   end;
   case of redObject
      when redCase then "red"
      when greenCase then "green"
   end;
   case of redObject
      when redCase then "red"
      else "else"
   end;
   case greenObject
      when greenCase with x then
         x.intensity
      else ~1
   end;
f) Exceptions:

   let newExc = exception "new Exc" end;
   raise newExc end;
   try
      raise newExc end
      "normal"
   else
      "else"
   end;
   try
      raise newExc end
      "normal"
   when newExc then
      "newExc"
   else
      "else"
   end;
   try
      raise newExc end
      "normal"
   when newExc then
      "newExc"
      reraise
   end;
   if true then "then" else raise newExc  end end;
   if false then "then" else raise newExc end end;

Recursive values

a) Recursive functions:

   let rec fac(n :Int) :Int =
      if n == 0 then 0
      elsif n == 1 then 1
      else n * fac(n-1)
      end;
   fac(0);
   fac(1);
   fac(6);
   let rec even(x :Int) :Bool =
      if x == 0 then true else odd(x-1) end
   and odd(x :Int) :Bool =
      if x == 0 then false else even(x-1) end;
   even(2);
   odd(2);
b) Recursive tuples:

   let rec lonelyJohn =
      tuple
         let name = "John"
         let bestFriend = lonelyJohn
      end;
   Let Rec Person <:Ok = Tuple
                            name :String
                            bestFriend :Person
                         end;
   let rec lonelyJohn :Person =
      tuple
         let name = "John"
         let bestFriend = lonelyJohn
      end;
   lonelyJohn.bestFriend.name;
   let rec john :Person =
      tuple
         let name = "John"
         let bestFriend = mary
      end
   and mary :Person =
      tuple
         let name = "Mary"
         let bestFriend = john
      end;
   john.bestFriend.bestFriend.name;
c) Recursive variant tuples:

   Let Rec IntList <:Ok = 
      Tuple
      case nil
      case cons with head :Int  tail :IntList
      end;
   let nil = tuple_case nil of IntList end;
   let single = 
      tuple_case cons of IntList with
         let head = 100
         let tail = nil
      end;
   single!cons.tail?cons;
   let rec ring :IntList = 
      tuple_case cons of IntList with
         let head = 99
         let tail = ring
      end;
   ring!cons.tail?cons;

Persistence

   let name = "John";
   do exit;
   tycoon -restart
   name;
   let name = "John";
   do saveSystem;
   let name = "Mary";
   do exit;
   tycoon -restart
   name;

Ulrike Steffens; updated by Gerald Schröder 27-MAR-1996