Включает ли (или будет) C# функции для проверки побочных эффектов?
Я знаю, что C# получает большую поддержку параллельного программирования, но AFAIK до сих пор нет конструкций для проверки побочных эффектов, верно?
Полагаю, теперь сложнее, когда C# уже выложен. Но есть ли планы получить это? Или F# единственный язык.NET, имеющий конструкции для проверки побочных эффектов?
3 ответа
C# язык не является, но.NET каркас может быть.
Библиотека Contracts + инструменты статического анализа, представленные в.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. Если они это сделают, я бы предположил, что инструмент для статического анализа будет применять правило, а не компилятор.
Я только что загрузил 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] и [Mutability] атрибуты этого типа. Итог: похоже.NET 4 ничего не делает для проверки побочных эффектов.
edit 3 С недавно (в конце 2011 года) предварительно анонсированными инструментами компилятора как службы Microsoft Rosyln - которые, как полагают, запланированы для RTM в Visual Studio 2015, - похоже, они смогут поддерживать такие вещи; Вы можете написать расширения для компилятора, чтобы проверить чистоту и неизменность, и выдавать предупреждения компилятора, если что-то, украшенное этими атрибутами, не следует правилам. Тем не менее, мы рассчитываем на несколько лет, чтобы поддержать это.
edit 4 Теперь, когда Rosyln находится здесь летом 2015 года, возможность создания расширения компилятора для чистой / неизменности действительно существует. Тем не менее, это ничего не делает для существующего кода фреймворка или кода сторонней библиотеки. Но на горизонте предложение C# 7 для неизменяемых типов. Это будет выполняться компилятором и введет новое неизменяемое ключевое слово в 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.
}
править 5 Это ноябрь 2016 года, и кажется, что неизменяемые типы были удалены из C# 7. Всегда есть надежда для C# 8.:-)
править 6 Это ноябрь 2017 года. C# 8 выходит на первый план, и хотя у нас не будет чистых функций, мы будем иметь структуры только для чтения. Это делает структуру неизменной, что позволяет оптимизировать несколько компиляторов.
Мало того, что нет ничего для проверки побочного эффекта - нет ничего даже, чтобы проверить, что тип является неизменным, что является меньшим шагом по тому же маршруту IMO.
Я не верю, что в C# 4.0 что-то происходит, хотя я могу ошибаться. Я действительно надеюсь, что неизменность влияет на C# 5.0; конечно, Эрик Липперт довольно много об этом писал в блоге, и люди из MS много думали о параллелизме.
Извините, это не более обнадеживающая картина.
Редактировать: ответ Иуды значительно ярче... достаточно ли поддержки фреймворка для вас?:) (Я не был бы полностью удивлен, если бы некоторые аспекты контрактов кода не были готовы для.NET 4.0, заметьте - если, возможно, они сохранили первоначальный выпуск относительно небольшим и увеличили его позже.)
В принципе, проверить, является ли что-то неизменным и нет ли в коде побочных эффектов, легко. Все поля структуры класса / данных должны быть доступны только для чтения, а их тип должен быть другим неизменным объектом. Нам также нужен способ пометить делегата как "чистый" (без побочных эффектов), но это, вероятно, все будет возможно.
Однако проблема в том, что это часто слишком ограничительно. В F# вы обычно пишете код в стиле без побочных эффектов и неизменяемости, но часто полезно использовать некоторые мутации локально. Это не нарушает общую чистоту (в некотором смысле) и значительно облегчает написание кода. Однако проверить это автоматически сложно (это означает, что это интересная теоретическая проблема..)
Например, совершенно нормально работать с массивами "в чистом виде". У вас могут быть такие методы, как Array.map, которые применяют некоторую функцию ко всем элементам и возвращают новый массив без изменения исходного. Функция мутирует (вновь созданный) массив перед его возвратом, но массив нигде не мутирует, так что это в принципе чисто, но трудно проверить (и это довольно полезный шаблон программирования в F#).
Итак, я думаю, что многое можно сделать, но просто запретить все побочные эффекты может быть не так хорошо, как кажется. Хорошая вещь о контрактах в том, что они могут быть использованы в этом сценарии.