Format/2-3 and term write depth

From Permion’s XVM Prolog implementation. We extended the format/2-3 predicates to allow specifying the term write depth. This extension is compatible with the de facto standard definition of these predicates. From the XVM Handbook:

~k or ~Nk term

term is printed with write_canonical/1 with optional depth set to N

~q or ~Nq term

term is printed with writeq/1 with optional depth set to N

~w or ~Nw term

term is printed with write/1 with optional depth set to N

We are wondering if other systems find this extension worthwhile and consider implementing it.

ECLiPSe has always supported this, although we only have a rudimentary format/2,3 in lib(format) that maps to our printf/2,3 built-in.
In addition, a number of modifier characters are allowed before the w to control most other write_term options, see comparison table here.

I suppose we would first have to propose a PIP to describe de-facto format/2,3 at all!

I think a PIP on format/1,2,3 would be good. The various implementations share a good deal of functionality, but there are also a number of unnecessary differences. SWI-Prolog has ~W, which takes two arguments: the term and the options. So, you use e.g.,

format('~W', [Term, [max_depth(10)]]).

Note that most systems support ~@, so you can also use

format('~@', [write_term(Term, [max_depth(10)])]).

I agree, this would make a good PIP!

A starting point can be the format/2-3 tests found in the Logtalk distribution. they are based in the de facto standard for these predicates:

The main specification issue where implementations differ is the format of the error when control string and the list of arguments is not consistent (e.g. too few or too many arguments). In the tests that check for these errors, an ISO exception is used. But this is not a good choice as we are dealing with consistency errors that are not covered by ISO.

My idea here is to make a separate proposal for a consitency_error/3 based on:

https://logtalk.org/manuals/refman/methods/consistency_error_3.html

This exception term is useful in other contexts and is inspired by the standard domain_error/2 in that the first argument informs of what’s wrong.

1 Like

I’m all in favour. Just, SICStus does this, i.e., consistency_error(+Arg1, +Arg2, +Type).

?- catch(format('~w', [aap, noot]), E, true).
E = error(consistency_error('~w',user:[aap,noot],format_arguments),consistency_error(format('~w',user:[aap,noot]),'~w',user:[aap,noot],format_arguments)) ?

edit Checked some more:

  • yap has just consistency_error(Who), using the 2nd arg of error for the context
  • scryer and traella do not have it.
  • SWI, ciao, and xsb do not have it

That needs to be resolved. I’m also tempted to argue for

 consistency_error(+Type, +Args)

where Args is a list. After all, at least in theory more than two arguments may be involved.

@herme, you can move these posts to a new thread.

I was aware of SICStus version of the consistency error and ultimately decided against it when I added the definition above to Logtalk, which is arguably more consistent with the existing ISO exception terms: type error first argument is the type, domain error first argument is the domain, and consistency error is the consistency condition/check.

I don’t see the point of caring for more than two arguments being inconsistent. When checking, an implementation most likely will throw an error as soon as it finds two inconsistent arguments.

1 Like

I agree that Logtalk’s version is more in line with ISO than SICStus’s. But since we now have this unfortunate inconsistency (pun intended) for consistency_error/3, I’d suggest to adopt @JanWielemaker’s proposal to use consistency_error/2. Systems that already use consistency_error/3 can implement both (obligatory xkcd).

Well, SICStus may, just may, be wiling to change. I think consistency in the design standard exceptions is more important than the conflict here with a single system. Elegance should not be optional. From my experience with standardization, there will always be this kind of conflicts in most systems as their implementers feel strong about something that others collectively disagree. No accepting that as a facto of life have killed many convergence attempts in the past.

The consistency error seems reasonable, but I have to say that the ISO error specification is elegant, but in my opinion out of date. I really prefer the basically hierarchical approach of Python and even … Java … (ugh, let me compose myself).

There’s a lot of thinking to be done about error classes. One probably insoluble problem is ISO incompatibility. I really want to be ISO compatible whenever possible, but once in a while ISO is a fetter that keeps back Prolog and contributes to the myth that Prolog is not a “modern” language. I think that error handling is one of these cases.

Could we agree on a taxonomy of errors, and have an alternate catch that checks for inheritance? This would be slightly slower than regular catch and perhaps not suitable for every application but I think it would help out Prolog in complex applications where a good model for errors is important for resiliency and diagnosis.

I figured I’d “throw” these ideas out,