Почему Scheme не поддерживает среды первого класса? - PullRequest
18 голосов
/ 06 марта 2009

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

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

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

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

В своем примере они затем демонстрируют точно использование, которое я хотел бы - элегантный, минималистский способ выполнения стиля "ОО" в схеме ... Они "объединяют" вместе «type», который фактически является тем, что было возвращено специальной формой «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».

Ответы [ 4 ]

12 голосов
/ 09 марта 2009

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

"Специалисты 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 )

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

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

4 голосов
/ 12 января 2010

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

Выезд http://groups.csail.mit.edu/mac/projects/scheme/

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

4 голосов
/ 06 марта 2009

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

1 голос
/ 06 марта 2009

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

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