Python vs Scheme: Formatted output
In Python, it's common to format string output using the % operator. (There are other ways, but this is the oldest and most widely used.) A few examples of frequently used string substitutions:
# integer
>>> "I ate %d hamburgers" % (4,)
'I ate 4 hamburgers'
# string
>>> "Hello, my name is %s" % ("John Doe",)
'Hello, my name is John Doe'
# float rounded to 2 decimals
>>> "Execution took %0.2f seconds" % (12.5678,)
'Execution took 12.57 seconds'
# compound objects
>>> "Output: %s" % (locals().keys(),)
"Output: ['__builtins__', '__name__', '__doc__']"
# repr
>>> "Invalid argument: %r" % ("foobar",)
"Invalid argument: 'foobar'"
# multiple values
>>> "Brought to you by the letters %s, %s and %s" % ("P", "Q", "R")
'Brought to you by the letters P, Q and R'
Now, on to Scheme. As far as I can tell, R5RS has nothing of the sort. Which is somewhat surprising, or then again maybe not, when you realize that it's not so difficult to write a formatting function that works for most cases.
Which is exactly what Chicken provides, in the extras unit. The printf, sprintf, fprintf and format functions all take a format string and a number of arguments (so no messing with tuples like Python does -- although that is a consequence of using an operator rather than a function).
While printf and friends are underpowered, they work for most cases:
> (printf "Once again, I ate ~a hamburgers.~n" 4)
Once again, I ate 4 hamburgers.
> (printf "I saw ~a at the ~a ~a, having ~a ~as.~n"
"Fred" 'foo 'bar '17 'martini)
I saw Fred at the foo bar, having 17 martinis.
From what I've seen, the ~a and ~n directives are the most common; there are a few more, like ~x to display a number as hexadecimal, and ~\n to skip all whitespace in the string until the next non-format character. (Note that this actually *extends* SRFI-28, which describes a form of string formatting that is rather bare-bones.)
As said, this works for most cases, but not when you, for example, want to display a float with 2 decimals. printf has no equivalent for Python's "%0.2f".
Fortunately, there are extensions that do allow this. The format egg, for instance, provides Common Lisp-like format strings.
Installing the egg is easy, more about which in a separate post; for now, suffice to say that
$ sudo chicken-setup format
should probably do the trick. Then, use the egg:
> (use format) ; loading /usr/local/lib/chicken/3/format.so ... > (format #f "The pie was ~,2F cm thick.~%" 3.1415) "The pie was 3.14 cm thick.\n"
(It provides a function format that, when imported, overrides the built-in format function. printf and friends are not affected, though.)
More information about the directives can be found in the documentation of the format egg, but basically they work the same way as the directives found in printf & co. There's just more of them, with more options.