In many languages I have used, there is a way to have a variable number of arguments in the function signature, e.g. in Go you can declare a function with func doSomething(args ...int)
and call it with doSomething(2, 3, 4)
or in Python def do_something(*args)
and do_something(1, 2, 3)
, etc. Additionally, there is some syntax for spreading/unpacking these args, e.g. in Go things = append(things, others...)
or in Python do_something_else(*args)
.
I want to make a wrapper that takes a format string and passes it and any number of arguments to format t
. Since format
takes a variable number of arguments, my guess is that this is a language feature, yet I have not been able to find any explanation of how to do this.
The code I have that does not work correctly looks like this:
(defun printf (fstr vals)
(format t (concatenate 'string fstr "~%") vals))
If I call it with a format string that requires 1 value, it works fine, but I have no idea how to make it work with more than that. For example, (printf "~d is not ~a" 12 "13")
results in the error "too many arguments given to printf". I also tried the following:
(defun printf (fstr &rest vals)
(format t (concatenate 'string fstr "~%") vals))
The error then says "there are not enough arguments left for this format directive". It is clear that vals
is a list of arguments, but I have no idea how to expand them to pass to the call to format t
.
Am I accepting args correctly by using the &rest
notation? How do I expand that list of values in the call to format t
?