4

http://lisperati.planvita.com/でclojureに適合したロシア語バージョンの「castingSPELs」チュートリアルを読みました...そしてこれまで、次のマクロがどのように機能するか理解できません:( http:を参照)ロシア語バージョンの場合は//lisperati.planvita.com/actions.html、Lispの場合は元のバージョンの場合はhttp://lisperati.com/actions.html):

(defspel game-action [command subj obj place & args]
  `(defspel ~command [subject# object#]
     `(spel-print (cond (and (= location '~'~place)
                             (= '~subject# '~'~subj)
                             (= '~object# '~'~obj)
                             (have? '~'~subj))
                        ~@'~args
                        :else '(i cannot ~'~command like that -)))))

それはさらに次のように使用されます:

(game-action weld chain bucket attic
   (cond (and (have? 'bucket) (def chain-welded true))
              '(the chain is now securely welded to the bucket -)
         :else '(you do not have a bucket -)))

(game-action dunk bucket well garden
             (cond chain-welded 
                   (do (def bucket-filled true)
                       '(the bucket is now full of water))
                   :else '(the water level is too low to reach -)))

ここでdefspel-はdefmacroの単なるエイリアスです。

マクロを作成する理由は、次の関数を置き換えるためです。

(defn weld [subject object]
  (cond (and (= location 'attic)
             (= subject 'chain)
             (= object 'bucket)
             (have? 'chain)
             (have? 'bucket)
             (not chain-welded))
        (do (def chain-welded true)
            '(the chain is now securely welded to the bucket -))
        :else '(you cannot weld like that -)))
(defn dunk [subject object]
  (cond (and (= location 'garden)
             (= subject 'bucket)
             (= object 'well)
             (have? 'bucket)
             chain-welded)
        (do (def bucket-filled true)
            '(the bucket is now full of water))
        :else '(you cannot dunk like that -)))

私はこの「ゲームアクション」マクロがどのように機能するかについて完全に混乱しています...誰かがそれについてのすべてのこと(ネストされた引用符)を私に説明できますか?

私はすでに次の記事を読んだ-http://blog.8thlight.com/colin-jones/2012/05/22/quoting-without-confusion.html-それは役に立たなかった...

macroexpand-1も私を怖がらせます...

これは、溶接ゲームアクションの出力です。

(clojure-magic-game.core / defspelweld [subject_ 1058 _auto__ object_ 1059 _auto_](clojure.core / seq(clojure.core / concat(clojure.core / list(quote clojure-magic-game.core / spel-print))(clojure.core / list(clojure.core / seq(clojure.core) / concat(clojure.core / list(quote clojure.core / cond))(clojure.core / list(clojure.core / seq(clojure.core / concat(clojure.core / list(quote clojure.core / and)) (clojure.core / list(clojure.core / seq(clojure.core / concat(clojure.core / list(quote clojure.core / =))(clojure.core / list(quote clojure-magic-game.core / location ))(clojure.core / list(clojure.core / seq(clojure.core / concat(clojure.core / list(quote quote))(clojure.core / list(quote attic))))))))(clojure .core / list(clojure.core / seq(clojure.core / concat(clojure.core / list(quote clojure.core / =)))(clojure.core / list(clojure.core / seq(clojure.core / concat( clojure.core / list(quote quote))(clojure.core / list subject _1058_auto _))))(clojure.core / list(clojure.core / seq(clojure.core / concat(clojure.core / list(quote quote))(clojure.core / list(quote chain)))))) ))(clojure.core / list(clojure.core / seq(clojure.core / concat(clojure.core / list(quote clojure.core / =)))(clojure.core / list(clojure.core / seq(clojure。 core / concat(clojure.core / list(quote quote))(clojure.core / list object_ 1059_auto__))))(clojure.core / list(clojure.core / seq(clojure.core / concat(clojure.core / list(quote quote))(clojure.core / list(quotebucket))))))) )(clojure.core / list(clojure.core / seq(clojure.core / concat(clojure.core / list(quote clojure-magic-game.core / have?))(clojure.core / list(clojure.core / seq(clojure.core / concat(clojure.core / list(quote quote))(clojure.core / list(quote chain)))))))))))(quote((cond(and(have?(quoteバケット))(def chain-welded true))(quote(チェーンはバケットにしっかりと溶接されています-)):else(quote(バケットがありません-)))))(clojure.core/list: else)(clojure.core / list(clojure.core / seq(clojure.core / concat(clojure.core / list(quote quote)))(clojure.core / list(clojure.core / seq(clojure.core / concat( clojure.core / list(quote clojure-magic-game.core / i))(clojure.core / list(quoteclojure-magic-game。core / cannot))(clojure.core / list(quoteweld))(clojure.core / list(quote clojure-magic-game.core / like))(clojure.core / list(quote clojure-magic-game.core / that))(clojure.core / list(quote clojure.core /-))))))))))))))))

すべての名前空間を削除して出力をインデントしたとしても、私には理解できないほど複雑に見えます。

(defspel weld [subject__1058__auto__ object__1059__auto__] 
  (seq (concat 
         (list (quote spel-print)) 
         (list (seq (concat 
                      (list (quote cond)) 
                      (list (seq (concat 
                                   (list (quote and)) 
                                   (list (seq (concat 
                                                (list (quote =)) 
                                                (list (quote location)) 
                                                (list (seq (concat 
                                                             (list (quote quote)) 
                                                             (list (quote attic)))))))) 
                                   (list (seq (concat (list (quote =)) 
                                                      (list (seq (concat 
                                                                   (list (quote quote)) 
                                                                   (list subject__1058__auto__)))) 
                                                      (list (seq (concat 
                                                                   (list (quote quote)) 
                                                                   (list (quote chain)))))))) 
                                   (list (seq (concat 
                                                (list (quote =)) 
                                                (list (seq (concat 
                                                             (list (quote quote)) 
                                                             (list object__1059__auto__)))) 
                                                (list (seq (concat 
                                                             (list (quote quote)) 
                                                             (list (quote bucket)))))))) 
                                   (list (seq (concat 
                                                (list (quote have?)) 
                                                (list (seq (concat 
                                                             (list (quote quote)) 
                                                             (list (quote chain))))))))))) 
                      (quote ((cond 
                                (and 
                                      (have? (quote bucket)) 
                                      (def chain-welded true)) 
                                (quote (the chain is now securely welded to the bucket -)) 
                                :else (quote (you do not have a bucket -))))) 
                      (list :else) 
                      (list (seq (concat 
                                   (list (quote quote)) 
                                   (list (seq (concat 
                                                (list (quote i)) 
                                                (list (quote cannot)) 
                                                (list (quote weld)) 
                                                (list (quote like)) 
                                                (list (quote that)) 
                                                (list (quote -))))))))))))))
4

1 に答える 1

4

これからマクロやClojureについて学ぼうとしないでください。

  1. 英語の Lisp バージョンの引用

    このスペルがどれほどばかげて複雑になっているかに注意してください。リストを振ることができるよりも、より奇妙な引用、バックコート、コンマ、その他の奇妙なシンボルがあります。それ以上に、実際に別の SPEL をキャストした SPEL です。経験豊富な Lisp プログラマーでさえ、このような巨大なものを作成するには、ある程度の考えを入れなければなりません (実際、彼らはこの SPEL を洗練されていないと見なし、ここで心配する必要のないより良い動作にするために、いくつかの特別な難解な手順を実行するでしょう)。 ...)

    この SPEL のポイントは、これらの SPEL を使用してどれだけ洗練され、賢いものになるかを示すことです。また、私たちがそれを一度だけ書く必要がある場合、それを使用してから、より大きなアドベンチャーゲームのために何百ものコマンドを作成することができれば、ugさは本当に重要ではありません。

    翻訳: これは書き込み専用のガベージです。言語へのチュートリアルの導入を意図したもので、著者は不必要に複雑なマクロを紹介するために貧弱なデザインを選択し、マクロの賢明な使用とファーストクラスおよび高次関数の力について議論する機会を無駄にしました.

  2. Clojure バージョンは、適切な翻訳ではなく音訳です。1 つの例:関数の内部は、関数setfの内部に音訳されましたdef。これは悪いclojureです。

今私の石鹸箱をオフに

リンク先のQuoting Without Confusionの記事は、もう 1、2 回読む価値があります。

「Casting SPELs」の作成者は、目的により適切な文字列 、"bucket"またはキーワード を使用するのではなく、引用符で囲まれた記号 (としても知られる) を使用しています。:bucket'bucket(quote bucket)

したがって、作者は次のようなマクロ展開が必要です

(... (quote bucket) ...)

しかし

user=> `(... 'bucket ...)

名前空間修飾を行います:

(... (quote user/bucket) ...)

だから、あなたはしなければならないことになります

user=> `(... '~'bucket ...)

取得するため

(... (quote bucket) ...)

Quoting Without Confusionの記事~'で説明されているように、トリックは余分です。

しかし、game-actionマクロの作成者が構文引用符で 2 つの深さのネストを作成したため、展開するレイヤーがもう 1 つあります。~'

user=> ``(... '~'~'bucket ...)

1 つ目'quoteあなたが望むものです。2 つのセットは~'、構文 quote の各レベルに対して 1 回ずつ、名前空間修飾を 2 回エスケープすること``です。

これにより、

(clojure.core/seq 
  (clojure.core/concat 
    (clojure.core/list (quote ...)) 
    etc...

うわぁ!ただし、ネストされた構文の引用符を扱う場合は、 Quoting Without Confusionのアドバイスに従ってください。

user=> (eval *1)

(... (quote bucket) ...)

そして、この構造はすべて、私たちが望んでいたものを提供するためのものであることがわかります.

于 2013-02-16T20:09:28.570 に答える