Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional arguments and dots in scheme

So, I am trying to see how functions that can accept any number of arguments work?

I tried this

(define (plus x . xs)
  (if 
   (null? xs) x
   (plus (+ x (car xs)) . (cdr xs))))
(plus 1 2 3 4)

But is seemed that it wasn't actually applying cdr to xs, but passing ( (2 3 4)) in when I stepped through it in the debugger. So I tried this

(define (plus* x . xs)
  (if 
   (null? xs) x
   (let ((h (car xs))
         (t (crd xs)))            
     (plus* (+ x h) . t))))

Thinking: "ha, I'd like to see you pass cdr in now", but I get an error: "application: bad syntax (illegal use of `.') in: (plus* (+ x h) . t)"

What is going on?

(I can get a version of addition to work, either by

(define (add . xs)
     (foldl + 0 xs))

Or even

(define (plus x . xs)
  (if 
   (null? xs) x
   (apply plus (cons (+ x (car xs))  (cdr xs)))))

so, the addition is not the problem, how dotted things work is.)

like image 281
Theo Belaire Avatar asked Nov 15 '10 04:11

Theo Belaire


1 Answers

Your last version is the correct way to pass a list of numbers as inputs to plus -- you must use apply to do this. (Well, either that, or avoid the whole thing as you did with foldl.) Using a dot in the application is not doing what you think it should -- it makes the program read differently.

like image 108
Eli Barzilay Avatar answered Oct 12 '22 07:10

Eli Barzilay