-
Notifications
You must be signed in to change notification settings - Fork 8
6.7 Data Structures
LispE provides a way to handle data structures through functional data type definition.
A data type in LispE is created with the keyword: data followed with a list of descriptors:
; Basic data types
(data (D1 p1 p2 ...) (D2 p1 p2 ...) (D3 p1 p2...) ...)
; Group of data type identified with 'name'
(data name (D1 p1 p2 ...) (D2 p1 p2 ...) (D3 p1 p2...) ...)
Each descriptor Dd is an atom followed with a list of parameters.
You can optionally add a name to a group of data type definitions.
; Some basic data types
(data (Point _ _) (Circle _ ) (Rectangle _ _) )
; We create a Shape, which is either a Triangle or a Square
(data Shape (Triangle _ _ _) (Square _))
We use '_' as a placeholder when the parameter type is irrelevant.
Note '_' is actually an alias for nil. Hence, you can replace this description with:
(data (Point nil nil) (Circle nil ) (Rectangle nil nil) )
We use '_' as a bit of a tradition in this case.
As a side note, since parentheses are a bit too many in these contexts, you can replace them with []
if you wish. This is also true for pattern functions. Hence, you can replace the above definitions with:
; Some basic data types
(data [Point _ _] [Circle _] [Rectangle _ _] )
; We create a Shape, which is either a Triangle or a Square
(data Shape [Triangle _ _ _] [Square _])
This notation does not change the semantics of these definitions, however it acts as a visual cue and makes the code more readable. Note that if you open with a [
you have to close with a ]
.
The creation of an instance is very simple. You simply implement a list that contains your data type name with its arguments. LispE checks then if the structure matches its definition.
(setq v (Point 10 20))
(setq v (Point 10))
; --> Error: Size mismatch between argument list and data type definition
It is actually possible to put a constraint on the placeholders. LispE already provides the following list of basic types:
- atom_
- data_
- dictionary_
- dictionary_i_
- dictionary_n_
- float_
- floats_
- heap_
- integer_
- integers_
- list_
- llist_
- matrix_
- matrix_float
- number_
- numbers_
- set_
- set_i_
- set_n_
- set_s_
- short_
- shorts_
- string_
- strings_
- tensor_
- tensor_float_
In that case, you can force the arguments to be of a certain type. For instance, you might force Point to only accept integers.
(data [Point integer_ integer_])
If you try to create a data type that does not match, an error will be sent back.
(setq v (Point 10 'test))
; yields: Error: mismatch on data structure argument: 2 (integer_ required)
Of course, you can define nested definitions:
(data [Point _ _] [Circle [Point _ _] _] [Rectangle (Point _ _) _ _] )
which will be again enforced by LispE.