Подтвердить что ты не робот

Чисто функциональное программирование в D

На мой взгляд, сила функциональной чистоты заключается в том, что глубокие коды кода могут быть проверены как побочные эффекты. Что люди испытывают в масштабах дерева кодов, которые могут находиться внутри чистого спецификатора, и каков уровень повторного использования кода?

Несколько вещей, которые я заметил:

std.algorithm в основном не помечен как pure, но потенциально может быть в значительной степени чистым, либо чистой версией алгоритмов, требующих чистоты функции-экземпляра или mixin, либо самим спецификатором чистоты является статически полиморфным. < ш > Полезные преобразователи, такие как to!string( someInt ), в настоящее время не чисты.

Созданные пользователем структуры, похоже, имеют проблемы (как показано ниже) с помощью: 1. Чистые деструкторы на вложенной структуре
2. чистая postblit-функция даже на не-вложенной структуре

Следующий код в настоящее время дает несколько ошибок в DMD 2.052, выигрывает 32-разрядный

struct InnerStruct
{
    pure this(this) {}
    pure ~this() {}
}

struct OuterStruct
{
    InnerStruct innerStruct;
    pure this(this) {}
    pure ~this() {}
}

pure void somePureFunc()
{
    OuterStruct s1 = OuterStruct(); // pure nested destructor does not compile
    OuterStruct s2 = s1;
    InnerStruct is1 = InnerStruct(); // pure non-nested destructor seems to compile
    InnerStruct is2 = is1; // pure non-nested postblit does not compile
}

void main()
{
    somePureFunc();
}
pure_postblit.d(18): Error: pure function 'somePureFunc' cannot call impure function '__cpctor'  
pure_postblit.d(20): Error: pure function 'somePureFunc' cannot call impure function '__cpctor'  
pure_postblit.d(18): Error: pure function 'somePureFunc' cannot call impure function '~this'  
pure_postblit.d(17): Error: pure function 'somePureFunc' cannot call impure function '~this'  
4b9b3361

Ответ 1

Теоретически точка pure в D состоит в том, что она должна гарантировать, что функция является побочным эффектом независимо от того, как эта функция реализована. В D есть два вида чистоты:

  • Все функции, отмеченные pure, слабо чисты. Они могут не иметь доступа к глобальному изменяемому состоянию (глобальные переменные, переменные потока, переменные static и т.д.) Или выполнять ввод-вывод. Однако они могут изменить свои аргументы. Точка этих функций состоит в том, что они могут быть вызваны из сильно чистых функций (подробно ниже), не нарушая гарантий сильной чистоты.

  • Все функции, которые являются слабо чистыми и, не имеют аргументов с изменяемой косвенностью, являются сильно чистыми. Для этого можно использовать конструкторы типа const и immutable. (При работе с структурами и классами указатель this считается параметром.) Сильно чистые функции обладают всеми хорошими свойствами, о которых говорят функциональные программисты, даже если они реализованы с использованием изменяемого состояния. Сильно чистая функция всегда возвращает одно и то же значение для любых заданных аргументов и не имеет наблюдаемых побочных эффектов. Сильно чистые функции являются ссылочно прозрачными, то есть их возвращаемое значение может быть заменено вызовом к ним с заданным набором параметров, не влияя на наблюдаемое поведение. Любая сильно чистая функция может быть безопасно выполнена параллельно с любой другой сильно чистой функцией.

К сожалению, взаимодействие между общим кодом и pure (а также const и immutable) довольно невелико. Было высказано несколько предложений по исправлению этого вопроса, но пока никто не был принят.
\ std.algorithm записывается как можно более общий, поэтому он не может требовать, чтобы его лямбда-функции и диапазоны, которые он принимает, были чистыми. Кроме того, функции системы типов, которые были добавлены в D2, как правило, являются самыми ошибками в языке, потому что более основные вещи были приоритетными перед устранением соответствующих проблем. Прямо сейчас pure в основном не используется, за исключением тривиальных случаев, таких как std.math.