В Меркурий по умолчанию все чисто (даже IO), и невозможно написать нечистый код без использования редко необходимых функций.
Чистый IO обрабатывается аналогичноЧистота (я полагаю), используя уникальность и параметр состояния мира.Однако Mercury считает уникальность свойством mode , а не свойством типа.(«Режим» в этом контексте является более или менее направлением потока данных)
Но у Меркурия также есть система статической чистоты.Некоторый код распознается компилятором как impure (вызовы интерфейса на иностранном языке или известных нечистых функций / предикатов, доступ к изменяемым переменным и несколько других случаев).Такой код должен быть явно объявлен impure
, или это ошибка компилятора.Поскольку компилятор знает о нечистоте, он не выполняет переупорядочения или другие оптимизации, которые могут повлиять на нечистый код.Если на каком-то уровне вы можете обеспечить чистый интерфейс вокруг нечистых операций, вы можете пообещать компилятору, что функция / предикат на самом деле является чистой.В противном случае требуемые декларации примесей распространяются вплоть до предиката main
;если вы готовы сделать это, вы могли бы по сути программировать на Меркурии (хотя это было бы не очень весело).
У Меркурия также есть концепция semipure кода.Это код, который не имеет побочного эффекта при работе любого другого полупрозрачного или нечистого кода (чистый код по определению не подвержен побочным эффектам любого другого кода), но может подвергаться влиянию побочных эффектов от другихнечистый код.Этот дополнительный уровень информации означает, что компилятор может гораздо более свободно оптимизировать вызовы, которые не являются чистыми только потому, что они «видят» побочные эффекты, но сами по себе их не имеют;они могут быть оптимизированы, если их результаты не нужны, и они могут быть переупорядочены до тех пор, пока они не перемещены «поверх» вызова impure
.