Archive for the ‘parlor-trick’ Tag

newLISP で On Lisp する...第22章(その1の続き)

(この blog は、“short short story または 晴耕雨読な日々”からの引越してきたもの。スクリプトは、newLISP V10.2.1 以降で動作するように書き直しています。
defun 等の newLISP組込関数に無い関数は、特に断らない限り、newlisp-utility.lsponnewlisp.lsp に定義してあります。)

 さて、“On Lisp” 第20章の 継続渡しマクロ と共に使った例を(=defun、=values、=bind は onnewlisp.lsp に、choose-bind は 本章(その1)に定義してあります定義してあります)。

(=defun two-numbers ()
  (choose-bind n1 '(0 1 2 3 4 5)
    (letex (_n1 n1)
      (choose-bind n2 '(0 1 2 3 4 5)
        (=values '_n1 n2)))))

(=defun parlor-trick (sum)
  (=bind (n1 n2) (two-numbers)
    (if (= (+ n1 n2) sum)
        (list "the sum of" n1 n2)
      (fail))))

 これを実行すると、

> (parlor-trick 7)
("the sum of" 2 5)

 入れ子も出来ます。(multiple-value-list は onnewlisp.lsp に定義してあります)

> [cmd]
(multiple-value-list
  (choose-bind first-name '(henry william)
    (letex (_first-name first-name)
      (choose-bind last-name '(james higgins)
        (=values '_first-name last-name)))))
[/cmd]
(henry james)
> (multiple-value-list (fail))
(henry higgins)
> (multiple-value-list (fail))
(william james)
> (multiple-value-list (fail))
(william higgins)
> (multiple-value-list (fail))
(@)
> 

 letex を使うのが、お約束です。また、*cont* の初期値の values は、以前は、list で代用していましたが、今回は多値対応を使っています。ですから、multiple-value-list で受けないとリストになりません。
 ここまでは、順調でした。
 つまずいたのは、次のスクリプトdescent 。気分も急降下です(笑)。(kids は最初の方に、t は newlisp-utility.lsp に、kids は 本章(その1)に定義してありますに記述してあります。)

(=defun descent (n1 n2)
    (cond ((= n1 n2) (=values n2))
          ((kids n1) (letex (_n1 n1)
                       (choose-bind n (kids '_n1)
                         ;(println '_n1 " " n)
                         (=bind (p) (descent n n2)
                           (=values (cons '_n1 p))))))
          (t ;(println "fail")
             (fail))))

 これを実行すると、

> (descent 'a 'g)
(a b b a c c f g)
> 

 あれれ、余計なものが!
 コメント・アウトしてある println文を動作させてみると、その様子がわかります。

> (descent 'a 'g)
a b
b d
fail
b e
fail
a c
c d
fail
c f
f g
(a b b a c c f g)
> 

 バック・トラックは、うまくいっているのです。ただ、たどった道のりを全て返しているだけで(悲)。
 これは、ダイナミック・スコープによる変数補足を letex を使って回避した副作用なのです。

 そして、その解決方法は、、、次回に。

 以上、如何でしょうか?

広告