首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么引发异常是一种副作用?

为什么引发异常是一种副作用?
EN

Stack Overflow用户
提问于 2012-05-22 13:39:07
回答 5查看 9.5K关注 0票数 50

根据维基百科关于side effect的词条,提出一个例外是一个副作用。考虑下面这个简单的python函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def foo(arg):
    if not arg:
        raise ValueError('arg cannot be None')
    else:
        return 10

使用foo(None)调用它时,总是会遇到异常。同样的输入,同样的输出。它在引用上是透明的。为什么这不是一个纯函数?

EN

回答 5

Stack Overflow用户

发布于 2012-05-23 12:35:27

只有当您观察到异常,并根据它做出更改控制流的决策时,才会违反纯洁性。实际上,抛出异常值在引用上是透明的--它在语义上等同于非终止或其他所谓的bottom values.

如果一个(纯)函数不是total,那么它的计算结果是最低值。如何编码最低值取决于实现-它可能是一个异常;或者不终止,或者除以零,或者其他一些失败。

考虑纯函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 f :: Int -> Int
 f 0 = 1
 f 1 = 2

这并不是为所有输入定义的。对于一些人来说,它的计算结果是底部。该实现通过抛出异常来对此进行编码。它应该在语义上等同于使用MaybeOption类型。

现在,只有在观察最低值时才会破坏引用透明性,并根据它做出决策--这可能会引入非确定性,因为可能会抛出许多不同的异常,而您不知道是哪一个。因此,捕获异常是在Haskell的IO monad中进行的,而生成所谓的"imprecise" exceptions则完全可以完成。

因此,引发异常本身就是一种副作用的说法是不正确的。问题在于是否可以基于异常值修改纯函数的行为,从而破坏引用透明性。

票数 35
EN

Stack Overflow用户

发布于 2012-05-22 13:43:40

从第一行开始:

“在计算机科学中,如果一个函数或表达式除了返回值之外,还修改了某些状态,或者与调用函数或外部世界有可观察到的交互作用,则称其具有副作用。”

它修改的状态是程序的终止。来回答你的另一个问题,为什么它不是一个纯函数。该函数不是纯粹的,因为抛出异常会终止程序,因此它有副作用(您的程序结束)。

票数 16
EN

Stack Overflow用户

发布于 2012-05-22 13:43:55

引用透明性也是用计算本身的结果替换计算(例如函数调用)的可能性,如果你的函数引发异常,你就不能这样做。这是因为异常不会占用计算的一部分,但它们需要被捕获!

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10703232

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文