The standard says that when calling write to a string value, double quotes should not be displayed.
But in scryer-prolog I have :
?- write("should not see dquote"), nl.
"should not see dquote"
true.
The format library output the right answer though :
?- format("~s", ["should not see dquote"]), nl.
should not see dquote
true;
Empty string is a special case since empty list is equivalent to empty string.
with write :
?- write(""), nl.
[]
true.
and format :
?- format("~s", [""]), nl.
true;
In swipl write("") return empty output, what is the correct output from the ISO standard point of view ?
another format problem:
?- writeq("liquide d'ascite").
"liquide d\'ascite" true.
expected : "liquide d'ascite"
The Prolog ISO standard defines write/1 as a bootstrapped built-in predicate in terms of current_output/1 and write_term/1:
write(Term) :- current_output(S), write_term(S, Term, [numbervars(true)]).
The point of write_term/3 is, as the name suggests, that the term is written. Writing the term "abc" as abc would not make sense, because these are different terms. Analogously, we do not write the term [1,2,3] as 1,2,3.
For the particular case you cite, the following applies:
g) Else if Term has the form '.'(Head, Tail), and
there is an effective write-option ignore_ops(false),
then Term is output using list notation, that is:
1) [ (open list char) is output.
2) Head is output by recursively applying these
rules.
3) If Tail has the form '.'(H,T) then , (comma
char) is output, set Head:=H, Tail:=T, and goto (2).
4) If Tail is [ ] then a closing bracket ] (close list
char) is output,
5) Else a | (head tail separator char) is output,
Tail is output by recursively applying these rules,
and finally, ] (close list char) is output.
So, we actually expect [a,b,c]. However, for the specific case when double_quotes is set to chars (the default value in Scryer Prolog) and the list to be output is a list of characters, it seems highly appropriate to output [a,b,c] as "abc", as in this case.
Use write_canonical/1 to write the canonical representation of a term:
?- write_canonical("abc").
'.'(a,'.'(b,'.'(c,[])))
Regarding quotes, a related issue is #301.
what about the quoted option which is enabled on writeq and write_canonical but not on write ?
quoted(Boolean) -- If Boolean is true each atom and functor is quoted if this would be necessary for the term to be correctly input by read_term.
The predicates write_term/2, write/1, write/2, writeq/1, writeq/2, write_canonical/1, and write_canonical/2 are defined as if:
write_term(Term, Options):-
current_output(S),
write_term(S, Term, Options).
write(Term):-
current_output(S),
write_term(S, Term, [numbervars(true)]).
write_term(S, Term) :-
write_term(S, Term, [numbervars(true)]).
writeq(Term):-
current_output(S),
write_term(S, Term, [quoted(true),numbervars(true)]).
writeq(S,Term):-
write_term(S, Term, [quoted(true),numbervars(true)]).
write_canonical(T) :-
current_output(S),
write_term(S, Term, [quoted(true),ignore_ops(true)]).
write_canonical(S,T) :-
write_term(S, Term, [quoted(true),ignore_ops(true)]).
I understand the truly equivalent nature of "abc" and [a, b, c] in scryer which is not the case in swipl.
So in scryer prolog what would be the difference between write and writeq predicates ?
To write some strings in a file would you recommend using the format predicate ?
Use writeq/1 if you want to use read/1 to read the terms later. For instance:
?- write(',').
,
?- writeq(',').
','
In format/3, this format is available with the ~q modifier:
?- format("~q", [',']).
','
Yes, you can use format/3 for convenient and efficient writing to files. However, in the future, an even better way will become available in library(pio), called pure output, with a new predicate phrase_to_file/2: This will allow us to invoke a DCG in such a way that the described string is directly written to a file. The garbage collector must be designed to handle such cases efficiently, immediately reclaiming what has already been written to file.
The advantage of phrase_to_file/2 (over format/3) is that the same DCG can then also be used conveniently on the top-level and in interactive tests, without any side-effects. The nonterminal format_//2 is similar, but manifests the entire list in memory and may therefore require too much memory to describe extremely long output.
Note that you can also use portray_clause/2 from library(format) to write a Prolog term to a stream in a nicely formatted way. Use portray_clause/2 (or writeq/2, or format/3) if you want to write Prolog text that is meant to be read by Prolog as terms, using read/1.
For the general use case (i.e., when the text is not necessarily an actual Prolog term), DCGs are the major attraction of Prolog when processing input and describing output. Scryer Prolog begins to show the full potential of the language for string processing, the use case Prolog was designed for, due to its compact internal string representation that also permits the use of DCGs to parse and describe strings.
looking forward to use phrase_to_file
Use
writeq/1if you want to useread/1to _read_ the terms later.
Better yet, use write_canonical/1-2.