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).