Gra*_*Lea 82 io functional-programming scala assignment-operator
Scala分配评估单元而不是分配的值的动机是什么?
I/O编程中的一个常见模式是执行以下操作:
while ((bytesRead = in.read(buffer)) != -1) { ...
Run Code Online (Sandbox Code Playgroud)
但这在Scala中是不可能的,因为......
bytesRead = in.read(buffer)
Run Code Online (Sandbox Code Playgroud)
..返回Unit,而不是bytesRead的新值.
从函数式语言中省略,似乎是一件有趣的事情.我想知道为什么这样做了?
Dav*_*lak 82
我主张让作业返回分配的值而不是单位.马丁和我在它上面来回走动,但他的论点是在95%的时间内将值放在堆栈上是浪费字节码并对性能产生负面影响.
Dan*_*ral 20
我不知道有关实际原因的内幕消息,但我的怀疑非常简单.Scala使得副作用循环难以使用,因此程序员自然会更喜欢理解.
它在很多方面都是这样做的.例如,您没有for声明和变异变量的循环.while在测试条件的同时,你不能(容易地)在循环上改变状态,这意味着你经常需要在它之前和它结束时重复变异.在while块中声明的变量在while测试条件下是不可见的,这使得它变得do { ... } while (...)不那么有用.等等.
解决方法:
while ({bytesRead = in.read(buffer); bytesRead != -1}) { ...
Run Code Online (Sandbox Code Playgroud)
无论它值多少钱.
作为另一种解释,也许Martin Odersky不得不面对一些因这种用法而产生的非常丑陋的错误,并决定将其从他的语言中取缔.
编辑
大卫·波拉克已经回答了一些实际的事实,这显然的事实,同意马丁·奥德斯基自己评价他的回答,让可信的性能相关的问题争论由波拉克提出.
Dan*_*wak 11
这是因为Scala的一部分具有更"正式正确"的类型系统.从形式上讲,转让是纯粹的副作用声明,因此应该返回Unit.这确实有一些很好的结果; 例如:
class MyBean {
private var internalState: String = _
def state = internalState
def state_=(state: String) = internalState = state
}
Run Code Online (Sandbox Code Playgroud)
该state_=方法返回Unit(正如预期的那样),因为赋值返回Unit.
我同意对于复制流或类似的C风格模式,这个特定的设计决定可能有点麻烦.然而,它实际上通常相对没有问题,并且真正有助于类型系统的整体一致性.
也许这是由于命令查询分离原则造成的?
CQS倾向于在OO和函数式编程风格的交集中流行,因为它在具有或不具有副作用的对象方法(即,改变对象)之间产生明显的区别.将CQS应用于变量赋值比平常更进一步,但同样的想法适用.
为什么CQS是有用的简短说明:考虑用一个假设的混合动力F/OO语言List有方法的类Sort,Append,First,和Length.在命令式OO风格中,人们可能想要编写这样的函数:
func foo(x):
var list = new List(4, -2, 3, 1)
list.Append(x)
list.Sort()
# list now holds a sorted, five-element list
var smallest = list.First()
return smallest + list.Length()
Run Code Online (Sandbox Code Playgroud)
而在功能更强大的风格中,人们更有可能写出这样的东西:
func bar(x):
var list = new List(4, -2, 3, 1)
var smallest = list.Append(x).Sort().First()
# list still holds an unsorted, four-element list
return smallest + list.Length()
Run Code Online (Sandbox Code Playgroud)
这些似乎试图做同样的事情,但显然其中一个是不正确的,并且在不知道更多关于方法的行为的情况下,我们无法分辨哪一个.
但是,使用CQS,我们坚持认为如果Append并Sort改变列表,它们必须返回单元类型,从而阻止我们在不应该使用第二种形式时创建错误.因此,副作用的存在也变得隐含在方法签名中.
| 归档时间: |
|
| 查看次数: |
7202 次 |
| 最近记录: |