【问题标题】:What does "Pure" mean, in the context of programming languages and paradigms?在编程语言和范式的上下文中,“纯”是什么意思?
【发布时间】:2012-07-21 10:00:36
【问题描述】:

换句话说,是什么让语言变得纯粹?

例如,Smalltalk 被认为是一种纯面向对象的语言。 Haskell 和 Lisp 可以说是纯函数式语言。

当我们说纯粹时,这是否意味着它们无法使用其他编程范式(这与事实相去甚远),还是意味着它们被设计用于“纯粹”的 X 范式?

【问题讨论】:

  • 虽然这是一个有趣的问题,但我认为如果转移到programmers.se会更好
  • Lisp 不是纯粹的函数式语言。
  • 虽然这个问题很理论化,但这个问题有一个明确而明确的答案,不是主观的; “纯”有不同的定义,但它们定义,尽管在不同的上下文中。这个问题可以说是题外话,但它建设性的。 (投票重新开放)

标签: haskell language-agnostic lisp paradigms


【解决方案1】:

函数式语言中的“纯”一词可以说是“无状态”,输出不依赖于状态。

对于命令式语言,您分配 x := 0,但您可以稍后重新分配变量 x 的值。 x 的值取决于当前状态。

但对于纯函数式语言,如果 f(x) = 1,则结果将始终为 1。

【讨论】:

    【解决方案2】:

    这个词在不同的语境中有不同的含义。

    函数式编程

    当人们谈论 Haskell 是一种纯语言时,他们的意思是它有 referential transparency。也就是说,您可以用它的值替换任何表达式,而不会改变程序的含义。例如,在 Haskell 中:

    square :: Int -> Int
    square x = x * x
    
    main = print (square 4)
    

    表达式square 4 可以替换为它的值(16),而不会改变程序的含义。另一方面,在这段 Java 代码中:

    public int square(int x) {
        System.out.println("Done!");
        return (x*x);
    }
    
    public static void main(String [] args) {
       System.out.println(square(4));
    }
    

    您不能将 square(4) 替换为其值 (16),因为它会改变程序的含义 - 它不会再将 Done! 打印到标准输出。在 Haskell 中,函数不可能有副作用,例如打印到标准输出或更改内存位置,因此强制引用透明。

    请注意,对于纯粹的含义,Lisp 不是纯函数式语言,因为它的函数可能会产生副作用(如果你想挑剔的话,Haskell 不是纯函数式语言,因为unsafePerformIO 的存在,但每个人都知道,如果你曾经使用过这个功能,你就会被送入更恶劣的地狱圈子之一。

    当然,在不纯的语言中采用纯的样式总是可能的,许多程序员会这样做是为了更容易推理他们的程序。只是编译器不会强制执行引用透明性,因为它是纯语言。

    纯函数式语言的示例包括HaskellCleanMiranda。不纯函数式语言的示例包括OCamlF#Scheme

    面向对象编程

    当人们谈论 Smalltalk 或 Ruby 是一种纯面向对象的语言时,他们的意思是对象和原始值之间没有区别。在 Smalltalk 和 Ruby 中,整数、布尔值和字符等值也是对象,因为它们可以接收消息 (Smalltalk) 或具有方法 (Ruby)。例如,你可以这样做

    1.to_s
    

    在 Ruby 中,即调用整数 1 的方法,将其转换为字符串。将此与像 Java 这样的“不纯”OO 语言进行比较,其中有对象(它们是类的实例,可以有方法等)和原始值(例如intdoublebool,它们可以'没有方法)。

    当一个面向对象语言是纯的时,人们常说“一切都是对象”,这不是严格正确的(例如,if 语句不是对象)而是 is正确地说“每个值都是一个对象”。

    纯面向对象语言的示例包括RubySmalltalk。不纯的面向对象语言的例子包括JavaC++

    【讨论】:

    • 只是出于好奇,是什么让 C# 成为一种不纯的面向对象语言?据我所知,它确实有一个统一的类型系统(一切都是object),所以0.ToString() 是一个有效的表达式。
    • 我的印象是 C# 中的值类型不能有(非静态)方法,但经过一些研究后发现这是错误的。谢谢指正!
    • 这种描述让 Haskell 听起来毫无用处。您说“在 Haskell 中,函数不可能有副作用,例如打印到标准输出或更改内存位置”。仅在这样做是返回值(IO monad)的一部分的意义上,这才是正确的,因此在技术上不是副作用。但是你让它听起来好像你不能在 Haskell 中打印到标准输出,这是不正确的,你可以。
    • 这是正确的,因为这样做是返回值(IO monad)的一部分,因此在技术上不是副作用。 --它不是“X 意义上的真实”,它只是“真实”。函数没有有副作用。有时将返回 IO 操作的函数视为具有副作用的函数可能会有所帮助,但事实并非如此。它是一个返回 IO 动作的纯函数。您可以打印到标准输出,但您不能通过调用函数来实现,而是通过执行 IO 操作来实现。
    • 当人们谈论 Haskell 是一种纯语言时,他们的意思是它具有引用透明性 - 不完全是;参见例如*.com/q/4865616.
    最近更新 更多