33.7 Syntactic Sugar

There is a package that transforms programs and queries from an eval-quote variant of clp(Q,R) into corresponding programs and queries in a quote-eval variant. Before you use it, you need to know that in an eval-quote language, all symbols are interpreted unless explicitly quoted. This means that interpreted terms cannot be manipulated syntactically directly. Meta-programming in a CLP context by definition manipulates interpreted terms, therefore you need quote/1 (just as in LISP) and some means to put syntactical terms back to their interpreted life: {}/1.

In a quote-eval language, meta-programming is (pragmatically) simpler because everything is implicitly quoted until explicitly evaluated. On the other hand, now object programming suffers from the dual inconvenience.

We chose to make our version of clp(Q,R) of the quote-eval type because this matches the intended use of the already existing boolean solver of SICStus. In order to keep the users of the eval-quote variant happy, we provide a source transformation package. It is activated via:

     | ?- use_module(library('clpqr/expand')).
     | ?- expand.

expand/0 puts you in a mode where the arithmetic functors like +/2, */2 and all numbers (functors of arity 0) are interpreted semantically. noexpand/0 gets you out of the mode.

     clp(r) ?- 2+2=X.
     
     X = 4.0

The package works by purifying programs and queries in the sense that all references to interpreted terms are made explicit. The above query is expanded prior to evaluation into:

     {2.0+2.0=X}

The same mechanism applies when interpreted terms are nested deeper:

     some_predicate(10, f(A+B/2), 2*cos(A))

Expands into:

     {Xc=2.0*cos(A)},
     {Xb=A+B/2},
     {Xa=10.0},
     some_predicate(Xa, f(Xb), Xc)

This process also applies when files are consulted or compiled. In fact, this is the only situation where expansion can be applied with relative safety. To see this, consider what happens when the top-level evaluates the expansion, namely some calls to the clp(Q,R) solver, followed by the call of the purified query. As we learned in Feedback, the solver may bind variables, which produces a goal with interpreted terms in it (numbers), which leads to another stage of expansion, and so on.

We recommend that you only turn on expansion temporarily while consulting or compiling files needing expansion with expand/0 and noexpand/0.