Схема: правильное применение функции eval?

На работе я столкнулся с основной проблемой при попытке реализовать скрипт конфигурации с помощью Scheme. Чтобы избежать необходимости изобретать искусственный и ограниченный язык, скрипт должен содержать реальный код. Этот код будет оценен позже. Чтобы конфигурация работала как нужно, она должна иметь доступ к определенным переменным. Эти переменные известны только в контексте оценки. Поэтому сценарий конфигурации должен оцениваться в текущей среде. Вот примитивный пример того, о чем я говорю:

(let ((a #t))
  (wr "a is ..."
    (eval '(if a "true" "false"))))

При запуске этого кода я всегда получаю сообщение об ошибке, сообщающее, что переменная 'a' неизвестна. Итак, вопрос: знаете ли вы, как оценивать замороженный код внутри текущей среды?

PS: я использую компилятор bigloo.

///////////////////////////////////////////// РЕДАКТИРОВАТЬ: //////////////////////////////////////////////////////

При использовании подхода, предложенного Крисом, я столкнулся с другой интересной проблемой - использованием ключевого слова case. В следующих двух примерах используется одна и та же конструкция case, которая должна вызывать вывод "yes!" линия. К сожалению, они ведут себя по-разному.

Обычный -> вывод "да!" как и ожидалось:

  (define testit "test")
  (case testit
    (("test")
     (begin (newline) (write "yes!") (newline)))
    (else
      (begin (newline) (write "no!") (newline)))))

С eval -> output на удивление "нет":

  (define env (null-environment 5))
  (eval '(define testit "test") env)
  (eval '(case testit
           (("test")
            (begin (newline) (write "yes!") (newline)))
           (else
            (begin (newline) (write "no!") (newline))))) 

Имеет ли это смысл?

2 ответа

Решение

eval не может получить доступ к лексическим переменным, таким как определенные с помощью let,

Вместо этого вам нужно создать среду и заполнить ее переменными, которые вы хотите сделать доступными. Например:

(define env (null-environment 5))
(eval '(define a #t) env)
(wr "a is ..."
    (eval '(if a "true" "false") env))

Чтобы ответить на ваши изменения, вы не передаете env в качестве аргумента последнему eval. testit не существует в среде, которую создает eval, если этот аргумент не указан.

Это может быть опечатка, но если нет, то это ваша проблема.

Другие вопросы по тегам