Schema functions that "remember" values โ€‹โ€‹with let / set

I am new to Scheme and trying to understand how certain values โ€‹โ€‹that appear inside a function can be stored for several purposes. Take the following counter:

(define count
   (let ((next 0))
     (lambda ()
       (let ((v next))
         (set! next (+ next 1))
         v))))

What I cannot understand (and did not find an explanation anywhere) is why it nextdoes not get reset to 0 every time it is used count.

+5
source share
6 answers

I do not completely agree with your explanation. You are right that a function definition is evaluated only once, but the function itself is evaluated every time it is called.

, , - "... ...", ( ).

: - , , - "". , "next" ( , - ). , ( "next" 0 ). , , - . 1 "next" , - 1..

: () , .

+2

. next .

, :

(define next 0)

(define count
  (lambda ()
    (let ((v next))
      (set! next (+ next 1))
      v))))

, next.

, , , let, , lambda next. next. , :

(define count
  (lambda ()
    (let ((next 0))
      (let ((v next))
       (set! next (+ next 1))
       v))))

next, next lambda, , , lambda.

+11

, : , - "let". . , "let" :

#lang racket

(define (make-counter-from counter)
  (lambda ()
    (set! counter (+ counter 1))
    counter))

(define count (make-counter-from 9))

(count)
(count)

( ): ! !

EDIT: , , , .

"" , . "", โ€‹โ€‹(a.k.a. "mutated" ).

, , "make-counter-from" 9 , "counter" 9. / "" , . (), "" . , , . , /.

+5

, "next reset 0 , count",

(define count (let ((next 0))
                 (lambda ()
                    (let ((v next))
                       (set! next (+ next 1))
                       v))))

(define count #f)

(set! count ( (lambda (next)              ; close over `next`
                 (lambda ()                  ; and then return lambda which _will_
                    (let ((v next))          ;   read from `next`,
                       (set! next (+ v 1))   ;   write new value to `next`,
                       v)))                  ;   and then return the previous value;
              0 ))                        ; `next` is initially 0

( "let-over-lambda", Lisp ).

count "" . , next, () (). , count "", , , () : , . ; , , .

. , . (lambda () ...) next, (lambda (next) ...).

+2

, - . , (lambda): , , . let next, . , set! . , count , next .

, , .

0

, .

(define count
  (local ((define next 0)          
          (define (inc)
            (local ((define v next))
                    (begin 
                      (set! next (+ next 1))
                      v))))
    inc))

 (count)   0
 (count)   1
 (count)   2 .........

Perhaps your let / set sequence follows the same mechanism. The procedure that you are actually calling has the value inc, not count . The inc procedure grows further each time. An equivalent definition may be

 (define next 0)

 (define (inc)
  (begin
    (set! next (+ next 1))
    (- next 1)))

 (define count inc)


 (count)  0
 (count)  1
 (count)  2......

So, I think that the call count in the first program is the same as starting the whole second program. I dont know. I am also new to the scheme. Thanks for the helpful post.

0
source

All Articles