Включает (или будет) C # функции для проверки побочных эффектов? - PullRequest
71 голосов
/ 27 февраля 2009

Я знаю, что C # получает большую поддержку параллельного программирования, но AFAIK до сих пор нет конструкций для проверки побочных эффектов, верно?

Полагаю, теперь сложнее, когда C # уже выложен. Но есть ли планы получить это? Или F # единственный язык .NET, имеющий конструкции для проверки побочных эффектов?

Ответы [ 3 ]

163 голосов
/ 27 февраля 2009

C # язык не такой, но .NET может быть фреймворком.

Библиотека контрактов + инструменты статического анализа, представленные в .NET 4, могли бы представить их так:

Microsoft использует [Immutable] и [Pure] внутри .NET 3.5 framework прямо сейчас.

Например, см. [Microsoft.Contracts.Immutable] и [Microsoft.Contracts.Pure] внутри .NET 3.5 в System.Core.dll. К сожалению, они внутренние. Однако Microsoft.Contracts. * В основном создан на основе исследований Spec #, а Spec # был добавлен в API-интерфейсы Contracts, которые станут частью .NET 4.0.

Посмотрим, что из этого выйдет. Я не проверял, содержат ли биты .NET 4.0, выпущенные до выпуска, какие-либо API-интерфейсы, такие как [Pure] или [Immutable] в API-интерфейсах Contracts. Если они это сделают, я бы предположил, что инструмент для статического анализа будет применять правило, а не компилятор.

edit Я только что загрузил Microsoft.Contracts.dll из последней предварительной версии MS Code Contracts на этой неделе. Хорошие новости: атрибуты [Pure] и [Mutability (Mutability.Immutable)] существуют в библиотеке, что говорит о том, что они будут в .NET 4.0. Woohoo!

edit 2 Теперь, когда вышел .NET 4, я посмотрел эти типы. [Pure] все еще существует в пространстве имен System.Diagnostics.Contracts. Он не предназначен для общего использования, а скорее для использования с API-интерфейсом Контракта до и после проверки условий. Он не применяется компилятором, и инструмент проверки контрактного кода не обеспечивает чистоту . [Изменчивость] исчезла. Интересно, что когда Microsoft использовала атрибуты Mutable и Pure в .NET 3.5 (во внутреннем классе BigInteger в System.Core.dll), .NET 4 переместил BigInteger в System.Numerics и удалил [Pure] и [Mutable] атрибуты этого типа. Итог: кажется, что .NET 4 ничего не делает для проверки побочных эффектов.

edit 3 С недавно выпущенными (в конце 2011 года) инструментами компилятора как службы Microsoft Rosyln, которые, как предполагается, запланированы для RTM в Visual Studio 2015, похоже, они смогут поддерживать такие вещи; Вы можете написать расширения для компилятора, чтобы проверить чистоту и неизменность, и выдавать предупреждения компилятора, если что-то, украшенное этими атрибутами, не следует правилам. Тем не менее, мы рассчитываем на несколько лет, чтобы поддержать это.

edit 4 Теперь, когда Rosyln находится здесь летом 2015 года, возможность создания расширения компилятора для чистой / неизменяемости действительно существует. Тем не менее, это ничего не делает для существующего кода фреймворка или кода сторонней библиотеки. Но на горизонте предложение C # 7 для неизменяемых типов . Это будет выполняться компилятором и введет новое ключевое слово immutable для C # и атрибут [Immutable] в .NET Framework. Использование:

// Edit #4: This is a proposed design for C# 7 immutable as of June 2015.
// Compiler will implicitly mark all fields as readonly.
// Compiler will enforce all fields must be immutable types.
public immutable class Person
{
    public Person(string firstName, string lastName, DateTimeOffset birthDay)
    {
        FirstName = firstName; // Properties can be assigned only in the constructor.
        LastName = lastName;
        BirthDay = birthDay; 
    }

    public string FirstName { get; } // String is [Immutable], so OK to have as a readonly property
    public string LastName { get; }
    public DateTime BirthDay { get; } // Date is [Immutable] too.
}

edit 5 Это ноябрь 2016 года, и кажется, что неизменяемые типы были удалены из C # 7. Всегда есть надежда для C # 8.: -)

edit 6 Это ноябрь 2017 года. C # 8 выходит в полноэкранный режим, и хотя у нас не будет чистых функций, у нас будет структуры только для чтения . Это делает структуру неизменной, что позволяет несколько оптимизаций компилятора.

18 голосов
/ 27 февраля 2009

Мало того, что нет ничего для проверки побочного эффекта - нет ничего даже, чтобы проверить, что тип является неизменным, что является меньшим шагом по тому же маршруту IMO.

Я не верю, что в C # 4.0 что-то происходит (хотя я могу легко ошибаться). Я действительно надеюсь , что неизменность оказывает влияние в C # 5.0; конечно, Эрик Липперт довольно много об этом писал в блоге, и ребята из MS думали о параллелизме довольно много.

Извините, это не более обнадеживающая картина.

Редактировать: Ответ Иуды значительно ярче ... достаточно ли поддержки фреймворка для вас? :) (Я не был бы полностью удивлен, если бы некоторые аспекты контрактов кода не были готовы к .NET 4.0, заметьте - если бы они сохранили первоначальный выпуск относительно небольшим и повысили его позже.) 1013 *

15 голосов
/ 28 февраля 2009

В принципе, проверить, является ли что-то неизменным и нет ли в коде побочных эффектов, легко. Все поля структуры класса / данных должны быть доступны только для чтения, а их тип должен быть другим неизменным объектом. Нам также нужен способ пометить делегата как «чистый» (без побочных эффектов), но, вероятно, все это будет возможно.

Однако проблема в том, что это часто слишком ограничительно. В F # вы обычно пишете код в стиле без побочных эффектов и неизменяемости, но часто полезно использовать некоторые мутации локально. Это не нарушает общую чистоту (в некотором смысле) и значительно облегчает написание кода. Однако проверить это автоматически сложно (это означает, что это интересная теоретическая проблема ..)

Например, прекрасно работать с массивами «чистым» способом. У вас могут быть такие методы, как Array.map , которые применяют некоторую функцию ко всем элементам и возвращают массив new без изменения исходного. Функция мутирует (вновь созданный) массив перед его возвратом, но массив нигде не мутирует, так что в принципе это pure , но его трудно проверить (и это довольно полезный шаблон программирования в F # ).

Итак, я думаю, что многое можно сделать, но просто запретить все побочные эффекты может быть не так хорошо, как кажется. Хорошая вещь о контрактах заключается в том, что они, вероятно, могут быть использованы и в этом сценарии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...