Martin Maechler wrote:
vQ> sptinf('%q%s', 1)
vQ> still suggests that one uses %{f,e,g,a} for numerics,
vQ> while %s is pretty much valid, too. you see, in c
vQ> sprintf(buffer, "%s", 1) is destined to cause a
vQ> segfault, but in r it works -- so the error message is
vQ> slightly misleading, as it suggests %s is *not* valid
vQ> for numerics.
yes, but only the error message somewhat suggests that;
at the moment, I'd like to keep it, since really the user
*should* think of using the number formats, rather than %s
{which just calls as.character(.)} for numeric arguments
then maybe sprintf('%s', 1) should complain about a format-argument
mismatch? in c, 1 would be taken to be an address at which a string
starts, but in r you do not have pointers, so this interpretation is
impossible. if the user *should* use number formats for numerics, %s
should not work. smells lack of design.
MM> I think we should signal an error if there are too many arguments.
vQ> agree. but it might be more complex than it appears:
vQ> sprintf('%3$s', 1, 2, 3)
vQ> should *not* complain about too many args, despite just
vQ> one conversion spec in the format.
very good point; thanks!
vQ> Interestingly,
vQ> sprintf('%3$s', , , 3) # error: argument is missing,
vQ> with no default
yes, empty (aka "missing") arguments are not allowed in sprintf().
be nice and document such items, pliz.... even if all internal functions have this behavour (do they?), ?sprintf does not say that sprintf is internal, or that the r wrapper calls an internal so that all arguments are necessarily evaluated.
>> Could anyone think of a case where the current behavior
>> is desirable ?
>>
vQ> well, one scenario might be that one wants to print a collection of
vQ> items with an arbitrary format, supplied by the users,
vQ> e.g.
vQ> foo = function(fmt) { a = ... b = ... ... s =
vQ> sprintf(fmt, a, b, ...) ... }
vQ> without having to examine the format to establish which
vQ> values are needed. in the current state, sprintf would
vQ> use those it would need to use with a particular format,
vQ> with no undesirable complaints.
ok. you have given good examples which make me revert my
proposal, i.e. continue to not erroring about "too many" arguments.
i did not say i supported that view, however. it was just an example where *a* developer might wish sprintf did not complain about wrong number of arguments. examples to the opposite effect can easily be given, but that's not what you asked about.
>>> but they *are* evaluated nevertheless, e.g.:
>>>
>>> sprintf('%d', 0, {print(1)}) # "1" # [1] "0"
>>>
>>> it might be a good idea to document this behaviour.
MM> actually I think it should be changed to be more strict MM> (see above). as a matter of fact, and the result of many more examples, I've changed my oppinion and now agree with your original proposal: I've just commmited another sprintf() patch which (among more more important changes) *documents* that all arguments of sprintf() are evaluated; this actually already entails that empty / missing arguments are not allowed.
excellent, thanks. vQ