Swap

This example illustrates three of LARD's more interesting features: classes, polymorphism and implicit parameters.

Classes

In lard the class of something is what "kind" of thing it is. It doesn't have much in common with the use of the same term in object-oriented languages. One aspect of the class of something is often its type, but this is only part of it. Here are some of the classes:

Var Parameters

The parameters to the gcd function in the last example were of class val(int), indicating that they took values of type int. It is often useful to have parameters of other classes. Here is a function that swaps its two parameters:

	swap(x:var(int),y:var(int)):expr(void)=(
	  tmp:var(int).
	
	  tmp:=x;
	  x:=y;
	  y:=tmp
	).
A couple of points to note: It would be better if the function were capable of swaping variables of any type. The following examples show how LARD allows this.

Type Parameters

LARD allows parameters to have the class type, and this can help make the code more generic:
	swap(T:type,x:var(T),y:var(T)):expr(void)=(
	  tmp:var(T).
	
	  tmp:=x;
	  x:=y;
	  y:=tmp
	).
This version of the code takes an additional parameter T which indicates the type of the variables to be swapped. T is then used as the type in the declarations of x, y and tmp. This version of swap would be called as follows:
	swap(int,foo,foo2)
or
	swap(bool,cond,xxx)

Implicit Parameters

Although this code allows variables of any type to be swapped it is a little awkward to have to specify the type each time. To make things easier LARD has a feature called implicit parameters. All the parameters used so far are explicit parameters, that is they are all listed explicitly in the declaration of the function and in the call. An implicit parameter on the other hand appears in the declaration but does not appear in the call. Here's how swap can be written using implicit parameters:
	swap(x:var(T:type),y:var(T)):expr(void)=(
	  tmp:var(T).
	
	  tmp:=x;
	  x:=y;
	  y:=tmp
	).
The function still has three parameters, x, y, and T, but T is now an implicit parameter within the class of x. This can now be called without the need for an explicit type parameter:
	swap(foo,sprocket)
Note that x and y are still constrained to have the same type. If you wanted to allow x and y to have different types you would need two implicit parameters:
	foo(x:var(Tx:type),y:var(Ty:type)):expr(void)=(...
This mechanism is used extensively to implement polymorphic functions in the standard library. Examples include the assignment function :=, the array indexing function _[_], and the channel communication functions. These are all described in later examples.