1

Lisp ファミリー (EDIT: Lisp-1) 言語で、関数としての位置または引数としての位置に関してシンボル評価を区別する方法はありますか (つまり、いつ評価されるかに関して、このシンボルの eval をオーバーライドします)?
例として(この機能は必要ありません。これは例です)、オブジェクト自体から呼び出すことができるオブジェクトのセットにある種の中置操作を実装したかったのです。

(my-obj some-operator arg1 ...)  

my-obj と引数に関数 some-operator を実際に適用します。
ただし、このオブジェクトがコード内の他の場所で引数として使用されている場合は、次のようになります。

(some-function my-obj &args...) 

my-obj の値に評価されます。
ありがとうございました。

4

4 に答える 4

5

Racket では、この精神でいくつかのことを行うことができます。

  1. を定義してstructを与えることができますprop:procedure。のインスタンスがstructアプリケーションで提供されると、プロシージャが呼び出されます。

  2. 独自の関数でデフォルトをオーバーライドして、#%app一般的にアプリケーションを再定義し、structs ではないものを含めることができます。たとえば、Clojure の(key map)構文をエミュレートするようなことができるので、('symbol dict)実際には(hash-ref dict 'symbol).

于 2015-12-15T17:16:20.903 に答える
1

Lisp-1 であるということは、基本的に、組み合わせの最初のスロットを他のスロットとまったく異なる方法で評価しないことを意味します。とにかく書いたコードでそのような動作を得るには、それを Lisp-1 の規則の下で必要なことを行うコードに変換する必要があります。したがって、この変換を実行するマクロを実装する必要があります。

たとえば、中置演算子が必要な場合は、いくつかのマクロを記述する必要がinfixあり、おそらく次のように記述できます。

(infix (+ - * /) (1 + 2 * 5 - 3) / 4)

そしてそれを2に評価させます。

于 2015-12-15T13:47:42.937 に答える
1

私はオブジェクト指向 CLOS のようなスキームのデフォルト プロシージャのアイデアをいじっています。例えば。その書き込み

(obj 5 10)

obj がプロシージャまたはメソッドである場合は、obj を検証し、引数を使用して適用しますが、そうでない場合は、デフォルトのディスパッチャーと同じになります。

(default-dispatcher obj 5 10)

そのようなスキームでは、ベクトル アクセサーを作成できます。

(define-method default-dispatcher 
  "Default dispatcher for vectors"
  ([obj %vector] [index %number])       -> (vector-ref obj index)
  ([obj %vector] [index %number] value) -> (vector-set! obj index value)
  (args ...)                            -> (error "No such method"))

; example usage
(define vec (vector 4 5 6 7))
[vec 1]     ; => 5
[vec 1 10] 
[vec 1]     ; => 10

Racket では、言語の#%app構文を変更することでこれが可能になります。

于 2015-12-15T17:04:00.613 に答える