Definitely an interesting read! I have a few comments about the following paragraph specifically, because the potential of convenient string processing is so essential to logic programming:<p><i>"As in Prolog, strings are lists of character codes which makes them
automatically suitable for stream processing. Apart from avoiding the
tedious duplication of list and string manipulation operations, this
allows for efficient, asynchronous handling of streams of characters,
so the extra space needed for lists is partially balanced by manipulating
them in a lazy manner, one piece at a time, by communicating processes."</i><p>In Prolog, the meaning of double-quoted strings depends on the value of the Prolog flag double_quotes. Only if it is set to the value <i>codes</i> are double-quoted strings interpreted as lists of codes. However, a much better setting is the value <i>chars</i>, and then double-quoted strings are interpreted as lists of 1-char <i>atoms</i>. For example, with this setting, we have:<p><pre><code> ?- "abc" = [a|Ls].
Ls = "bc".
</code></pre>
This is the default value in all of the three newest Prolog systems: Scryer Prolog, Tau Prolog and Trealla Prolog. It was also the original interpretation of strings in the very first Prolog systems, Prolog 0 and Marseille Prolog, which were designed for natural language processing. Lists of characters ensure that strings are very readable, also when emitted in their canonical representation. For example, Scryer Prolog yields:<p><pre><code> ?- write_canonical("abc").
'.'(a,'.'(b,'.'(c,[]))) true.
</code></pre>
The mentioned advantage of "avoiding the tedious duplication of list and string manipulation operations" in this way can hardly be overstated: It is massive, because everything one knows about lists carries over directly to strings, including common predicates such as append/3, length/2 and reverse/2 which even beginning Prolog programmers universally know, and the ability to <i>generalize</i> arbitrary elements by using logic variables at desired positions, obtaining partially instantiated terms such as "all strings of length 3" which can be specified symbolically as [_,_,_]. In addition, lists are especially conveniently reasoned about with Prolog's built-in grammar mechanism, definite clause grammars (DCGs), tailor-made for generating and parsing sequences and therefore also strings. And further, "the extra space needed for lists" can be avoided with a compact internal representation of lists of characters, i.e., encoding them as sequences of raw bytes, using UTF-8 encoding. This efficient representation is currently already implemented in Scryer Prolog and Trealla Prolog.