This is a serious problem for me!

I’m using: SWI-Prolog version 8.1.15

I want the code to: be sane

But what I’m getting is: insanity

My code looks like this:

?- 5 > 6.
false.  % this looks fine
?- 5 > 4.
true.  % this looks fine
?- 5 > [6].
false.  % WTF!?
?- 5 > [4].
true.  % WTF!?
?- 5 > [4,6].
ERROR: Arithmetic: `[4,6]' is not a function
ERROR: In:
ERROR:   [20] throw(error(type_error(evaluable,...),_8180))
ERROR:   [17] arithmetic:expand_function([4,6],_8218,_8220) at d:/swipl/library/arithmetic.pl:175
ERROR:   [16] arithmetic:math_goal_expansion(5>[4|...],_8264) at d:/swipl/library/arithmetic.pl:159
ERROR:   [14] '$expand':call_goal_expansion([system- ...],5>[4|...],_8310,_8312,_8314) at d:/swipl/boot/expand.pl:876
ERROR:   [13] '$expand':expand_goal(5>[4|...],_8370,_8372,_8374,user,[system- ...],_8380,[]) at d:/swipl/boot/expand.pl:525
ERROR:   [12] setup_call_catcher_cleanup('$expand':'$set_source_module'(user,user),'$expand':expand_goal(...,_8460,_8462,_8464,user,...,_8470,[]),_8434,'$expand':'$set_source_module'(user)) at d:/swipl/boot/init.pl:539
ERROR:    [8] '$expand':expand_goal(user:(5> ...),_8514,user:_8536,_8518) at d:/swipl/boot/expand.pl:459
ERROR:    [6] setup_call_catcher_cleanup('$toplevel':'$set_source_module'(user,user),'$toplevel':expand_goal(...,...),_8564,'$toplevel':'$set_source_module'(user)) at d:/swipl/boot/init.pl:539
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
^  Exception: (6) setup_call_catcher_cleanup('$toplevel':'$set_source_module'(user, user), '$toplevel':expand_goal(user:(5>[4, 6]), _6918), _8622, '$toplevel':'$set_source_module'(user)) ? abort
% Execution Aborted
% WTFF!?!?!

This is good old Edinburgh behavior to deal with e.g., C >= "a" :slight_smile: It is even documented

P.s. better style is C >= 0'a

I surveyed three implementations (SWI, GNU, JIP). Two accepted this stupidity (and I’m unabashed at calling it stupidity!) and one didn’t (JIP).

This is a HUGE breach of “principle of least surprise”. For single-element lists to be specially blessed in this way is just insanity.

Probably is pretty much insane, but it is tradition. Apparently even GNU implements it, where GNU is typically standard compliant with not that many extensions. I guess a good static lint tool should only let it pass if the list originates from a static one-character string.

Can I propose a dont_use_idiotic_list_conversion_rules config flag?

The Logtalk linter catches uses of this legacy practice when using the portability flag. E.g.

:- object(wtf).

	:- set_logtalk_flag(portability, warning).

	a(X) :- X is 42 + [a] * 5.

:- end_object.
?- {wtf}.
*     Call to non-standard Prolog built-in arithmetic function: '[|]'/2
*       while compiling object wtf
*       in file /Users/pmoura/wtf.lgt at or above line 5
*     
% [ /Users/pmoura/wtf.lgt loaded ]
% 1 compilation warning
true.
1 Like

Proposing is free :slight_smile: It won’t be implemented though. Flags, being global state, cause too much problems in their own right and are thus minimized. The only disadvantages of this feature are failure to trap what was probably an error and not being able to verify a Prolog program is ISO compliant. The latter is surely not a task SWI-Prolog wants to be able to perform. The first is just one example and requires better tools (runtime and linting).

Thats a legacy feature that was already found in DEC 10 Prolog. Together
with the convention that double quoted string mean character code lists,
it can be used to find character codes:

?- set_prolog_flag(double_quotes, codes).
true.

?- X is "A".
X = 65.

It is not something that is found in the ISO core standard. Nevertheless,
as others have already observed, many Prolog systems support it, like
GNU Prolog, YAP, Ciao, etc… It is specified and motivated in the

DEC 10 manual from 10 November 1982 as follows:

[X]         (a list of just one element) evaluates to  X  if  X  is  an
            integer.  Since a quoted string is just a list of integers,
            this  allows  a quoted character to be used in place of its
            ASCII code; e.g. "A" behaves within arithmetic  expressions
            as the integer 65.

https://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/prolog/doc/intro/prolog.doc

SWI-Prolog seems to have it extended to its string data type. So it also
works there without the double quotes flag.