Прежде всего, они не ведут себя одинаково, попробуйте сделать еще Lazy.force y
еще раз, и вы заметите разницу, сообщение "World"
больше не печатается, поэтому вычисление не повторяется, так как результат был запомнен в ленивом значении.
Это основное различие между ленивыми вычислениями и thunks. Они оба откладывают вычисления до момента, когда они вынуждены. Но thunk будет оценивать свое тело каждый раз, когда значение lazy будет оцениваться один раз, и результат вычисления будет запомнен.
Под капюшоном ленивое значение реализуется как объект-объект со специальным флагом. Когда среда выполнения сначала вызывает ленивое значение, она заменяет тело thunk результатом вычисления. Итак, после первого вызова Lazy.force y
объект y
фактически стал целым числом 2
. Поэтому последующие звонки в Lazy.force
ничего не делают.