Syntactic sugar for terms
Dyna provides a couple of special notations for terms. These notations are merely syntactic sugar intended to improve readability. They are borrowed from Prolog.
Dyna offers a convenient list syntax. Lists written in the sugared form on the left are syntactically expanded by the compiler into the ordinary terms on the right. (Note:
nil are the traditional LISP names for these list-building operators.)
[one, 2, three] ==> cons(one, cons(2, cons(three, nil)) ["Miller", "Carl"] ==> cons("Miller", cons("Carl", nil)) [singleton(1)] ==> cons(singleton(1), nil)  ==> nil [first | Rest] ==> cons(first, Rest) [first, second | Rest] ==> cons(first, cons(second, Rest))
The last two examples use Prolog's vertical bar syntax. Note that their
expansions do not mention
nil. The variable
Rest would typically be a list itself. Then
[first | Rest] is a new list with
first added to the front.
Type declarations for lists
If your program uses list syntax, then it implicitly uses
nil. So you might wish to give them precise type declarations, for example:
:- structure(cons(int i, list rest)). % specifically a list of ints :- structure(nil).
However, if you omit declarations for
nil, then declaration inference will kick in as usual, and infer declarations that are consistent with your actual usage.
If you have a term called
span, like here:
constit(X, span(I, J)) max= word(Y, span(I, J)) + rewrites(X, Y).
it can be convenient to declare a special operator like in Prolog:
:- operator(400, yfx, ".."). :- cname("..", "span").
Then you can use
.. instead of
span throughout your dyna program:
constit(X, I..J) max= word(Y, I .. J) + rewrites(X, Y).
Such operators can make program code nicer. But do not overuse them since they currently affect the performance of your program. Extensive use in bigger dyna programs can also make the code harder to understand.