Вопрос по – найти свободные переменные в лямбда-выражении

13

Кто-нибудь знает, как я могу определить свободные переменные в лямбда-выражении? Свободные переменные - это переменные, которые не являются частью лямбда-параметров.

Мой текущий метод (который ни к чему меня не приводит) - просто использовать car и cdr для прохождения выражения. Моя основная проблема - выяснить, является ли значение переменной или это один из примитивов схемы. Есть ли способ проверить, оценивает ли что-либо одну из встроенных функций схемы? Например:

(is-scheme-primitive? 'and)
;Value: #t

Я использую схему MIT.

Ваш Ответ

2   ответа
6

Error: User Rate Limit Exceededand:

(let ((and 7)) (+ and 1))

Error: User Rate Limit Exceeded'and.

Error: User Rate Limit ExceededandError: User Rate Limit Exceeded

Error: User Rate Limit Exceededfree-variablesError: User Rate Limit Exceeded

Error: User Rate Limit ExceededexpandError: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit ExceededexpandError: User Rate Limit Exceededlocal-expandError: User Rate Limit Exceeded

Error: User Rate Limit Exceededfree-variables functionError: User Rate Limit ExceededexpandError: User Rate Limit Exceededlocal-expandError: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit Exceeded

Error: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit Exceeded

Error: User Rate Limit ExceededletError: User Rate Limit ExceededlambdaError: User Rate Limit Exceededenvironment-reference-typeError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Ваше решение не работает для любых функций со связующими (например,letError: User Rate Limit ExceededlambdaError: User Rate Limit Exceeded
3
[EDIT 4] Disclaimer; or, looking back a year later:

very

[/EDIT]

but it will work for any lambda form you want to give it in the REPL environment of mit-scheme get-varslambdaenvironment-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

lambdalambda

Error: User Rate Limit ExceededexpandError: User Rate Limit ExceededletError: User Rate Limit ExceededlambdaError: User Rate Limit ExceededletError: User Rate Limit Exceeded
Error: User Rate Limit Exceededenvironment-reference-typeError: User Rate Limit Exceededlambda.
Error: User Rate Limit Exceeded(lambda () (quote x)). flattenError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Justin Kredible
Error: User Rate Limit Exceeded(lambda (x) (let ((y 1)) (+ x y))).

Похожие вопросы