4

関数の連鎖 (パイピング) を可能にする既製の Lisp マクロはありますか? 見つかりませんでした。この例で私が何を意味するかを説明しようとします。

次のように多くの未使用の中間変数で let* を使用する代わりに:

(let*
  ((var1 (f1 x y))
   (var2 (f2 x var1))
   (var3 (f1 var2 z)))
 var3)

以下のように書いていただきたいです。

(->
  (f1 x y)
  (f2 x _)
  (f1 _ z))

ここで、明らかに_は前の式からの戻り値になります。プラスは、_1_2、...を使用して以前に返された値を参照できる場合です。

これはアイデアであり、正確な構文はそれほど重要ではありません。

これを書くのはそれほど難しいことではありませんが、とても便利なので、すでに書かなければなりません。

4

5 に答える 5

7

このようなもの?

(defun チェーン エキスパンダー (フォーム)
  (cond ((null (cdr フォーム)) (car フォーム))
    (t `(let ((それ、(車の形)))
          ,(チェーンエキスパンダー (cdr フォーム))))))

(defun chain-counted-expander (フォームカウンター)
  (cond ((null (cdr フォーム)) (car フォーム))
    (t (let* ((name (フォーマット nil "_~d" カウンター))
          (照応 (または (検索記号名) (インターン名))))
         `(let ((,anaphora ,(car forms)))
        ,(chain-counted-expander (cdr フォーム) (1+ カウンター)))))))

(defmacro チェーン (&body フォーム)
  (チェーンエキスパンダー形式))

_1、_2 などを使用できるものを使用したい場合は、CHAIN-EXPANDER の呼び出しを CHAIN-COUNTED-EXPANDER の呼び出しに置き換えるだけです (優先する最初の番号を使用すると、0 または 1 のいずれかをお勧めします)。 . 明示的に _ Nを参照として使用することのみに対応していますが、後続の各レベルで _ もバインドするように変更することはそれほど難しくありません。

于 2010-02-01T23:46:43.957 に答える
5

なぜだけではないのですか

(f1 (f2 x (f1 x y)) z)

?

またはそれを関数にしますか?

于 2010-01-29T14:54:42.030 に答える
2

On Lispの ablock マクロを使用できます

(defmacro alambda (parms &body body)
  `(labels ((self ,parms ,@body))
     #'self))

(defmacro ablock (tag &rest args)
  `(block ,tag
     ,(funcall (alambda (args)
            (case (length args)
              (0 nil)    
          (1 (car args))
          (t `(let ((it ,(car args)))    ;; change it to _ 
            ,(self (cdr args))))))
       args)))

マクロは前の式の値を「it」にバインドしますが、必要に応じて「_」に変更できます。もちろん、名前を -> などに変更することもできます。

于 2012-07-16T20:01:36.827 に答える
1

On Lisp経由

于 2010-01-30T03:54:54.700 に答える
0

この質問は興味深いかもしれません: Lisp での暗黙のプログラミング

その質問に対する私の答えは、この質問に対するヴァティーヌの答えに似ていますが、カウントがありません。余談ですが、カウントは危険なほど壊れやすいと思います-コードを更新すると、並べ替えのバグが発生する可能性があります。以前の結果に名前を付ける方法を提供する方がおそらく良いでしょうが、実際には、最後の結果以外の結果が必要になることはほとんどありません。それらが必要な場合は、チェーン式の代わりに関数を作成する必要があります。

于 2012-07-17T09:46:48.487 に答える