Too many arguments to format/2

This surprised me a bit. I didn’t find it documented but historically I have been quite bad at reading the docs.

?- format("~w~n", [foo,bar]).
foo
true.

The opposite (not enough arguments) throws an error.

1 Like

GNU Prolog 1.4.5 and YAP 6.5.0 git behaves as SWI-Prolog for that query. But ECLiPSe 7.0#49 and SICStus Prolog 4.5.0 throw an error reporting the surplus bar argument. I considered in the past implementing a lint check for this case but it’s relatively heavy to parse and check the arguments at compile (also, the arguments may only be bound at runtime). It would be preferable that the predicate implementation itself generated an error (or at least a warning) in these cases.

1 Like

I would vote for format with wrong # of args should throw an error (either too few or too many). It’s a mistake I often make and I would rather see an error than incorrect output. (But what about this breaking existing code? I hear you ask, and I reply “It was wrong code, and it’s probably easily fixed”)

1 Like

I’m happy to add an error. What is the error term produced by SICStus and ECLiPSe? I don’t really see the obvious ISO style error term …

1 Like

ECLiPSe:

Version 7.0 #49 (x86_64_macosx), Wed Sep 18 19:49 2019
[user 36]: format("~w~n", [foo,bar]).
foo
bad argument list in format(output, "", [bar])
Abort

[user 37]: catch(format("~w~n", [foo,bar]), Error, true).
foo
bad argument list in format(output, "", [bar])
Error = abort
Yes (0.00s cpu)

SICStus Prolog:

$ sicstus
SICStus 4.5.0 (x86_64-darwin-17.7.0): Thu Jan 17 17:17:35 CET 2019
Licensed to Paulo Moura
% consulting /Users/pmoura/.sicstusrc...
% consulted /Users/pmoura/.sicstusrc in module user, 7 msec 45392 bytes
| ?- format("~w~n", [foo,bar]).
! Consistency error: [126,119,126,110] and user:[foo,bar] are inconsistent
! format_arguments
! goal:  format([126,119,126,110],user:[foo,bar])
| ?- catch(format("~w~n", [foo,bar]), Error, true).
Error = error(consistency_error([126,119,126,110],user:[foo,bar],format_arguments),consistency_error(format([126,119,126,110],user:[foo,bar]),[126,119,126,110],user:[foo,bar],format_arguments)) ? 
yes

Abort is a bit drastic. Interesting. Is this

consistency_error(Something, SomethingElse, WhyItIsInconsistent)?

My understanding is that, in ECLiPSe, most non-ISO errors throw an abort exception term. Joachim should be able to explain it better :stuck_out_tongue: You interpretation of the SICStus exception term is correct:
https://sicstus.sics.se/sicstus/docs/latest4/html/sicstus.html/ref_002dere_002derr_002dcns.html#ref_002dere_002derr_002dcns

Currently, I see:

$ swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.20-3-g369b0fa2a)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- format("~w~w", [1]).
1
ERROR: Format error: not enough arguments
ERROR: In:
ERROR:   [10] format("~w~w",[1])
ERROR:    [9] <user>
?- catch(format("~w~w", [1]), E, true).
1
E = error(format('not enough arguments'), context(system:format/2, _12930)).

?- format("~w", [1,2]).
1
true.

Do you mean that you’d like to change the error term for “not enough arguments” as well?

1 Like

Good question. Opinions? I guess we have two options:

  • format('too many arguments')
  • consistency_error(format(X, Y), X, Y, format_arguments) and use this also for all the other format errors.

Format/2,3 has quite a few currently fairly informative error messages. We map all of these to consistency errors and use the error/2 second field to retain the informative error messages? Does that make sense or is this a complete overkill? I’m tempted to consider this an overkill …

For the record, I have no strong opinion either way, as long as it is consistent. The lazy programmer in me tells me “whatever is the least work”.

too many arguments fits with the current too few arguments.

consistency_error feels like “I know more about the error but I won’t tell you.”
(And, yes, abort is too harsh.)

1 Like

With this patch we get

101 ?- format("~w~n", [foo,bar]).
foo
ERROR: Format error: too many arguments
ERROR: In:
ERROR:   [10] format("~w~n",[foo,bar])
ERROR:    [9] <user>
102 ?- 

Let us see whether that results in too many broken programs … Having a flag to suppress errors that will be in the system forever and needs documenting is no fun either.

2 Likes

Coincidentally, I got annoyed at getting an exception from format/2 on incorrect “n placeholder”/“m arguments” matching if “n > m” and used this annoyance to look at what other systems are doing.

IMHO, Perl does it best. It warns if there is a problem (even if this problem is due to wrong argument type) - STDERR was invented for this - and continues. This absolutely makes sense in a dynamic language, where much more high-level stuff is going on and surprises during formatting output should probably rarely, if ever, lead to program halt.

#!/usr/bin/perl -w

printf "%d %s %s %s %s\n", "x", "a", "b", "c";
printf "Ok, Buddy!\n";
Argument "x" isn't numeric in printf at test.pl line 3.
Missing argument in printf at test.pl line 3.
0 a b c 
Ok, Buddy!

Just my 2 cents, as a decision on “erroring out in all cases” has been taken already.

Best regards,

– David

1 Like

While I have been following the thread at StackOverflow, perhaps you could add more details into your post for those here.

When I read the details on StackOverflow it appeared to me you were looking for a change to the code or pointing out a bug that could be fixed. When I read your post here I get an entirely different view; it looks like you are just adding your 2 cents, but I know you desire more. :smiley:

Also I was surprised to see you add it to this topic, IMHO it should be a separate topic, but time will tell.