Functional programming 函数式编程的副作用(racket)

Functional programming 函数式编程的副作用(racket),functional-programming,racket,Functional Programming,Racket,我想更好地理解函数式语言(如Racket)的副作用 Racket不是一种纯粹的函数式语言,对吗?在书中,它将副作用定义为: 如果它以任何方式影响后续计算(以及最终的程序输出),而不是返回一个值以在周围环境中使用 根据定义,我认为定义,设置或displayln应该是副作用。那么让怎么样呢 区分副作用的最简单方法是什么 有各种可能的定义,但一个常见且有启发性的定义是,副作用是使评估顺序可见的任何东西。也就是说,如果只需替换定义,而不改变程序的结果,就可以按任何顺序简化其任何子表达式,那么程序是纯的(

我想更好地理解函数式语言(如Racket)的副作用

  • Racket不是一种纯粹的函数式语言,对吗?在书中,它将副作用定义为:
  • 如果它以任何方式影响后续计算(以及最终的程序输出),而不是返回一个值以在周围环境中使用

    根据定义,我认为
    定义
    设置
    displayln
    应该是副作用。那么让
    怎么样呢

  • 区分副作用的最简单方法是什么

  • 有各种可能的定义,但一个常见且有启发性的定义是,副作用是使评估顺序可见的任何东西。也就是说,如果只需替换定义,而不改变程序的结果,就可以按任何顺序简化其任何子表达式,那么程序是纯的(没有副作用)。特别是,您始终可以使用变量的定义替换变量,而无需首先对其进行求值


    这意味着I/O、可变状态和异常都是副作用,正如人们所预料的那样。严格地说,它甚至意味着不终止是一种效果——虽然一开始听起来可能有些奇怪,但这正是您在依赖类型语言的情况下想要的。例如,有各种可能的定义,但一个常见且有启发性的观点是,副作用是使评估顺序可见的任何东西。也就是说,如果只需替换定义,而不改变程序的结果,就可以按任何顺序简化其任何子表达式,那么程序是纯的(没有副作用)。特别是,您始终可以使用变量的定义替换变量,而无需首先对其进行求值


    这意味着I/O、可变状态和异常都是副作用,正如人们所预料的那样。严格地说,它甚至意味着不终止是一种效果——虽然一开始听起来可能有些奇怪,但这正是在依赖类型语言的情况下所需要的。例如,如果整个程序没有副作用,它将什么也做不了。在Haskell这样的“纯函数”语言中,纯函数用于描述I/O操作执行的操作(有副作用)。你说的“let”是什么意思?你怎么看
    产生副作用?@Qantas94Heavy,这是不对的,一个程序仍然可以产生结果。Haskell的I/O技巧是,这个结果描述了一个I/O交互,但计算本身并不执行它。@AndreasRossberg blah,愚蠢的我,它当然可以生成一个结果。谢谢你。如果整个计划没有副作用,它将一事无成。在Haskell这样的“纯函数”语言中,纯函数用于描述I/O操作执行的操作(有副作用)。你说的“let”是什么意思?你怎么看
    产生副作用?@Qantas94Heavy,这是不对的,一个程序仍然可以产生结果。Haskell的I/O技巧是,这个结果描述了一个I/O交互,但计算本身并不执行它。@AndreasRossberg blah,愚蠢的我,它当然可以生成一个结果。谢谢你,谢谢你!但是你能给我举个例子吗?我仍然对你提到的“简化子表达式”或“你总是可以用它的定义替换变量,而不需要先计算它。”这句话感到困惑。在Racket中,
    define
    是一种副作用,而
    let
    则不是。我想清楚地知道为什么是这样。@HAruMOmo,
    define
    引入了可变状态,因为您可以在以后更改定义(通过对同一标识符的另一个定义)。因此,使用标识符时很重要。对于
    let
    :如果您使用
    let
    将某个x绑定到一个值V,那么它是不可变的,使用该x将始终导致V。因此,将程序中x的所有用法直接替换为V不会改变程序的结果(假设V本身也是纯的)。同一标识符的确切含义是什么?有趣的是:能够以任何顺序计算表达式的特性称为“谢谢!”!但是你能给我举个例子吗?我仍然对你提到的“简化子表达式”或“你总是可以用它的定义替换变量,而不需要先计算它。”这句话感到困惑。在Racket中,
    define
    是一种副作用,而
    let
    则不是。我想清楚地知道为什么是这样。@HAruMOmo,
    define
    引入了可变状态,因为您可以在以后更改定义(通过对同一标识符的另一个定义)。因此,使用标识符时很重要。对于
    let
    :如果您使用
    let
    将某个x绑定到一个值V,那么它是不可变的,使用该x将始终导致V。因此,将程序中x的所有用法直接替换为V不会改变程序的结果(假设V本身也是纯的)。同一标识符的确切含义是什么?有趣的是:能够以任何顺序计算表达式的属性称为