3 ms·
To be more precise, most Prologs before the last 5 years have built-in predicates that break _atoms_ up into either character codes, or characters. "String" as
by YeGoblynQueenne 5y ago
To be more precise, most Prologs before the last 5 years have built-in predicates that break _atoms_ up into either character codes, or characters. "String" as a datatype is the novelty of the new generation of Prologs.
For instance, here's Sicstus
| ?- atom_codes('abcd', Cs).
Cs = [97,98,99,100] ? ;
no
| ?- atom_chars('abcd', Cs).
Cs = [a,b,c,d] ? ;
no
| ?-
Personally, I'm kind of ambivalent about this new direction. "String" is a programming language concept, but not a FOL concept. "Atom" is a FOL concept- but Prolog mangles the clean and tidy FOL (and Logic Programming) nomenclature and calls "atom" everything that should really be called a _constant_, and calls what should really be called an "atom", a "term". Then it's all downhill from there.
The ideal for me would be to redress the wrong of confusing terminological swaps in Prolog jargon (atom--> constant, term--> bloody everything, predicate--> program, functor--> symbol, etc) and leave the details of the implementation (whether to represent constants as lists of characters or codes, and whether to define built-ins that operate on them) to the implementor.
For me, Prolog's Logic Programming roots are the only thing that makes sense and helps understand Prolog. The turn towards programming language semantics and sometimes database semantics, has only served to make a mess of things. I blame it for the notorious difficulty that most programmers face in trying to pick up Prolog, which is seriously incommensurate to the brilliant simplicity of FOL and LP syntax and semantics.
- dallasg3 5y agoI didn't know FOL stood for First-Order Logic.
- YeGoblynQueenne 5y agoOh, sorry, you're absolutely right. I should have explained the acronym before using it.
- jhgb 5y ago> "Atom" is a FOL concept- but Prolog mangles the clean and tidy FOL (and Logic Programming) nomenclature and calls "atom" everything that should really be called a _constant_, and calls what should really be called an "atom", a "term". It almost seems like they got all this confusion from badly copying Lisp. What you refer to above is clearly ancient (pre-Common) Lisp's EXPLODE and IMPLODE operators (https://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/part2/faq-doc-3.html https://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/part2/f...). Of course Lisp's symbols are Prolog's atoms, and Lisp's atoms are Prolog's terms.
- YeGoblynQueenne 5y agoWell I confess I don't know LISP nearly as well as Prolog, but they were both languages that came out of a certain tradition of research in FOL and how to calculate it with computers. There was bound to be some overlap. I remember noticing the thing about LISP atoms and symbols etc. and I thought that's probably it.
- triska 5y agoIn SICStus Prolog, the query I showed yields C = 108 by default, because "Hello, world!" is interpreted as the list of character codes [72,101,108,...]. In contrast, in all the recent systems I mentioned, the double-quoted string "Hello, world!" is interpreted as the list of atoms of length one ['H',e,l,l,o,...]. This is preferable because it is more readable, and also because reasoning about such atoms in Prolog programs does not depend on any system-specific character encoding. In all ISO conforming systems, we can switch between these two interpretations of double-quoted strings by setting the Prolog flag double_quotes to codes and chars, respectively. The interesting phenomenon I mentioned is that both the earliest and the most recent Prolog systems acted as if this flag (which was not available yet in the first Prolog systems) was set to chars, interrupted by a number of years where it was set to a different default value in the Edinburgh tradition of Prolog systems. It is interesting because the newest Prolog systems follow the Marseille tradition in this respect, which precedes the Edinburgh tradition. Prolog does not have a native "string" type, neither SICStus nor the other systems I mentioned have it, because such a type does not fit into the language. Still, we often call a list of characters a string, much like we call a char array a string in C, even though C does not have a native string type either. One can force an ISO conforming Prolog system to interpret double-quoted strings as atoms, i.e., to interpret "Hello, world!" as the atom 'Hello, world!', by setting the flag to the value atom. It is preferable to set it to chars though, because this allows the application of DCGs for reasoning about strings.
- YeGoblynQueenne 5y agoThanks. Prolog doesn't have a native string type- indeed. And so atoms must be converted into lists. That's were trouble begins, I fear. Split the atom, and what do you get? Fallout. I'll get my coat.
- triska 5y agoI would phrase it like this: If you are using, in Prolog code, an atom of length greater than 1, then consider using a list of characters instead, especially if you want to reason about the data itself within your program. If you use lists of characters throughout, then no conversion to or from longer atoms is needed. For example, in the sample queries you posted, instead of the atom abcd, consider using the list of characters "abcd" (i.e., [a,b,c,d]) instead, because such lists of characters can be readily described and analyzed with DCGs. In addition to this convenience, as a secondary concern, lists of characters provide an efficiency advantage, because they can be more transiently allocated on the Prolog heap instead of in the atom table, and are therefore immediately reclaimed on backtracking. Characters, i.e., 1-char atoms, are indeed a good use case of atoms. For anything longer, lists of characters are in many cases a better option: In addition to their being amenable to reasoning with DCGs and the mentioned efficiency advantage, they also allow partial instantiations, such as [a,b,c|Ls] and [a,B,c,d], a feature that atoms do not support. Hence, when using atoms, the code tends to become more moded, whereas lists of characters readily allow generalizations. Existing and upcoming Prolog implementation techniques allow a very compact internal representation of lists of characters as packed UTF-8 encoded sequences of bytes, and also a very efficient representation of each character as a single heap cell. Scryer Prolog and Trealla Prolog are the first Prolog systems that provide such an efficient internal representation of lists of characters, and are therefore already especially useful for efficient text processing.