Почему мы не видим ошибку при вводе (или #t (/ 1 0)) в оболочку Racket? - PullRequest
0 голосов
/ 27 сентября 2018
(or #t (/ 1 0))

(/ 1 0) - это illegle, но почему мы не видим ошибку?

В моей лекционной записке есть объяснение.

Идентификатор or делаетне относится к функции, а скорее к синтаксической форме, которая реализует короткое замыкание.

Но я все еще не совсем понимаю.

1 Ответ

0 голосов
/ 27 сентября 2018

Ключевой частью является то, что or является синтаксической формой , как упоминалось в ваших примечаниях к лекции.Это означает, что правила оценки отличаются от обычной процедуры и могут быть реализованы на уровне интерпретатора или (более вероятно) как производное выражение или макрос.Если бы мы попытались реализовать or как процедуру, ваш пример действительно потерпел бы неудачу:

(define (my-or a b)
  (if a a b))

(my-or #t (/ 1 0))
=> /: division by zero

Процедуры оценивают все свои аргументы перед передачей их в тело.Напротив, or оценивает свой первый аргумент, если он верен, он возвращает значение первого аргумента, в противном случае он возвращает результат вычисления второго аргумента - но он никогда не оценит второй аргумент, еслиПервый был правдивым.Это известно как оценка «короткого замыкания» логических коннекторов, и нечто подобное происходит с and.

Чтобы лучше понять, что происходит под капотом, прочитайте главу 4 SICP, вот соответствующаяссылка, объясняющая производные выражения .Цитата: «Некоторые специальные формы в нашем языке могут быть определены в терминах выражений, включающих другие специальные формы, а не реализованы напрямую».В этом случае or может быть реализовано с использованием if, что, в свою очередь, также является синтаксической формой, реализованной в качестве особого случая в процедуре оценки интерпретатора.

...