What type is a single quoted string?

I’m using: SWI-Prolog version 8.1.9.

What type is a element that is contained in single quoted strings? The string/1 predicate does not regard it as a string yet it appears to “act” like one?

What are the benefits/drawbacks of single quoted strings vs double quoted strings?

Side question: Is there a predicate that tells you what type a ground variable contains?

2 Likes

are atoms, possibly containing ‘special’ characters like those used to shape operators or variables.

Backward (ISO) compatibility / Efficiency.
Double quoted strings were translated to list of character codes, clearly a costly operation.

3 Likes

It is an atom.

I think the reason for that is that Jan W has been putting quite a bit of effort (in the form of code) to make it so. For example, if you take a look at the implementation of term_string, you’ll see it uses read_term_from_atom and this takes atoms or “string objects”, which is either a string OR a list of codes. See:

$ swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.11-36-g77d225875)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit http://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- term_string(T, 'foo(bar)').
T = foo(bar).

?- term_string(T, "foo(bar)").
T = foo(bar).

?- term_string(T, `foo(bar)`).
T = foo(bar).

It’s magic! :wink:

This is explained in some detail in the “Strings” section of the manual: SWI-Prolog -- library(strings): String utilities

Speculation: I don’t think there is, so either I don’t know about it, or maybe it is not too useful if you consider the bigger picture. One of the heavyweights would have to answer this question. Keep in mind that even a ground variable can be more than one “type” at once:

?- atom(foo).
true.

?- atomic(foo).
true.

?- number(2.1).
true.

?- float(2.1).
true.

There is some hierarchy to it, but it isn’t formalized.

3 Likes

As many have noted it is an atom, but to add some clarification for others new to Prolog reading this, 'Hello' is an atom even though it starts with an upper case letter which would by default make it a variable. The use of '' to bookend a sequence of characters makes it an atom.

However be aware of the closely looking back-quoted sequence of characters, `Hello` which is a code list in version of SWI-Prolog starting with version 7.x.


This is actually not a valid question because a single quoted string is actually a sequence of characters book-ended by single quotes which is an atom and a double quoted string, which is actually a sequence of characters book-ended by double quotes is a string.

To split hairs even more, I don’t think of them as characters but as glyphs, e.g.

?- atom(∎).
true.

?- atom(☃).
true.

A more useful question is:

What are the benefits/drawbacks of atoms vs strings vs code list?

See: Representing text: strings, atoms and code lists


Another useful question when using SWI-Prolog starting with version 7.x is

What are the benefits/drawbacks of double-quoted strings vs back-quoted strings?

In a practical sense with SWI-Prolog starting with version 7.x

See: The string type and its double quoted syntax

When using DCGs, one can process the data in different ways such as atoms or code lists. Now if using DCGs to parse input text and using SWI-Prolog library basics.pl one must note:

This library provides various commonly used DCG primitives acting on list of character codes.

NB The library works on code lists and not strings.

So when you look at DCG examples parsing input text you have to reason if the code is parsing the input as atoms, (typically done with NLP and other structure deconstruction and analysis) or as codes (typically done with data or source code parsers).

Now standard ISO Prolog will convert "" to a code list but SWI-Prolog starting with version 7.x will convert "" to a string. This means that if you copy and paste DCG examples expecting "" to be converted to a code list with SWI-Prolog starting with version 7.x it could fail (especially if the code uses basics.pl expecting code list). However SWI-Prolog has some Prolog flags that can override the meaning of "" and ``, e.g.

:- set_prolog_flag(double_quotes, codes).
:- set_prolog_flag(back_quotes, string).

Now if you are like me and like to use unit testing, it must be remembered that

:- begin_tests(xyz).
...
:- end_tests(xyz).

is actually a separate module with in the same code and thus the Prolog flags set in the code are not active in the test module, so the use of set_prolog_flag/2 is also required in the test module.

Took me many months to realize all of that.


Another item of note is that when debugging DCGs as list of codes and using the GUI debugger (gtrace), by default both strings and list of codes are represented as strings in the display, e.g. "today". By examining the value it can be determined if it is a string or a code list, but this does rely on interacting with the debugger for each variable each time. portray/1 might be able to resolve this but haven’t used portray/1 as I do this so rarely.


AFAIK there is no one single predicate that does this; there are times I am tempted to write it, but am pretty sure it would have to be written in C and not Prolog for SWI-Prolog. Even if the predicate did exist for a term, the problem of compound terms comes into play and how do you display the type of a compound term and then also deal with homogeneous and heterogeneous compound types. In a way this reminds me of Python with duck typing and a similar problem I had.

See:
Verify Type of a Term
error.pl – Error generating support
Wiki: Bug hunting toolbox

?- var(Hello).
true.

?- ground(Hello).
false.

?- atom('Hello').
true.

?- ground('Hello').
true.

?- string("Hello").
true.

?- ground("Hello").
true.

?- compound(`Hello`).
true.

?- acyclic_term(`Hello`).
true.

?- ground(`Hello`).
true.

?- must_be(atom,'Hello').
true.

?- must_be(list,`Hello`).
true.

?- must_be(string,"Hello").
true.

Another aspect of these types that should be covered is how are they represented.

?- write_canonical('Hello').
'Hello'
true.

?- write_canonical("Hello").
"Hello"
true.

?- write_canonical(`Hello`).
[72,101,108,108,111]
true.

?- set_prolog_flag(double_quotes,codes).
true.

?- write_canonical("Hello").
[72,101,108,108,111]
true.

?- set_prolog_flag(back_quotes,string).
true.

?- write_canonical(`Hello`).
`Hello`
true.

Also see:

Character Escape Syntax
What is the difference between ’ and " in Prolog?
format/3 and with_output_to/2

2 Likes

Thanks everyone! I love it when a question leads to a suite of quality answers that comprise an ad hoc Wiki page. :slight_smile:

Please make a wiki page for this; it really is one of the best ways to learn as it will force you to think about and research what you write and help others learning about Prolog. This case is especially important for those using SWI-Prolog starting with version 7.x and using DCGs.

If you need help with site admin functions such as converting a topic to a wiki I’ll be happy to help. :slightly_smiling_face:

1 Like