Re: term_expansion/2 with DCG clauses

Michael Hendricks <[email protected]>
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <CAFHuXuYSZB14ePUJWMO1M4k+SUuKPSEv09tF3gry+mPF9CSMfg@mail.gmail.com>
On Thu, Aug 15, 2013 at 4:43 AM, Paulo Moura <[email protected]> wrote:

> As Richard would wrote, "An example would be handy about now." :-)
>

Good idea.  These conversations are always more productive when based
around something concrete.


> Assume that you have three expansions that should occur in a fixed order:
>
>         A -> B -> C
>
> ...
> Can you show us exactly how you would do the same (fixed order expansions)
> under recursive expansion?


If A, B and C macro terms don't unify with each other, then recursive
expansion gives the proper order by default.  My experience suggests this
is the most common scenario.  This works with goal_expansion today:

    goal_expansion(c, zap).  % C
    goal_expansion(a, b).  % A
    goal_expansion(b, c).  % B


If A, B and C do unify with each other but they don't pollute the global
user:term_expansion/2 predicate, one can do it the same as your Logtalk
example. It behaves the same under recursive or first-solution expansion:

    :- use_module(a).
    :- use_module(b).
    :- use_module(c).
    term_expansion(T0, T) :-
        a:term_expansion(T0, T1),
        b:term_expansion(T1, T2),
        c:term_expansion(T2, T).


If A, B and C unify with each other and define global
user:term_expansion/2, then each definition must cooperate to guarantee
order and it gets a little ugly. I believe this is true under both
recursive and first-solution expansion, because multifile predicates don't
guarantee a clause order. (One of several reasons I don't like macro
expansion via global predicates).  In this example, assume that
mark_as_expanded/1 and has_expanded/1 use something like
prolog_load_context(term_position,_) to uniquely identify terms.  Under
recursive expansion it might look like this:

    % A
    user:term_expansion(T0, T) :-
        \+ has_expanded(T0),
        % ... expand T0 into T
        mark_as_expanded(T0).
    % B
    user:term_expansion(T0, T) :-
        a:has_expanded(T0),
        \+ has_expanded(T0),
        % ... expand T0 into T
        mark_as_expanded(T0).
    % C
    user:term_expansion(T0, T) :-
        b:has_expanded(T0),
        \+ has_expanded(T0),
        % ... expand T0 into T
        mark_as_expanded(T0).

Global resources have an unhappy way of requiring this sort of
coordination, it seems.  Modules currently define user:term_expansion/2
because that's the only way to export macros.


A thought that's only tangentially related: The multifile directive
acknowledges that clauses are a meaningful unit of code reuse.
 Unfortunately, multifile creates a single global predicate.  It might be
helpful if modules could export their clauses to augment an existing, local
predicate definition.

-- 
Michael
-------------- next part --------------
HTML attachment scrubbed and removed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.