library(strings)
defines a set of concatenation functions.
Each of them takes a list of constants as its first argument, and
returns the concatenation of the names of the constants as its second
argument. They are
concat_atom(
+ListOfConstants,
-Atom)
concat_atom(
+ListOfConstants,
Separator,
-Atom)
concat_atom/2
, except that the elements of Atom are separated
by Separator.
concat_chars(
+ListOfConstants,
-Chars)
concat_chars(
+ListOfConstants,
+Separator,
-Chars)
concat_chars/2
, except that
the elements of Chars are separated by +Separator.
Simplified versions of these predicates could have been defined thus:
concat_atom(Constants, Atom) :- concat_chars(Constants, Chars), atom_chars(Atom, Chars).
concat_chars([], []). concat_chars([Constant|Constants], Chars0) :- name(Constant, Name), append(Name, Chars1, Chars0), concat_chars(Constants, Chars1).
There is one additional "feature": in place of a constant, you may supply a non-empty list of character codes. For example,
| ?- concat_atom([fred_,27], X). X = fred_27
and
| ?- concat_atom([fred,"_",27], X). X = fred_27
both work. Beware: an empty list of character codes, ""
, is in fact
the atom written []
. Because of this ambiguity it is not possible to
write a predicate that will accept any atom and any list of
character codes, because "" = []
is both.
[]
is the atom []
, which has two punctuation marks in its name.
This is for compatibility with other Edinburgh Prologs.
So while you might expect
| ?- concat_atom([fr,"",ed], fred). no
you will in fact get
| ?- concat_atom([fr,"",ed], X). X = 'fr[]ed'
This "feature" of allowing non-empty lists of character codes is thus sufficiently confusing that it is likely to be withdrawn in future releases of the Quintus library, and is retained in this release for backward compatibility with earlier releases of the library. The concatenation functions themselves will remain.