lisp - Understanding objects with local state -- Scheme -


i'm studying scheme final , objects local state has been tough subject.

here question final exam need on.

(define (make-incrementer n)   (let ((old 0)         (new 0))     (lambda ()       (cond ((< new n)               (set! old new)              (set! new (+ new 1))              old)             (else               (set! old 0)              (set! new 1)              old)))))  (define (make-incrementer 3)) (define b (make-incrementer 3)) (define c a)  ; 1) (a) ; 2) (a) 

why when a called second time returns 1? i'm looking @ code , n give 3. wouldn't else case?

welcome wonderful world of closures! textbook example of how closures in scheme work.

so make-counter returns function has 3 variables captures it's enclosing environment: n, old, new. in case, starting environment looks like

_name_|_value_  n    | 3  old  | 0  new  | 1 

on each invocation, increments old , new , wraps them around if they're greater n. because it's using set!, incrementing mutating variables in lambda's environment, since these variables captured surrounding environment, changed future calls well.

that's why different returns same input.

if seems witchcraft, can think of objects in more common languages:

eg python:

class foo():     def __init__(self, n, m):         self.n = n         self.m = m     def count(self):         self.n += 1         if self.n == self.m:            self.n = 1         return self.n-1  f = foo(0, 2)  f.count() # 1 f.count() # 0 

this same basic idea except here we're being bit more explicit environment coming from, self. in scheme, mimic lambda capturing surrounding variables.

for more, check out sicp


Comments

Popular posts from this blog

c# - DetailsView in ASP.Net - How to add another column on the side/add a control in each row? -

javascript - firefox memory leak -

Trying to import CSV file to a SQL Server database using asp.net and c# - can't find what I'm missing -