Схема: почему этот результат при переопределении предопределенного оператора?
Я получил неожиданный результат при переопределении оператора +
в программной программе с использованием guile
. Я должен указать, что это произошло во время экспериментов, чтобы попытаться понять язык; здесь нет попытки написать полезную программу.
Здесь код:
(define (f a b) 4)
(define (show)
(display (+ 2 2)) (display ",") (display (f 2 2)) (newline))
(show)
; guile & mit-scheme: "4,4"
(define (+ a b) 5)
(define (f a b) 5)
(show)
; mit-scheme: "5,5"
; guile: "4,5" - this "4" is the unexpected result
(define (show)
(display (+ 2 2)) (display ",") (display (f 2 2)) (newline))
(show)
; guile & mit-scheme: "5,5"
В guile
функция show
использует предопределенное определение +
даже после того, как я ее переопределил, хотя он использует новое определение f
. Мне нужно переопределить show
, чтобы узнать, что нового определения +
. В mit-scheme
оба новых определения сразу распознаются, что я и ожидал. Кроме того, любые дальнейшие определения +
мгновенно распознаются обоими интерпретаторами без необходимости переопределять show
.
Что происходит за кулисами в guile
, чтобы связать ссылки с этими переопределенными операторами по-разному?
И почему разница между двумя переводчиками?
Ответы
Ответ 1
Похоже, что Guile ошибочно полагает, что никто не настолько сумасшедший, чтобы переопределить +
и делает оптимизацию складывания (+ 2 2) => 4
, делая (display (+ 2 2))
стать (display 4)
. Это объясняет, почему вам нужно переопределить show
, чтобы отразить ваш новый +
.
В самом деле, если вы сначала сделаете (define (+ a b) 4)
в самой верхней части своей программы, Guile не будет делать эту оптимизацию, и вы получите 4,4
и 5,5
так же, как MIT Scheme.
Изменить: На самом деле, похоже, что Guile оптимизирует +
для ссылки на собственную конструкцию +
, что означает, что даже если вы не используете константы (без постоянной сгибания), вы будете по-прежнему не может переопределить +
.