Common Lispにyield
という直接的な同等物はありません。いくつかの機能的アプローチを使用するか、遅延計算を提供する何らかの種類のライブラリを使用するかもしれません。
あなたのアプローチを完了する1つの方法は、現在の継続を保持する変数f
を持つこのようなものです。
(defun make-prime-generator (&aux (p (list 2)) (n 2) f)
(labels ((f2() ; a function for the first iteration
(incf n)
(setf f #'fn) ; setting f to the next function
2)
(fn() ; a function for all other iterations
(loop while (divisor-in-list n p)
do (incf n 2))
(push n p)
n))
(setf f #'f2) ; setting f to the first function
(lambda() ; returning a closure
(funcall f)))) ; which calls the current f
CL-USER 28 > (let ((p (make-prime-generator)))
(flet ((p() (funcall p)))
(loop repeat 10 do (print (p)))))
2
3
5
7
11
13
17
19
23
29
NIL
もしも野心的であれば、すべてのコード部分を定義し、移行を管理するマクロの背後に隠れる可能性があります。
また探査
我々は状態を作ることができるがもう少し明確なローカル機能init
、exit
とstep
を導入することによって変更します。
(defun make-prime-generator (&aux (p (list 2)) (n 2) f)
(flet ((init (function)
(setf f function))
(exit (result function)
(setf f function)
result)
(step()
(funcall f)))
(labels ((f2()
(incf n)
(exit 2 #'fn))
(fn()
(loop while (divisor-in-list n p)
do (incf n 2))
(push n p)
(exit n #'fn)))
(init #'f2)
#'step)))
今では、もう少し高度なタスク別のようになります。私たちは定型を削除し、コードをより宣言させることを可能にするgen-run
マクロを書きます。また、このように使用されることがあります。
(defmacro gen-run (f-descriptions &key start)
(let ((§f (gensym "F"))
(§init (gensym "INIT"))
(§exit (gensym "EXIT"))
(§step (gensym "STEP")))
`(let (,§f)
(flet ((,§init (function)
(setf ,§f function))
(,§exit (result function)
(setf ,§f function)
result)
(,§step()
(funcall ,§f)))
(labels (,@(loop for fd in f-descriptions
collect (destructuring-bind (name -> next &body body)
fd
(declare (ignore ->))
`(,name()
(,§exit ((lambda() ,@body))
(function ,(if next next name)))))))
(,§init (function ,start))
(function ,§step))))))
(defun make-prime-generator (&aux (p (list 2)) (n 2))
(gen-run ((f2 -> fn
(incf n)
2)
(fn -> fn
(loop while (divisor-in-list n p)
do (incf n 2))
(push n p)
n))
:start f2))
FYI "怠惰" キーワード=>怠惰なライブラリ:[clazy](https://common-lisp.net/project/clazy/)[の – Ehvince
可能な重複がありますPythonのジェネレータの簡単なlispの同等ですか?](https://stackoverflow.com/questions/32956033/is-there-a-straightforward-lisp-equivalent-of-pythons-generators) – coredump
醜い人は見る人の目の前にいます。 Pythonのソリューションでは、ハードコーディングされた初期歩留まり2、既知のハードコードされた初期化[2]、3からの反復、そして最後に2ずつ増加する "チート"というPythonソリューションの多くが見られます。素数は「2」と言っておらず、3つおきに他の整数などをスキップすることから始まる。だから、Pythonのソリューションには、それに焼き込められた素数について私たちが知っていることに特有のあらゆる種類のトリッキーがあります。 「1より大きい整数、2つの整数要素だけが1とそれ自身です」からやり直してください。それでは、1つの醜いハックが必要です.2> 2の場合はスキップしてください。 – kennytilton