LINUX.ORG.RU

Closure в ELisp (XEmacs!) не работает :(


0

0

Помогите понять, в чем я неправ и где надо исправить, чтоб 
заработало :) Значит, имеется следующий код, работающий правильно 
в CLISP, но не работающий в ELisp по неизвестной мне причине:

;; нужно сделать closure, чтоб бегала по "кольцевому" списку
;; и выдавала текущее значение
(defun circulate-list-func (loop-list &optional first-elem)
  (let ((curr (if (member first-elem loop-list) 
		  first-elem
		(first loop-list))))
    (values (lambda ()
	       (let ((next (second (member curr loop-list))))
		 (setq curr (if (null next) 
				(first loop-list) 
			      next))))
	    (lambda () curr))))

;; проверяем функцию
(multiple-value-bind (l1 l2) 
    (circulate-list-func '("russian-computer" "ukrainian-computer")) 
  (print (funcall l2)) 
  (print (funcall l1)) 
  (print (funcall l1)) 
  (print (funcall l1)) 
  (print (funcall l2)))

=====

Вот тут и происходит затык -- ELisp пишет, что символ curr не 
является переменной (а CLISP хавает нормально!) :( пробовал curr 
в defvar'е объявить перед функцией -- не помогает :(

Заранее спасибо за ответы :) 
★★★

Ответ на: комментарий от amm

> Нету closure в Elisp-e, как и много другого, что есть в CLISP..

чего-то я недопонял аргументации того мужика по поводу того, что lexical scoping -- плохо для emacs... Он имеет в виду, что будет нельзя юзать что-то вроде (let ((case-fold-search nil)) (do-something)) ?

> Для замыканий в elisp'е предлагают использовать lexical-let.

гы, поменял let на lexical-let, теперь оно пишет, что символ loop-list (параметр в функции, снаружи lexical-let) не является переменной :D

uj2 ★★★
() автор топика
Ответ на: комментарий от uj2

Можно создать лексическую переменную с таким же именем:

(defun circulate-list-func (loop-list &optional first-elem) (lexical-let ((loop-list loop-list) (first-elem first-elem) (curr (if (member first-elem loop-list) first-elem (first loop-list)))) (values (lambda () (let ((next (second (member curr loop-list)))) (setq curr (if (null next) (first loop-list) next)))) (lambda () curr))))

amm
()
Ответ на: комментарий от uj2

Можно создать лексическую переменную с таким же именем:

(defun circulate-list-func (loop-list &optional first-elem)
  (lexical-let ((loop-list loop-list)
		(first-elem first-elem)
		(curr (if (member first-elem loop-list) 
			  first-elem
			(first loop-list))))
    (values (lambda ()
	      (let ((next (second (member curr loop-list))))
		(setq curr (if (null next) 
			       (first loop-list) 
			     next))))
	    (lambda () curr))))

amm
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.