在编程语言和范例的背景下,"纯粹"意味着什么?

pat*_*515 29 lisp language-agnostic paradigms haskell

换句话说,是什么让一种语言变得纯洁?

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

当我们说纯粹时,这是否意味着他们不具备其他编程范式(这远非事实),还是意味着它们被设计用于那种"纯粹的"X范式?

Chr*_*lor 53

纯粹这个词在不同的语境中有不同的含义.

功能编程

当人们谈论Haskell是一种纯语言时,他们意味着它具有参考透明度.也就是说,您可以使用其值替换任何表达式,而无需更改程序的含义.例如,在Haskell中:

square :: Int -> Int
square x = x * x

main = print (square 4)
Run Code Online (Sandbox Code Playgroud)

表达式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));
}
Run Code Online (Sandbox Code Playgroud)

你不能square(4)用它的值(16)替换它,因为它会改变程序的含义 - 它将不再打印Done! 到stdout.在Haskell中,函数不可能具有打印到stdout或更改内存位置等副作用,因此强制执行引用透明度.

请注意,有了这个纯粹的含义,Lisp 不是一个纯粹的函数式语言,因为它的函数可能有副作用(如果你想要挑剔,Haskell不是一个纯粹的函数式语言,因为它的存在unsafePerformIO,但是每个人都知道你如果你曾经使用过这个功能,那么它就会被送到地狱的一个恶劣的圈子里).

当然,总是可以采用不纯语言的纯粹风格,许多程序员会这样做,以便更容易推理他们的程序.只是引用透明度不是由编译器强制执行的,因为它是纯语言.

纯功能语言的例子包括Haskell,CleanMiranda.不纯函数语言的示例包括OCaml,F#Scheme.

面向对象编程

当人们谈论Smalltalk或Ruby是纯粹的面向对象语言时,他们意味着对象和原始值之间没有区别.在Smalltalk和Ruby,如整数,布尔值和字符的值也是对象,在这个意义上,它们可以接收消息(Smalltalk中),或具有方法(红宝石).例如,你可以做到

1.to_s
Run Code Online (Sandbox Code Playgroud)

在Ruby中,即调用1将其转换为字符串的整数方法.与Java这样的"不纯" OO语言比较一下,其中有物体(这是类的实例,并能有方法等),和原始值(例如int,double,bool,不能有方法).

当一个OO语言是纯粹的时候,人们常说"一切都是一个对象",这不是严格正确的(例如,一个if语句不是一个对象)但是说"每个值都是一个对象" 真的".

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

  • 我的印象是C#中的值类型不能有(非静态)方法,但经过一些看似虚假的研究之后.谢谢你的纠正! (3认同)
  • *这只是因为这样做是返回值(IO monad)的一部分,所以从技术上来说也不是副作用.* - 它不是'在X意义上是真的',它只是'真正'.功能*不*有副作用.也许有时候想到一个将IO动作作为具有副作用的函数返回的函数是有帮助的,但事实并非如此.它是一个返回IO动作的纯函数.你*可以*打印到stdout,但你不是通过调用函数来执行它,而是通过执行IO操作来完成它. (3认同)

Ron*_*son 5

功能语言中的"纯粹"一词可以说是"无国籍",输出不依赖于国家.

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

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