Skip to content

Types and Multiple Dispatching

vczh edited this page Jan 30, 2014 · 3 revisions

Tinymoe can define types.

###Define a Type User defined type is a tuple, with names for each item. For example, we can define a type storing a vector:

type vector
	x
	y
end

x and y are fields of type vector. Name of types and fields can be multiple token.

There are two ways to create an object from type vector:

  • new vector of () create a vector with x and y set to null.
  • new vector of (1, 2) create a vector with x and y set to 1 and 2.

When create an object from a type, you should provide values for all fields, or provide no value to make them all null. You are not allowed to provide only half of those fields.

You can use field x of v to get the x field in v. You can use set field x of v to 10 to modify the x field in v. You can also use v is vector or v is not vector to determine is v an object created from type vector or not.

###Inheritance A user defined type is allowed to derived from another type. If cat derived from animal, that means cat is a subset of animal, and cat automatically contains fields that defined in animal.

type animal
	name
	id
end

type cat : animal
	home address
end

When you create a cat c, both c is cat and c is animal are true, because cat derived from animal. When you create a cat, you should specify 0 or 3 values, because cat has 3 fields, two from animal, one from cat.

If you don't specify a parent type, then it is by default object. So animal derived from object.

###Multiple Dispatching When you have a big tree of type deriving, using <expression> is <type> or <expression> is not <type> will turn your code into garbage. So Tinymoe provide a powerful techniques called Multiple Dispatching. For example, you create types for each shape, and want to provide a function to calcuate areas:

type rectangle
	width
	height
end

type triangle
	a
	b
	c
end

type circle
	radius
end

phrase area of (shape)
	...
end

Sure, you can use if shape is rectangle to determine if shape is a rectangle and apply the right way of area calculating. But when you add more shapes, the code becomes complicated. And to the most important, this is slow in performance. Multiple dispatching is an extensible and fast way to do that:

phrase area of (shape)
	raise "This is not a shape."
end

phrase area of (shape : rectangle)
	set the result to field width of shape * field height of shape
end

phrase area of (shape : triangle)
	set a to field a of shape
	set b to field b of shape
	set c to field c of shape
	set p to (a + b + c) / 2
	set the result to square root of (p * (p - a) * (p - b) * (p - c))
end

phrase area of (shape : circle)
	set r to field radius of shape
	set the result to r * r * 3.14
end

The first function phrase area of (shape) is called the root function of the following three multiple dispatching cases. When all the cases fail, this function is selected. A root function should exist if you want to use multiple dispatching. So if you remove the root function and only keep the three cases, the Tinymoe compiler will not accept your code. Root function is a normal function. That means, if you want to provide cases for an existing function, just begin to use multiple dispatch. You don't need to do any special thing to make a function a root function.

So the following statements:

print area of new rectangle of (3, 4)
print area of new triangle of (3, 4, 5)
print area of new circle of (1)
print area of 1

prints

12
6
3.14

And then crashes because of the exception "This is not a shape." Details about raise can be found in Standard Library: Exception Handling.

All phrases, sentences and blocks can be root functions.

###Multiple Dispatching for Multiple Arguments You can specify types for more than one argument. For example:

phrase (a) and (b) are the same shape
	set the result to false
end

phrase (a : rectangle) and (b : rectangle) are the same shape
	set the result to true
end

phrase (a : triangle) and (b : triangle) are the same shape
	set the result to true
end

phrase (a : circle) and (b : circle) are the same shape
	set the result to true
end

This function can be used to determine if two value are the same shape or not.

###Multiple Dispatching across Modules Multiple dispatch cases can be defined in different module, the only requirement is that, the file containing those cases should be able to access the multiple dispatch root function by correctly specify the using list.