Subject: bug#21526: 24.5; prolog-mode: broken indentation for if-then-else construct

From: Markus Triska <[email-masked]>
Date: Wed, 30 Sep 2015 20:35:40 +0200

Stefan Monnier <[email-masked]> writes:

> I don't understand.  You say you want
>
>     :- multifile
>            pred1,
>            pred2,
>            pred3.

Yes, exactly. The most frequent such directives are:

    discontiguous dynamic meta_predicate module_transparent multifile 

Their unary argument is always a valid Prolog term itself, and the whole
directive is, like everything that appears in a Prolog file (except
comments), also a valid Prolog term, and ends with a '.'.

As a good approximation, you can expect these directives to have the
form:

   :- <keyword> pred1,
           pred2,
           ...,
           pred_n.

Where pred_k is a predicate indicator of the form Name/Arity, where
Name is a Prolog atom and Arity is an integer.

The atom may of course also contain a '.', for example, the directive
may look like:

   :- multifile 'unusual.predicate'/1.

This situation is very rare, but at least it should not produce errors.

> whereas clearly you'd like
>
>        multifile
>            (pred1,
>            pred2,
>            pred3)

Yes, this is because of the built-in precedences: multifile has
precedence 1150, and thus (,)/2 with arity 1000 binds more tightly.

> what should happen if "multifile" appears elsewhere?  what other keyword
> can appear where you have "multifile" and do they all use this
> same syntax?

The term above is just like any other Prolog term, so if multifile
appears elsewhere then, from a purely semantic point of view, I would
expect it to also indent just according to the structure of the
resulting Prolog term. However, not even Stefan Bruda's mode goes so far
as to ensure this kind of semantic indentation. For example, from a
purely semantic view, in the following example, the atom 'x' is an
argument of the operator multifile:

   test :-
           multifile
                   x.

However, as a first approximation, it would already be great to handle
this indentation of multifile just in directives (= lines where (:-)/1
is the primary functor). This is also what Stefan Bruda's mode does.

The same goes for the other keywords shown above.

The ability to define custom operators makes Prolog code harder to parse
and indent semantically than other languages. If you are interested in
truly pushing this to its ultimate conclusion, you will have to
dynamically take operator precedences into account, using Prolog's
current_op/3 predicate to look up the current precedences.

Independently of all this, would you please consider to set the default
value of prolog-electric-if-then-else-flag to t in Emacs? I find this
behaviour extremely useful, and other modes like C also have electric
indentation turned on by default in recent Emacs versions.

Thank you and all the best!
Markus