Pragmas are used to pass a wide variety of information in to the system.
They are visually separated by begining with :-
.
Some pragmas alter the syntax of the language.
.. index:: double: pragma; disposition
In Dyna source code, there are two different things that the term f(1,2)
could mean:
- Construct the piece of data whose functor is
f
and has arguments1
and2
, as inf(A,B) = f(1,2)
, which unifiesA
with1
andB
with2
. - Compute the value of the
f(1,2)
item, as inf(1,2) + 3
orY is f(1,2)
.
It is always possible to explicitly specify which meaning to use, by use of
the &
and *
operators (see :ref:`syntax-quote-eval`), but this would
be tedious if it were the only solution. As such, we endow functors (of
given arity) with dispositions, which indicate, by default, how they would
like to treat their arguments.
Dispositions are specified with the :-dispos
pragma, thus:
:-dispos g(&). % g quotes its argument. :-dispos '+'(*,*). % + evaluates both arguments.
Now g(f(1,2)) + 1
will pass the structure f(1,2)
to the g
function and add 1
to the result. Note that dispositions take effect
while the program is being parsed. That is, a program like:
:-dispos f(&). goal += f(g(1)). :-dispos f(*). goal += f(g(2)).
specifies that goal
has two antecedents: the f
images of g(1)
and the g
image of 2
.
It is also possible to indicate that some terms should not be evaluated:
:-dispos &pair(*,*). % pair suppresses its own evaluation
In the case of disagreements, like pair(1,2) + pair(3,4)
, the preference
of the argument is honored.
Defaults
Absent any declarations, all functors are predisposed to evaluate their
arguments. Some functors (pair/2
, true/0
, and false/0
)
suppress their own evaluation.
Warning
This section is probably relevant only if you are a developer of the Dyna compiler.
Just like it is possible to request that some functors not be evaluated even when in evaluation context, it is additionally possible for functors to request that they be evaluated even when the context is one of quotation:
:-dispos *f(*).
The neutral position of specifying neither &
nor *
before a pragma
is termed inherit, which means that the context or overrides apply. Under
the defaults above, this is the default position for all functors.
It is possible to override the defaults, as well; at least one of us has a stylistic preference for a more Prolog-styled structure-centric view of the universe. The pragma:
:-dispos_def prologish.
will cause subsequent rules to behave as if all functors which start with an
alphanumeric character had had :-dispos f(&,...,&)
asserted, while all
other functors had had :-dispos *f(*,...,*)
. There are, however, a few
built-in overrides to this rule of thumb, giving alphabetic mathematical
operators (e.g. abs
, exp
, ...) their functional meaning. See
:dynasrc:`src/Dyna/Term/SurfaceSyntax.hs`
The default default rules may be brought back in by either:
:-dispos_def dyna. :-dispos_def.
Note that when chaning defaults, any manually-speficied :-dispos
pragmas remain in effect.
.. index:: double: pragma; operator
Dyna aims to have a rather flexible surface syntax; part of that goal is achieved by allowing the user to specify their own operators.
As with :ref:`pragma_disposition`, these pragmas take effect while the program is being parsed.
bug
The ability to add and remove operators is not yet actually supported.
The :-oper add
pragma takes three arguments: the fixity, priority, and
lexeme that makes up the operator. Fixities are specified as pre
,
post
or in
. In the case of in
, one of left
, right
, or
non
must be specified for the associativity. Priorities are natural
numbers, with higher numbers binding tighter. Lexemes are either bare words
or singly-quoted functors.
Examples:
:-oper add in left 6 + . :-oper add pre 9 - .
The :-oper del
pragma may be used to remove all previously added forms
of a given operator.
The default operator table is, hopefully, more or less what you might expect and follows the usual rules of arithmetic.
bug
For the moment, the source is the spec. See the source in :dynasrc:`src/Dyna/Term/SurfaceSyntax.hs` for full details.
On the other hand, some pragmas impact the execution of the system.
.. index:: double: pragma; inst double: pragma; mode
Following the [MercuryLang]_ syntax, we allow the user to give names to instantiation states and modes:
:-inst name(args) == ... . :-inst mode(args) == ... >> ... .
.. index:: double: pragma; query mode single: qmode
A Query mode specifies that a particular backward-chaining operation is to be available to the system. These capture the change in instantiation state, determinism, and other properties of a query.