Вопрос

>
(defun hib (f1 f2)
  (cons
    (function
      (lambda ()
        (setq f2 (+ f1 (setq f1 f2))))
    )
    (function
      (lambda ()
        (list 88 f1 f2 99 ))
    )
  )
)
hib
> (setq hib1 (hib 1 1))
(#<function :lambda nil (setq f2 (+ f1 (setq f1 f2)))> .
 #<function :lambda nil (list 88 f1 f2 99)>)
> (setq hib2 (hib 1 1))
(#<function :lambda nil (setq f2 (+ f1 (setq f1 f2)))> .
 #<function :lambda nil (list 88 f1 f2 99)>)
> (funcall (car hib1))
2
> (funcall (car hib1))
3
> (funcall (cdr hib1))
(88 2 3 99)
> (funcall (car hib1))
5
> (funcall (cdr hib1))
(88 3 5 99)
> (funcall (car hib1))
8
> (funcall (cdr hib1))
(88 5 8 99)
> (funcall (car hib2))
2
> (funcall (cdr hib2))
(88 1 2 99)
> (funcall (cdr hib1))
(88 5 8 99)
> (funcall (car hib2))
3
> (funcall (cdr hib2))
(88 2 3 99)

Why (funcall (car hib1)) would change f1 and f2 in (cdr hib1)?

Why (funcall (car hib1)) would NOT change f1 and f2 in (cdr hib2)?

Это было полезно?

Решение

The closures of hib1 and hib2 are different, that is, there are separate variable bindings.

Calling (funcall (car hib1)) changes the value of f1 and f2 around the hib1. Those values are totally different to f1 and f2 around the hib2.

So any number of calls to hib1's environment cannot change hib2's environment.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top