简体   繁体   中英

Using local variables in scheme

I have been asked to translate a couple of C functions to scheme for an assignment. My professor very briefly grazed over how Scheme works, and I am finding it difficult to understand. I want to create a function that checks to see which number is greater than the other, then keeps checking every time you input a new number. The issue I am having is with variable declaration. I don't understand how you assign a value to an id.

(define max 1)

(define (x x)
  (let maxfinder [(max max)]
    (if (= x 0)
        0
        (if (> max x) 
            max
            ((= max x) maxfinder(max))))))

The trouble I keep running into is that I want to initialize max as a constant, and modify x. In my mind this is set up as an infinite loops with an exit when x = 0. If max is > x, which it should not be for the first time through, then set max = to x, and return x. I don't know what to do with the constant max. I need it to be a local variable. Thanks

Parenthesis use is very strict. Besides special forms they are used to call procedures. eg (> max x) calls procedure > with arguments max and x . ((if (> x 3) - +) 6 x) is an example where the if form returns a procedure and the result is called.

  • ((= max x) ...) evaluates (= max x) and since the result is not a procedure it will fail.
  • maxfinder without parenthesis is just a procedure object.
  • (max) won't work since max is a number, not a procedure.

As for you problem. You add the extra variables you need to change in the named let. Eg. a procedure that takes a number n and makes a list with number 0-n.

(define (make-numbered-list n)
  (let loop ((n n) (acc '()))
    (if (zero? n)
        acc
        (loop (- n 1) (cons n acc)))))

Local variables are just locally bound symbols. This can be rewritten

(define (make-numbered-list n)
  (define (loop n acc)
    (if (zero? n)
        acc
        (loop (- n 1) (cons n acc))))
  (loop n '()))

Unlike Algol dialects like C you don't mutate variables in a loop, but use recusion to alter them.

Good luck

If i understand you correctly, you are looking for the equivalent of a C function's static variable. This is called a closure in Scheme.

Here's an example implementation of a function you feed numbers to, and which will always return the current maximum:

(define maxfinder
  (let ((max #f))                    ; "static" variable, initialized to False
    (lambda (n)                      ; the function that is defined
      (when (or (not max) (< max n)) ; if no max yet, or new value > max
        (set! max n))                ; then set max to new value
      max)))                         ; in any case, return the current max

then

> (maxfinder 1)
1
> (maxfinder 10)
10
> (maxfinder 5)
10
> (maxfinder 2)
10
> (maxfinder 100)
100

So this will work, but provides no mechanism to reuse the function in a different context. The following more generalised version instantiates a new function on every call:

(define (maxfinder)
  (let ((max #f))                    ; "static" variable, initialized to False
    (lambda (n)                      ; the function that is returned
      (when (or (not max) (< max n)) ; if no max yet, or new value > max
        (set! max n))                ; then set max to new value
      max)))                         ; in any case, return the current max

use like this:

> (define max1 (maxfinder)) ; instantiate a new maxfinder
> (max1 1)
1
> (max1 10)
10
> (max1 5)
10
> (max1 2)
10
> (max1 100)
100

> (define max2 (maxfinder)) ; instantiate a new maxfinder
> (max2 5)
5

Define a function to determine the maximum between two numbers:

(define (max x y)
  (if (> x y) x y))

Define a function to 'end'

(define end? zero?)

Define a function to loop until end? computing max

(define (maximizing x)
  (let ((input (begin (display "number> ") (read))))
    (cond ((not (number? input)) (error "needed a number"))
          ((end? input) x)
          (else (maximizing (max x input))))))

Kick it off:

> (maximizing 0)
number> 4
number> 1
number> 7
number> 2
number> 0
7

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM