2017-03-13 8 views
0

私は宿題のためにSchemeのメタ面の評価に取り組んでいます。ユーザーが特別なフォームをテーブルに追加してインストールできるようにする必要があります。ユーザーが(square 5)のようなものを入力すると、評価者はsquareという名前のフォームを検索します。見つかった場合はlambdaという文が返されます((lambda (x) (* x x))など)。Scheme - 不正な関数オブジェクトとしてのラムダ

コードがlambdaステートメントを返すときに問題が発生します。

本当に奇妙な部分は、私は私のテーブルから取得した関数にパラメータを渡すことができるということです
Error: Bad function object:(lambda (x) (* x x)) 

が、それは私が以前にないとして、ラムダ文として手続き本体を定義する必要があることだけだ:私は、次のエラーメッセージが表示されますlambdaで始まるリスト

参考までに、ここでは動作しないコードがあります。 exp(install-special-form 'square (lambda (x) (* x x)))のようなものになりますので、この場合には、namesquareに評価し、func(lambda (x) (* x x))と評価されます

(define (install-eval exp) 
    (define name (cadadr exp)) 
    (define func (caddr exp)) 
    (if (special-form-lookup (list name func)) 
     #f 
     (begin 
     (append! special-forms-table (list name func)) 
     name))) 

そしてここで作業し、いくつかのコードです:

(define (install exp-list) 
    (append! special-forms-table exp-list)) 
(install (list 'square (lambda (x) (* x x)))) 

私は私の問題を推測していますつまり、動作しないコードを使用すると、lambdaは実際のlambdaではなく、見積もりとして評価されますか?実際のlambdaステートメントを取得して使用できるようにするために、ユーザー入力を取得するにはどうすればよいですか?

答えて

1

実際の手順ではなく、おそらくラムダをシンボルのリストとして格納しているでしょう。それは、これは動作しません理由です。

(define f '(lambda (x) (* x x))) 
(f 10) 
=> Error: Bad function object: (lambda (x) (* x x)) 

は、最初にそれを評価してみてください。

((eval f) 10) 
=> 100 
+0

完璧に作業しました!ありがとうございました! – JazzBullets

+0

そして、 'eval'を使うインタプリタで自由変数はどのように働くのでしょうか? – Sylwester

1

あなたはリスト(lambda (x) (* x x))を返すとき、それは('(lambda (x) (* x x)) 5)をやっようになるので、あなたがホストとそれを適用することはできません。それを試してみてください。同じエラーが発生します。

Schemeは特別なフォーム(lambda (x) (* x x))を評価するとき、作成時に環境とともにクロージャオブジェクトを返します。あなたがそれを呼び出すと、ビンディングが追加されたその環境で本体が実行され、xになります。これはあなたの通訳でシミュレートする必要がありますので、通常(lamba (args ...) body)は通常(closure-tag (args ...) environment body)と評価されます。あなたの申請には、正しい環境で身体のevalに電話する必要があります。オフィシャルではevalの使用は、あなたがevalで通訳を閉じることができなくなるため、長期的には機能しません。

関連する問題