1

だから私はSchemeが初めてです。((name: name) (args: args) (body: body)) という形式の仕様を使用してグローバル関数を定義する関数を作成しようとしていますので、たとえば

    (fn-maker '((name: mult5) (x) (* x 5)))

グローバルに呼び出すことができます

    (mult5 3)

そして15を取得します。

これが私がこれまでに持っているものです:

    (define (fn-maker fn-spec)
        (let* (spec (map cdr fn-spec))
              (name (caar spec))
              (args (cadr fn-spec))
              (body (caaddr (cdaddr fn-spec))))
        (lambda (args)
          body)))

現時点で私が混乱しているのは、ラムダにこれらの引数を使用させる方法です。現状では、ラムダは args の背後にあるリストを評価する代わりに、「args」という名前の新しいローカル変数を作成します。これを回避する方法はありますか?私の現在の思考プロセスは、args によって提供されるリスト全体で何らかの形式の let を使用する必要があるということですが、それがどのように見えるか、またはそれを構造化する方法さえわかりません。

これは宿題なので、コード (不正行為など) を探しているのではなく、正しい方向へのポイントと批評を探しているのは間違いありません。ありがとうございました。

更新: 将来これに遭遇する人には、巧妙な引用を使用してこのコードを非常に簡単に実行することができます。マクロは必要ありません。また、後でわかるように、Pretty Big の eval はデフォルトでグローバルに評価されます。

4

2 に答える 2

1

eval作成した任意のソース コードを評価するために使用できる、Scheme プロシージャと呼ばれるものがあります。

その使用は一般的にお勧めできません ( JavascriptRubyの場合と同様)。これは、より堅牢な代替手段が利用可能な場合に安全でないショートカットとして使用されることが多いためです。(簡単な例は、グローバル環境でシンボルに関連付けられた値を検索するために誰かが使用する可能性(eval name)がある場合です。この場合、名前は事前に定義された一連のシンボルから取得されます。この場合、多くの場合、別のルックアップ テーブルをこの目的のために地球環境を破壊する代わりに、関心のあるすべてのシンボル。

とにかく、一部のScheme システムでは、eval新しい定義をグローバル環境に注入するために使用できます。R5RSでは、eval手続きは式とその式を評価する環境の両方を取り、実装はこの目的のためにインタラクティブなグローバル環境を提供する必要がないため、修飾子「some」を追加する必要がありました。(つまり、interaction-environmentオプション手順です。)

evalwheninteraction-environment 提供されたときにグローバル変数を注入する例を次に示します。

(define (make-it-three name) (eval (list 'define name '3) (interaction-environment)))

;; At the REPL now

> (make-it-three 'x)

> x
3

> (map make-it-three '(a b c))
(#!unspecified #!unspecified #!unspecified)

> (+ a b c)
9

Racket (およびかなり大きいと思います) では、提供されませんinteraction-environment。しかし、この目標を達成するために使用できる別の手順がそこにあると思います。ドキュメントを確認してください。

いずれにせよ、これは正しい方向に導くかもしれないし、そうでないかもしれない 1 つの戦略についての小さなメモを提供しようとする方法にすぎません。「できないかもしれない」を強調する。

于 2013-02-12T02:02:35.547 に答える
0

プロシージャ内で作成された関数定義を、その定義がグローバル環境の外部に存在するように「エクスポート」する方法が必要です。これまでの実装では、単純にlambdaフォームが返されます。ヒント: これを行う方法はありますが (Racket で見たのを覚えています)、使用している Scheme インタープリターに固有のものである可能性があります。Pretty Big 言語で利用できるかどうかはわかりません。

補足として、パラメーターが新しい関数の名前と本体を含むリストfn-specを受け取る場合は、次のように、を呼び出すときに単一のパラメーターのみが渡されるようにしてください。fn-maker

(fn-maker '((name: mult5) (x) (* x 5)))

また、単純な手順の代わりにマクロを使用することを検討してください...

于 2013-02-12T00:08:15.650 に答える