Подтвердить что ты не робот

Почему Scheme не поддерживает среду первого класса?

Я читал через SICP (структура и взаимодействие компьютерных программ) и был очень рад открыть эту замечательную специальную форму: "make-environment", которую они демонстрируют в сочетании с eval как способ написания модульных код (выдержка из раздела 4.3 "Пакеты" ):

(define scientific-library
  (make-environment
   ...
   (define (square-root x)
    ...)))

Затем они демонстрируют, как это работает с

((eval 'square-root scientific-library) 4)

В своем примере они затем продолжают демонстрировать именно то, что я хочу, - элегантный, минималистский способ сделать стиль "OO" в схеме... Они "минуют" вместе "тип", который на самом деле то, что было возвращено специальной формой "make-environment" (т.е. vtable), и arg ( "состояние" )...

Я был так взволнован, потому что это именно то, что я искал, чтобы сделать полиморфную отправку "по символу" в Схеме без необходимости писать много явного кода или макросов.

то есть. Я хочу создать "объект", который имеет, скажем, две функции, которые я вызываю в разных контекстах... но я не хочу ссылаться на них с помощью "car" и "cdr", я хочу как объявить, так и оценивайте их своими символическими именами.

В любом случае, когда я прочитал это, я не мог дождаться, когда вернусь домой и попробую.

Представьте мое разочарование, когда я испытал следующее на схеме PLT и Chez:

> (make-environment (define x 3))
Error: invalid context for definition (define x 3).
> (make-environment)
Error: variable make-environment is not bound.

Что случилось с "make-environment", как указано в SICP? Все это казалось таким изящным, и именно то, что я хочу, но он, кажется, не поддерживается ни в каких современных переводчиках Scheme?

Какое обоснование? Это просто, что "make-environment" имеет другое имя?

Дополнительная информация найдена позже

Я посмотрел онлайн-версию:

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-28.html#%_sec_4.3

Я читал это первое издание SICP. Второе издание, по-видимому, заменило обсуждение пакетов секцией о недетерминированном программировании и операторе "amp".

4b9b3361

Ответ 1

После еще большего поиска я обнаружил этот информативный поток в новостной сети:

"Спецификаторы R5RS EVAL и среды - это компромисс между те, кто глубоко не любит первоклассные условия и хочет ограниченные EVAL, и те, кто не может принимать/понимать EVAL без второй аргумент, являющийся средой.

Кроме того, найден этот "обход":

(define-syntax make-environment 
  (syntax-rules () 
    ((_ definition ...) 
     (let ((environment (scheme-report-environment 5))) 
       (eval '(begin definition 
                     ...) 
             environment) 
       environment)))) 


(define arctic 
  (make-environment 
    (define animal 'polarbaer))) 

(взято из this)

Тем не менее, я в конечном итоге принял "стиль передачи сообщений" вроде первого предложенного парня - я возвращаю алист функций и получаю общий метод "Отправить" для вызова определенной функции по имени... т.е. что-то как это

(define multiply
  (list
    (cons 'differentiate (...))
    (cons 'evaluate (lambda (args) (apply * args)))))

(define lookup
  (lambda (name dict)
    (cdr (assoc name dict))))

; Lookup the method on the object and invoke it
(define send
  (lambda (method arg args)
    ((lookup method arg) args))

((send 'evaluate multiply) args)

Я читал дальше, и я знаю, что там все CLOS, если я действительно хотел принять полностью стиль OO, - но я думаю, что даже выше немного переборщить.

Ответ 2

У схемы нет первоклассных сред из-за соображений производительности. Когда Scheme был создан, это был не самый быстрый язык из-за отличных вещей, таких как первоклассные функции, продолжения и т.д. Добавление первоклассных сред ухудшило бы производительность еще больше. Так что это был компромисс, сделанный в ранние дни Схемы.

Ответ 3

Они написали это так, потому что MIT Scheme действительно имеет первоклассные среды и, предположительно, то, что авторы планировали обучать своему классу (поскольку книга была написана в MIT).

Отъезд http://groups.csail.mit.edu/mac/projects/scheme/

Тем не менее, я заметил, что MIT Scheme, хотя и несколько активно развивается, испытывает недостаток в многих функциях, которые может иметь действительно современная схема, например, интерфейс внешней функции или поддержка графического интерфейса. Вероятно, вы не захотите использовать его для серьезного проекта разработки программного обеспечения, по крайней мере, не сами по себе.

Ответ 4

Будет ли классическая функция диспетчера работать? Я думаю, что это похоже на то, что вы ищете.

(define (scientific-library f)
  (define (scientific-square-root x) (some-scientific-square-root x))
  (cond ((eq? f 'square-root) scientific-square-root)
        (else (error "no such function" f))))
(define (fast-library f)
  (define (fast-square-root x) (some-fast-square-root x))
  (cond ((eq? f 'square-root) fast-square-root)
        (else (error "no such function" f))))

((scientific-library 'square-root) 23)
((fast-library 'square-root) 23)

Вы даже можете объединить примеры научных и быстрых библиотек в один большой метод отправки:

(define (library l f)
  (define (scientific-library f)
    ...)
  (define (fast-library f)
    ...)
  (cond ((eq? l 'scientific) (scientific-library f))
        ((eq? l 'fast) (fast-library f))
        (else (error "no such library" l))))
(library 'fast 'square-root)