Scheme console printing

51,332

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:

  1. You can use (define (factorial n) [...]) as a shorthand for (define factorial (lambda (n) [...])).
  2. 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.

Share:
51,332
eric17859
Author by

eric17859

Updated on July 09, 2022

Comments

  • eric17859
    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
    Paul Richter over 12 years
    You don't need a begin within a lambda body.
  • eric17859
    eric17859 over 12 years
    Oh 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
    fnl over 12 years
    I fixed the part about begin. The body of a cond-clause may also contain multiple expressions, so you can easily just call display there.
  • eric17859
    eric17859 over 12 years
    Sry if I wasn't clear. I mean, if n=5, I would print 1 2 3 4 5
  • fnl
    fnl over 12 years
    I 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
    eric17859 over 12 years
    thanks 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
    fnl over 12 years
    That 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
    eric17859 over 12 years
    Hm.. it didn't work. procedure application: expected procedure, given: #<void>; arguments were: #<void> 1.. Ah, I don't get these error msgs.
  • fnl
    fnl over 12 years
    Having diverged quite a bit from the original question, I recommend you ask a separate one.
  • dyoo
    dyoo over 12 years
    The 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) ...).