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

StackOverflow https://stackoverflow.com/questions/617325

  •  03-07-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

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

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

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

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

> (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».

Это было полезно?

Решение

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

«Спецификаторы R5RS Eval и Environment-это компромисс между теми, кто глубоко не любит первоклассную среду и хочет ограниченную оценку, и теми, кто не может принять/понять 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))) 

(взято из этот)

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

(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, если я действительно хочу принять полностью объектно-ориентированный стиль, но я думаю, что даже выше это несколько излишне.

Другие советы

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

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

Проверить http://groups.csail.mit.edu/mac/projects/scheme/

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

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

(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)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top