Ленивость означает, что функция фактически не оценивается до тех пор, пока (или если) не будет использовано возвращаемое значение. Это означает, что вызовы функций не обязательно оцениваются в порядке их появления в коде. Это также означает, что не может быть пустых функций, потому что они никогда не будут оцениваться (поскольку невозможно использовать возвращаемое значение, которое не существует).
Однако для функций, которые выполняют побочные эффекты (такие как мутация, но также и печать на экране), имеет значение, в каком порядке они выполняются. Еще важнее то, что они казнены вообще. Это означает, что ленивым языкам нужен способ эмулировать побочные эффекты в специальных типах, которые гарантируют, что они выполняются и выполняются в правильном порядке.
Поскольку программы без побочных эффектов бесполезны (вам нужно вообще иметь возможность печатать на экране), ленивые языки действительно поддерживают побочные эффекты. Они просто инкапсулируют их с типами монады ввода-вывода или уникальности. Например, в haskell есть изменяемые массивы, но они могут использоваться только внутри монады ввода-вывода.