[編集 4] 免責事項。または、1年後に振り返ってみると:
これは実際には、この問題を解決するための非常に悪い方法です。これは、OP の基本的な目標を達成する非常に迅速で汚い方法として機能しますが、「実際の」ユースケースには耐えられません。理由については、この回答のコメントと他の回答のディスカッションを参照してください。
[/編集]
このソリューションはおそらく理想的ではありませんが、mit-scheme の REPL 環境で指定したい任意のラムダ形式で機能します(編集を参照)。私が使用した手順のドキュメントは、mit.edu doc サイトにあります。 get-vars
引用符を取り、lambda
ペアのリストを返します。各ペアの最初の要素はシンボルで、2 番目の要素は によって返される値environment-reference-type
です。
(define (flatten lst)
(cond ((null? lst) ())
((pair? (car lst)) (append (flatten (car lst)) (flatten (cdr lst))))
(else
(cons (car lst) (flatten (cdr lst))))))
(define (get-free-vars proc-form)
(let ((env (ge (eval proc-form user-initial-environment))))
(let loop ((pf (flatten proc-form))
(out ()))
(cond ((null? pf) out)
((symbol? (car pf))
(loop (cdr pf) (cons (cons (car pf) (environment-reference-type env (car pf))) out)))
(else
(loop (cdr pf) out))))))
編集:使用例:
(define a 100)
(get-vars '(lambda (x) (* x a g)))
=> ((g . unbound) (a . normal) (x . unbound) (* . normal) (x . unbound) (lambda . macro))
environment-reference-type
編集 2: コードを変更して、シンボル以外の何かで呼び出されることを防ぐようにしました。
編集 3: サムがコメントで指摘したように、これは、ラムダの下の let にバインドされたシンボルが値を持つものとして表示されません..これに対する簡単な修正があるかどうかはわかりません。したがって、これに関する私の声明lambda
は間違っており、「新しいバインディングフォームを含まない単純なもの」のように読むべきlambda
でした...まあ。