1
\$\begingroup\$

I am trying to build a function to find the highest number in a list without using the built-in functions of "apply" and "max".

I created the following code:

(define (highest-num lst)
  (define (iter lst accu)
    (cond ((null? lst) accu)
          ((< accu (first lst)) (iter (rest lst) (+ accu (- (first lst) accu))))
          (else (iter (rest lst) accu))))    
  (iter lst 0))

However, I bet this could be better. Any suggestions?

\$\endgroup\$
1
\$\begingroup\$

Remarks

  1. Using an internal function, recursion, and a trampoline is a good way to structure recursive procedures on a lists.
  2. The code fragment (+ accu (- (first lst) accu))) is the same as (first lst).
  3. The name accu suggests an accumulator, however, the value it stores is the maximum, so max might be better.
  4. Because of the letter l can be confused with 1, lst can be read as slang for 'first'. I prefer xs as the name for a list of x's. The nomenclature has become more common in Lisps over the past few decades due to the influence of other functional languages.
  5. No matter how it is dressed up, there's a max procedure in the code somewhere. And it has to be written. It is better to be explicit about it than to try to hide max by embedding it in some other function.

Alternative

For procedures that try to find a property of a list, folding is often a good place to start. This code uses foldl. Usually I find foldl rather than foldr is what I want, for whatever that's worth.

#lang racket
(define (highest-number xs)
  (define (max x1 x2)
    (if (> x1 x2) x1 x2))
  (foldl max (first xs) (rest xs)))

Maybe it's worth pointing out, that the starting point for writing the highest-number was wishful thinking where I wished I had max. Then at the next lower level of abstraction down, I wrote it. Credit goes to Ableson and Sussman's SICP lectures.

\$\endgroup\$
0
\$\begingroup\$

One can also use 'named let' here to have a recursive loop that compares sequentially each item to the maximum till that point:

(define (mymax L)
  (let loop ((L (cdr L)) 
             (m (car L)))          ; consider first item to be max at start.
    (cond
      [(empty? L) m]
      [(> (car L) m)               ; if next item is larger, loop with that.
         (loop (cdr L) (car L))]
      [else                        ; else loop with current max.
         (loop (cdr L) m)])))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy