Scheme console printing
Printing in Scheme works by calling display
(and possibly, newline
).
Since you want to call it sequentially before/after something else (which, in a functional (or in the case of Scheme, functional-ish) language only makes sense for the called functions side-effects), you would normally need to use begin
, which evaluates its arguments in turn and then returns the value of the last subexpression. However, lambda
implicitly contains such a begin
-expression.
So in your case, it would go like this:
(lambda (n)
(display n) (newline)
(cond [...]))
Two remarks:
- You can use
(define (factorial n) [...])
as a shorthand for(define factorial (lambda (n) [...]))
. - The way you implement
factorial
forbids tail call-optimization, therefore the program will use quite a bit of stack space for larger values of n. Rewriting it into a optimizable form using an accumulator is possible, though.
If you only want to print n
once, when the user calls the function, you will indeed need to write a wrapper, like this:
(define (factorial n)
(display n) (newline)
(inner-factorial n))
And then rename your function to inner-factorial
.
eric17859
Updated on July 09, 2022Comments
-
eric17859 almost 2 years
Just started with Scheme. I'm having problem with printing on console. A simple list printing example:
(define factorial (lambda (n) (cond ((= 0 n) 1) (#t (* n (factorial (- n 1)))))))
I want to print
n
, every time the function is called. I figured that I can't do that within the same function? Do I need to call another function just so I can print? -
Paul Richter over 12 yearsYou don't need a begin within a lambda body.
-
eric17859 over 12 yearsOh thx! But how about printing after the condition? I'm not working on factorial actually, but it's easier explaining with it. Something like print only if the condition is true, i.e. print if n!=0.
-
fnl over 12 yearsI fixed the part about
begin
. The body of acond
-clause may also contain multiple expressions, so you can easily just calldisplay
there. -
eric17859 over 12 yearsSry if I wasn't clear. I mean, if n=5, I would print 1 2 3 4 5
-
fnl over 12 yearsI assume you still want to extend
factorial
to do this? Then it would go like:(define factorial (lambda (n) (cond ((= 0 n) 1) (#t (let ((result (* n (factorial (- n 1))))) (display n) (newline) result)))))
-
eric17859 over 12 yearsthanks a lot! Can you tell me why you need to create a variable? why it doesn't work with (display n) (newline) (* n (factorial (- n 1)))
-
fnl over 12 yearsThat would also work, but achieve a different effect: Because the current
n
is now printed before the recursive call, the output would be reversed. -
eric17859 over 12 yearsHm.. it didn't work. procedure application: expected procedure, given: #<void>; arguments were: #<void> 1.. Ah, I don't get these error msgs.
-
fnl over 12 yearsHaving diverged quite a bit from the original question, I recommend you ask a separate one.
-
dyoo over 12 yearsThe original answer had a few typos. I've tried to edit the answer to be correct. e.g.
(define factorial (n) ...)
is syntactically incorrect: it should be(define (factorial n) ...)
.