tau-prolog: Missing de facto standard format/2-3 predicates

Would be possible to add the de facto standard format/2-3 predicates? Any (relatively) easy way for lifting the required functionality from an existing JS library?

For sample calls and tests, please see: https://github.com/LogtalkDotOrg/logtalk3/blob/master/tests/prolog/predicates/format_2/tests.lgt https://github.com/LogtalkDotOrg/logtalk3/blob/master/tests/prolog/predicates/format_3/tests.lgt

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 26 (9 by maintainers)

Commits related to this issue

Most upvoted comments

The default value for double_quotes in Tau Prolog is codes. The ISO/IEC 13211-1 leaves the default value to the implementation, so I relied on the default value of SWI (that now is string) and GNU Prolog. But the decision was totally arbitrary, I would have no problem changing it.

Thank you very much for your interest! format.pl is available from:

https://github.com/mthom/scryer-prolog/blob/master/src/lib/format.pl

It would be awesome if you could integrate it in Tau Prolog too, this is a great opportunity for collaboration between two Prolog systems that are very conforming to the ISO standard and hence allow easy porting of applications and libraries. It is especially fortunate that both systems have taken the bold step to set double_quotes to chars by default, a setting which I strongly encourage and which format.pl also assumes.

If possible, please make the non-terminal format_//2 from this library also available in Tau Prolog: I have found format_//2 to be a really useful building block to format lists of characters, and to declaratively describe output so that it can actually be reasoned about in test cases instead of appearing only on the screen.

The library also provides listing/1 and portray_clause/1, which I hope you also find useful for Tau Prolog. I often use portray_clause/1 when emitting solutions to generate output that can later be read with read/1 for convenient testing and reasoning.

Please let me know if you need anything specific to use the library: Ideally, porting it should amount to maybe changing a few directives, and changing the two occurrences of “Scryer” to “Tau”.

Added. Thank you very much to both!

It seems that format/3 is missing from https://github.com/tau-prolog/tau-prolog/commit/f1bf25b965044d1566338044d06c36c94bec9d6c? It can easily be added as:

format(Stream, Fs, Args) :-
        phrase(format_(Fs, Args), Cs),
        maplist(write(Stream), Cs).

Yes, well spotted! In Scryer Prolog, I have consciously chosen not to support an atom as the first argument: First, as you say, an atom inflates the atom table, and should be avoided unless one really needs it for indexing. A second reason are security concerns I think about when using atoms: The atoms that occurred while running a program leave more traces in the system state than lists, and one sometimes does not want to leave a trace of what was processed. As a general rule for using atoms vs. strings, I think the more ephemeral the data is used, the better it is to use lists of characters instead of atoms. Since in this case, the format string is only used once, lists are a very good fit, and make it easy to process the argument in the library.

For me, an even better reason to support only double quoted strings is to encourage better support for this feature also in other Prolog systems: There are ways to implement lists of characters very efficiently, they only have not yet caught on. My hope is that over time, we will eventually be able to use Prolog for the use case it was designed for: Efficient and convenient processing of text. This will only happen with bold steps as the ones taken by Scryer and Tau, by committing to lists of characters once and for all, and then implementing that efficiently. I would like to promote the use of lists of characters for this reason already: To encourage implementors to make this efficient.

Btw, Markus @triska wrote a nice Prolog implementation of the format/2-3 predicates for Scryer Prolog. If he would be willing to contribute it to Tau-Prolog, it could be an alternative to a native JS implementation.

I think the best option is to create a new project with npm (npm init), install the latest version of Tau Prolog in that project (npm install tau-prolog), and replace the files in node_modules/tau-prolog.

Then you should be able to import Tau Prolog and its modules in the following way:

var pl = require("tau-prolog");
require("tau-prolog/modules/os")(pl);
require("tau-prolog/modules/lists")(pl);
require("tau-prolog/modules/random")(pl);
require("tau-prolog/modules/format")(pl);
require("tau-prolog/modules/statistics")(pl);

Note that there may be problems in the new version v0.3.0 due to the new module system, since I am still working on it.

This is the most futuristic commit I have seen in a while. Thank you a lot!

Yes, I also think it’s more natural to see a string as a list of characters. Big Haskell fan!

I understand and sympathize with your view. But you’re not requiring only support for chars. You’re effectively forcing the use of chars even if the flag supports the other standard settings.

That means that any existing program using a different setting (e.g. codes) cannot call the format/2-3 predicates until is rewritten.

Yes, exactly: This consideration is the key motivation for this design. I want to encourage application programmers to make one final change to their code: Move from codes to characters. This is the last time they need to do this, since all future Prolog systems will use characters by default. Scryer demonstrates how this can be implemented efficiently, using a compact internal representation.

Okay. It’s a problem with my foldl/4 implementation. The accumulator is on the wrong side! 😮 Now everything seems to be working properly. The rest is a piece of cake, just add a couple of predicates to Tau Prolog. Thank you again!

I publish the Tau Prolog packages as predicates directly compiled into JavaScript, rather than as Prolog text. So if you like, I could add your copyright header in the package next to a link to the original Prolog source.

@triska Looking at the code of format.pl, there is format/2 but not format/3. Easy to add, of course:

format(Stream, Fs, Args) :-
        phrase(format_(Fs, Args), Cs),
        maplist(write(Stream), Cs).

Also, format/2 only accepts (as first argument) a double-quoted term, correct? Other Prolog system implementations also accept an atom. I can submit a pull request to fix both omissions. But I’m wondering if there’s some design decision here. Accepting an atom works around the portability mess of double-quoted terms (with the downside of inflating the atom table).

P.S. Great to see the cooperation between Tau-Prolog and Scryer Prolog developers!

Btw, Markus wrote a nice Prolog implementation of the format/2-3 predicates for Scryer Prolog. If he would be willing to contribute it to Tau-Prolog, it could be an alternative to a native JS implementation.

That sounds really interesting. @triska It would be a great help!