Search code examples
schemelispracketprocedure

Conditional definitions in scheme (lisp)


(define (smallest x y z)
  (define min x)
  (cond ((< y min) (define min y))
        ((< z min) (define min z))
        (se (define min x)))
  min)

I'm trying to create a short procedure which returns the smallest of three numbers. It seems like the expression in a conditional can't be a definition, because I'm getting this error:

 begin (possibly implicit): no expression after a sequence of internal definitions in:
  (begin (define min y))
  (define min y)

Do you have any suggestions on what I'm in fact doing wrong, is the problem using a definition for the expression portion? If that's so, how would you tackle the problem? Thanks in advance!


Solution

  • There are a couple of problems with the code in the question:

    • The last condition should be an else, not se.
    • You should not name a variable min, this name conflicts with a built-in procedure with the same name.
    • You can't define a variable in arbitrary places, define is only allowed at the beginning of the procedure. To change an already existing value, use set! - but wait! you should avoid using set! as much as possible, in Scheme we prefer functional-programming style solutions, and mutating variables is heavily discouraged.
    • The algorithm isn't right to begin with. Notice that only one of the conditions in a cond will get executed, and there's no way to determine the minimum of three numbers with just one comparison!

    The simplest way to solve this problem in Scheme would be:

    (define (smallest x y z)
      (min x y z))
    

    If you want to implement it by hand, it's possible with a couple more comparisons:

    (define (smallest x y z)
      (cond ((and (<= x y) (<= x z)) x)
            ((and (<= y x) (<= y z)) y)
            (else z)))