Previous: Type declaration, Up: Translating C into L


2.1.1.3 Grammar for types

The grammar for types is quite different from C's one. First, all types information are grouped together; you don't have some that are prefix to the identifier, and some postfix (like * and [] are in C).

Second, the notation for functions is simply <-.

Here are some examples:

C L
int i; let Int i;
int *pi; let Int *pi;
int pi[3]; let Int[3] pi;
int *pi[3]; let Int *[3] pi;
int (*)pi[3]; let Int [3]* pi;
float (*fi)(int); let (Float <- Int)* fi;

2.1.1.4 Type construction and memory allocation

By default when creating a new type, L creates also a new generic constructor, which depends on the created type.

For instance, you must use

     type Kelvin = int;
     
     let degree = Kelvin(24);

to create new Kelvin objects.

When the type is a struct, or a pointer to a struct, the constructor is used as in the following:

     type Point = struct { int x; int y; } *;
     type Point_Struct = struct { int x; int y; };
     
     ...
     
     let p = Point(x:4, y:5);
     let p2 = Point_Struct(x:4, y:5);

The difference between the two is that p2 is allocated on the stack (as a regular C struct), while p is allocated on the heap.

The x: and y: are keys for keyword arguments. The rationale behing using them is that if, later, you change your mind about the structure contents, you will know it immediatly (this wouldn't be the case if you used normal arguments).

In order not to forget this '*', you can use the record type constructor:

     type Point = record { int x; int y; };
     // same as type Point = struct { int x; int y; } *;

In fact, it isn't really the same: record-declared types are by default garbage collected, whereas struct *-declared types must be explicitly freed.

This can be overriddent by the alloc: parameter:

     let p1 = Point(x:4, y:5)
     // Allocated and managed by the most appropriate garbage collector
     
     let p2 = Point(x:4, y:5, alloc:gc) // Same as p1
     
     let p3 = Point(x:4, y:5, alloc:refcount)
     // Same as p1, but explicitly asks for the refcount GC
     
     let p4 = Point(x:4, y:5, alloc:mark_sweep)
     // Same as p1, but explicitly asks for the mark&sweep GC
     
     let p5 = Point(x:4, y:5, alloc:heap) //No garbage collection is done
     
     let p6 = Point(x:4, y:5, alloc:stack) //Allocated on the stack.

By default, all the type fields have to be given as arguments.