Я тоже читаю SICP, и мне было любопытно определение нормального порядка, данное авторами.Мне это показалось довольно схожим с оценкой Lazy, поэтому я отправился на поиски дополнительной информации, касающейся обоих.
Я знаю, что этот вопрос задавался очень давно, но я посмотрел на FAQ и не нашел упоминания об ответе.старые вопросы, поэтому я решил оставить то, что нашел здесь, чтобы другие люди могли использовать его в будущем.
Это то, что я нашел, и я склонен согласиться с этим:
Я бы сказал (как и другие), что ленивая оценка и NormalOrderEvaluation - это две разные вещи;разница упоминается выше.В ленивом вычислении оценка аргумента откладывается до тех пор, пока он не понадобится, после чего аргумент оценивается и его результат сохраняется (запоминается).Дальнейшее использование аргумента в функции использует вычисленное значение.Операторы C / C ++ ||, && и?: оба примера ленивой оценки.(Если только некоторые новички в программировании на C / C ++ не настолько глупы, чтобы перегружать && или ||, в этом случае перегруженные версии оцениваются в строгом порядке; именно поэтому операторы && и || НИКОГДА не должны перегружаться в C ++).
Другими словами, каждый аргумент вычисляется не более одного раза, а возможно, и вовсе.
С другой стороны, NormalOrderEvaluation переоценивает выражение каждый раз, когда оно используется.Вспомните макросы C, CallByName в языках, которые его поддерживают, и семантику циклических структур управления и т. Д. Оценка нормального порядка может занять гораздо больше времени, чем аппликативная оценка порядка, и может вызывать побочные эффекты более одного раза.(Именно поэтому, конечно, операторы с побочными эффектами обычно не следует указывать в качестве аргументов для макросов в C / C ++)
Если аргумент инвариантен и не имеет побочных эффектов, единственное различие между ними состоит в том, чтоспектакль.Действительно, в чисто функциональном языке ленивый eval можно рассматривать как оптимизацию оценки нормального порядка.При наличии побочных эффектов или выражений, которые могут возвращать другое значение при повторной оценке, оба имеют разное поведение;В частности, нормальный порядок eval имеет плохую репутацию на процедурных языках из-за сложности рассуждений о таких программах без ReferentialTransparency
Следует также отметить, что оценка строгого порядка (а также ленивая оценка) может быть достигнута вязык, который поддерживает оценку нормального порядка через явное запоминание.Противоположность не верна;это требует передачи thunks, функций или объектов, которые могут быть вызваны / переданы для того, чтобы отложить / повторить оценку.
И
Ленивая оценка объединяет нормальный порядокоценка и обмен:
• Никогда не оценивайте что-либо, пока вы не должны (в обычном порядке)
• Никогда не оценивайте что-либо более одного раза (обмен)
http://c2.com/cgi/wiki?LazyEvaluation
http://cs.anu.edu.au/student/comp3610/lectures/Lazy.pdf