4

I want to use the predefined (max) function (R5RS) with a list of numbers, which varies in length. Unfortunately, (max) accepts input like this:

(max 2 43 5 6)
=> 43

I'm attempting to use it like so:

(define lst '(3 5 53 4 53 54 32))
(max lst)

This produces the following error.

max: expects argument of type <real number>; given (3 5 53 4 53 54 32)

How can I break this list into the individual arguments I need, as I'm passing them to (max)?

ray
  • 1,966
  • 4
  • 24
  • 39

3 Answers3

6

You might consider using apply (though be warned, that this may impose limits with respect to the number of elements/arguments are acceptable, depending on your implementation of Scheme):

(apply max '(3 4 2 1 78 2 1))

In general, if the number of elements is not known to be small, it might be safer to do it manually:

(define max* (list)
    (if (null? list) (negative-infinity)
        (let loop ((list (cdr list)) (best (car list)))
            (if (null? list) best (loop (cdr list) (max best (car list)))))))
Community
  • 1
  • 1
Dirk
  • 30,623
  • 8
  • 82
  • 102
1

Using apply basically translates into running (max 3 4 2 1 78 2 1) but the number of arguments a procedure can be passed is not infinite on some systems. For max, you can take advantage of its commutativity by using fold:

(fold-left max -inf.0 '(3 4 2 1 78 2 1))
erjiang
  • 44,417
  • 10
  • 64
  • 100
0

You can write a procedure that compares the first item to the second,

(define (largestele lst)
        (if (null? (cdr lst))
            (car lst)
            (if (> (car lst) (cadr lst))
                (largestele (cons (car lst) (cddr lst)))
                (largestele (cdr lst)))))
Dave
  • 1