What type is a single quoted string?

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