Page 1 of 1

Passing multiple arguments

Posted: Thu Nov 04, 2004 11:18 pm
by Jeremy Dunn
I have a question about passing multiple arguments in a function. Suppose I want to write a function (+- a b c .... n) that is equivalent to
a+b-c+....n

How would I go about this?

Posted: Fri Nov 05, 2004 12:16 am
by Lutz
You would use a maco defined with 'define-macro', inside a macro you can use a function (args) to get all arguments in a list:

Code: Select all

(define-macro (+-)
  (let ((result 0) (sign true))
  (dolist (p (args))
    (if sign (inc 'result (eval p)) (dec 'result (eval p)))
    (set 'sign (not sign)))
  result))

(+- 1 2 3 4 5) => 3
(apply +- (sequence 1 1000)) => -500
This is a brute force solution, there must be a smarter way to do this, just wanted to show how to use (args).

Lutz

Posted: Fri Nov 05, 2004 5:08 am
by nigelbrown
if
(+- a b c .... n)
is equivalent to
a+b-c+....n

rather than

(+- 1 2 3 4 5) => 3

shouldn't the result be:

1+2-3+4-5 => -1

so, if that is the intent, what about
> (define (+- x) (add (first x) (apply 'add (map 'mul (rest x) (series 1 -1 (length (rest x)))))))

> (+- '(1 2 3 4 5))
-1
>

but this is handling just one argument - the list - perhaps a macro is needed to collect up arguments first.
viz
> (define-macro (+-m) (+- (args)))

> (+-m 1 2 3 4 5)
-1
>

so doing it all in one place

> (define-macro (+-) (add (first (args)) (apply 'add (map 'mul (rest (args)) (series 1 -1 (length (rest (args))))))))

> (+- 1 2 3 4 5)
-1
>

Nigel

Posted: Fri Nov 05, 2004 12:58 pm
by Lutz
Nice but: (apply +- (sequence 1 5)) would not work, because you forgot to evaluate the (args).

But building on your idea and allowing also for one argument:

Code: Select all

(define-macro (+- )
  (let (signs (cons 1 (series 1 -1 (- (length (args)) 1)))) 
   (apply 'add (map 'mul (map eval (args)) signs))))

(+- 1 2 3 4 5)            => -1
(apply +- (sequence 1 5)  => -1
The trap is, that the sequence of 1's starts with 2 1s (1 1 -1 1 -1 ...). This one works on one argument.

Lutz

Posted: Fri Nov 05, 2004 9:23 pm
by nigelbrown
Thanks for tidying it up
Nigel