Joa*_*nge 72 .net c# parallel-processing f# immutability
我知道C#获得了很多并行编程支持,但是AFAIK仍然没有副作用验证的构造,对吧?
我认为现在C#已经布局了,现在更棘手了.但是有计划将其纳入其中吗?或者F#是唯一具有副作用验证结构的.NET语言吗?
Jud*_*ngo 165
C#语言不是,但.NET可能是框架.
.NET 4中引入的Contracts库+静态分析工具可能会引入以下内容:
Microsoft现在正在.NET 3.5框架中使用[Immutable]和[Pure].
例如,请参阅System.Core.dll中.NET 3.5中的[Microsoft.Contracts.Immutable]和[Microsoft.Contracts.Pure].不幸的是,他们是内部的.但是,Microsoft.Contracts.*主要来自Spec#research,而Spec#已被折叠到将成为.NET 4.0一部分的Contracts API中.
我们会看到这是什么.我没有检查预发布的.NET 4.0位是否包含Contracts API中的[Pure]或[Immutable]等API.如果他们这样做,我认为静态分析工具将是强制执行规则的工具,而不是编译器.
编辑我刚刚从本周最新的MS Code Contracts预发布版本中加载了Microsoft.Contracts.dll .好消息:库中存在[Pure]和[Mutability(Mutability.Immutable)]属性,这表明它们将在.NET 4.0中.哇噢!
编辑2现在已经发布了.NET 4,我查找了这些类型.[Pure]仍然存在于System.Diagnostics.Contracts命名空间中.它不是用于一般用途,而是用于Contract API的条件前和条件后检查.它不是编译器强制执行的,代码合同检查工具也没有强制执行纯度.[可变性]消失了.有趣的是,微软在.NET 3.5中使用Mutability和Pure属性(在System.Core.dll的内部BigInteger类中),.NET 4已经将BigInteger移动到System.Numerics中,并剥离了[Pure]和[Mutability]该类型的属性.底线:似乎.NET 4对副作用验证没有任何作用.
编辑3随着最近(2011年末)预览的Microsoft Rosyln编译器即服务工具 - 被认为是在Visual Studio 2015中安排用于RTM - 看起来他们将能够支持这样的东西; 您可以编写扩展编译器以检查纯度和不变性,并在使用这些属性修饰的内容不符合规则时发出编译器警告.即便如此,我们还是花了几年时间来支持这一点.
编辑4现在Rosyln从2015年夏天开始就在这里,确实存在为纯/不可变性构建编译器扩展的能力.但是,这对现有框架代码和第三方库代码都没有任何作用.但即将出现的是针对不可变类型的C#7提案.这将由编译器强制执行,并将为C#引入一个新的immutable关键字,并在.NET框架中引入一个[Immutable]属性.用法:
// 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.
}
Run Code Online (Sandbox Code Playgroud)
编辑5这是2016年11月,似乎从C#7中删除了不可变类型.C#8总是有希望.:-)
编辑6这是2017年11月.C#8正在全面展开,虽然我们没有纯粹的功能,但我们将拥有只读结构.这使得结构不可变,这允许多个编译器优化.
Tom*_*cek 15
原则上,验证某些东西是否不可变以及代码是否缺乏副作用很容易.类/数据结构的所有字段必须是只读的,并且它们的类型必须是另一个不可变对象.我们还需要一种方法来将代表标记为"纯粹"(无副作用),但这可能都是可能的.
但问题是,这通常限制太多.在F#中,您通常以副作用自由和不可变的样式编写代码,但在本地使用某些变异通常是有益的.这不会破坏整体纯度(在某种意义上)并且使编写代码更容易.但是,自动验证这一点很困难(意味着它是一个有趣的理论问题......)
例如,以"纯粹"的方式处理数组是完全正确的.您可以使用Array.map等方法将一些函数应用于所有元素,并返回一个新数组而不修改原始数组.该函数在返回之前改变了(新创建的)数组,但是数组在其他任何地方都没有变异,所以这原则上是纯的,但很难验证(这在F#中是非常有用的编程模式).
所以,我认为可以做很多事情,但是简单地禁止所有副作用可能不像看起来那么好.合同的好处是它们也可能在这种情况下使用.
| 归档时间: |
|
| 查看次数: |
13800 次 |
| 最近记录: |