Printf in scheme - scheme

How would I do something like the following in scheme?
printf("I went to the park at %d with %s", 4, "Bob");
The closest I have right now is:
(define TIME 4)
(define NAME "Bob")
(display "I went to the park at ") (display TIME) (display " with ") (display NAME) (display ".")

You can't do this in standard Scheme. Many Scheme implementations have a format procedure that is modeled on the Common Lisp format. For example, Chez Scheme has a pretty complete implementation of format, and also printf which is just a wrapper around format. I am so used to using format that I never think to use printf in lisps:
> (format #t "I went to the park at ~A with ~A~%" 4 "Bob")
I went to the park at 4 with Bob
> (printf "I went to the park at ~A with ~A~%" 4 "Bob")
I went to the park at 4 with Bob
Here format sends the output to the current output port when the first argument is #t; printf automatically sends output to the current output port. Common Lisp style format directives are prefixed with a tilde (~). The ~A, or aesthetic, directive prints objects in human-readable form, and is what you want most of the time. There are other directives for formatting numbers; I added the ~% directive, which emits a newline. Your original example did not include a newline, and printf, at least in C, does not add a newline at the end of output (ordinarily this is desirable). The format procedure should allow much more control over results than the mother of all printfs, namely C's fprintf.
The specific facilities for printing formatted output will depend on the implementation, but Chez Scheme, MIT Scheme, Gauche Scheme, and Guile all implement format. Chicken Scheme implements format, and also implements printf, fprintf, and sprintf which all use the same format directives as format. Racket has a host of formatted output procedures, including format, printf, and fprintf; all of these use Common Lisp style format directives, too.
You will have to consult the documentation of a specific implementation to understand which format directives are supported and how they work; the Chez Scheme documentation contains some information, but suggests consultation of the Common Lisp HyperSpec for complete documentation.
There are also SRFI-28 (Basic Format Strings) and SRFI-48 (Intermediate Format Strings) which provide some of this functionality to implementations that support them.

It really depends on what Scheme interpreter you're using. For example, in Racket you can use printf for a similar effect:
(printf "I went to the park at ~a with ~a" 4 "Bob")
=> I went to the park at 4 with Bob
Check the documentation for more formatting modifiers.

Related

What is the type of the following expression in Scheme?

I am trying to understand what is the type of the following statement in Scheme:
#&\a
what is the type of the expression above?
is it a comment?
In Racket, #&\a is an immutable box containing a symbol.
(box? #&\a) ; #t
(unbox #&\a) ; 'a
(symbol? (unbox #&\a)) ; #t
(immutable? #&\a) ; #t
Refer to Reading Boxes.
#&\a is not valid Scheme code.
Anything starting with # is typically a reader macro of some sort. In Scheme all from reading numbers in specific bases, vector literals and booleans start with the # and this is remnants from the time Scheme was interpreted under a MacLISP host. It would use reader macro to do the right thing at read time. Common Lisp has the same functionality today.
Examples:
'#(1 2 3) ; a vector of 3 elements
#f ; boolean false (everything else is thruthy)
#x10 ; 16 read in hexadecimal
It's not uncommon for an implementation to expand features beyond the report and the report does not ban this. Thus any implementation can add other reader macros and it won't affect Scheme code since you'll never use those in Scheme code, only in the implementers new Scheme dialect. I don't think there exist one Scheme implementation that only implement the report and nothing else.

Call finish-output from format

I noticed that there is no
format directive which would
call force-output/finish-output.
Why?
It does seem to be useful in user interaction, cf.
Lisp format and force-output.
E.g., ~= could translate to finish-output, and ~:= to force-output.
I don't think clear-output makes much sense in this context, but we
might map ~#= to it for completeness.
PS. Cf. CLISP RFE.
Summary from comp.lang.lisp:
An explanation from Steven Haflich
The language defines no portable way to extend the set of format
directives (other then ~/.../) but that's not really the issue here.
The real problem is that it is not well defined to call finish-output or similar functions at arbitrary places during printing.
If pretty-printing is in progress, the stream received by a
pprint-dispatch or print-object method may be an encapsulating stream --
one that delays output temporarily until it can make decisions about
white space and line breaks. (There are also potential problems if
finish-output were called inside a ~< justification, but that directive
is a hairball!) What would one expect finish-output to do if called
inside a pretty print operation? I don't think it's well defined.
The problem isn't particular to format, of course, but a directive for
finish-output from format would just add another sharp edge to the
language. finish-output etc. are only safe to call when completely
outside an actual or implied call to cl:write. Call it as a function
at an appropriate point in your code (where you know execution isn't
inside a nested write) so the intention is clear and you don't mess up
printer internals.
A suggestion from Rob Warnock
Actually, no changes to format are needed. Just add this function somewhere in the COMMON-LISP-USER package:
(defun fo (stream arg colon-p atsign-p &rest params)
(declare (ignore arg params))
(cond
(colon-p (force-output stream))
(atsign-p (clear-output stream))
(t (finish-output stream))))
Then:
(progn
(format t "enter var: ~/fo/" nil)
(read))
enter var: 456
456
The problems with this (portable!) approach are
verbosity (~/fo/ instead of ~=)
need to consume a format argument (nil in the example above)

Scheme: Arrow -> What does it mean?

I'm taking a functional programming course, using the book SICP as reference. Several places in the book, I have come across the use of '->' arrows in procedure definitions.
Examples:
(define (segments->painter segment-list)
(lambda ...
(define (tree->list tree)
(if (...
(define (scheme-number->complex n)
(make-complex-from-real ...
So, what does the '->' arrow mean? Is it a naming convention to indicate that the procedure transforms one thing into another; such as tree-into-list?
If not; what does the arrow represent?
Thanks!
As #sepp2k mentions -> is part of the name and doesn't mean anything in it self.
The convention is to use -> in names for "conversion" (used loosely) functions.
The function string->list has a string as input and produces a list of characters.
In most cases you can pronounce -> as "to". That is string->list is pronounced "string to list" if you were to read code aloud.
Is it a naming convention to indicate that the procedure transforms one thing into another; such as tree-into-list?
Exactly.

Scheme let syntax error

(define (rec base height)
(let ((product (* base height))(half 0.5))
(let ((sum (* product half)))
(display "Area is")
(display sum))))
let: expected only one expression after the name-defining sequence, but found one extra part in: (display sum)
I am having the error as above, I don't know which part goes wrong
In full Scheme, this is allowed. However, you are probably using one of the teaching variants of Scheme (such as Intermediate Student or Advanced Student) that Racket provides, which disallows functions with more than one expression.
I'd say you can work around it by using begin, but Intermediate Student doesn't provide begin either (Advanced Student appears to, which helps). If you're using Intermediate Student, I guess you're just not meant to use multiple expressions, and that's that. :-)
The beginning and intermediate student languages really aren't a good fit for programs that use I/O. If your teacher is assigning problems that require you to use one of these languages and also require you to print something out, that would be a somewhat inappropriate assignment.
For the record, I certainly make mistakes like this myself....

Convert hexadecimal number to hexadecimal number presentation in common lisp

I'm trying to convert hexadecimal number to hexadecimal number presentation.
for example is below.
CL-USER> (foo 0D)
#x0D
Should i use macro function?
0D is a symbol (by default). Get its name with SYMBOL-NAME as a string. Use PARSE-INTEGER with :RADIX 16 to get the number.
If you don't have any reason for it, representing hex numbers as symbols is nothing I would do.
Are you saying that you want to format a number as a hexadecimal string? If so, you would want something like this: (format nil "~x" #x0D)
As phrased your question makes no sense. There is no such thing as a "hexadecimal number"; "hexadecimal" is the name of a number-presentation system. In your example, the input appears to be a symbol, as Rainer says, but not every such "hexadecimal" is a symbol. Presumably you want the output of (foo 10) to be #x10, and here the input is a number. So if the input is interpreted by the Lisp reader as a (base-10) number, then it should be converted to the number you would get if reread base 16.
Another point that Rainer overlooked is that if 0D is understood as a symbol, then (foo 0D) would cause an UNBOUND-VARIABLE error. You would have to write (foo '0D) to make 0D an input to foo.
On the output side, I don't think there is any native Lisp object that prints as "#x..." . If you want numbers to print in base 16, then you bind print-base to 16, but you won't see any sharpsign-x in front of it.
That suggests a somewhat different approach to your problem. We define a new datatype that does print starting with #x, and have foo construct such an object:
(defstruct (pseudo-hex (:print-object pseudo-hex-print))
thing)
(defun pseudo-hex-print (h srm)
(format srm "#x~a" (pseudo-hex-thing h)))
(defun foo (x)
(make-pseudo-hex :thing x))
Now we get the following:
cl-user(162): (foo 38)
#x38
cl-user(163): (foo '0D)
#x0D
I have a funny feeling this is not what Rafael was asking!

Resources