函数式编程是命令式编程的子集吗?
函数式编程的主要特征之一是使用无副作用函数。然而,这也可以用命令式语言来完成。对于递归和 lambda 函数(例如 C++0x)也是如此。因此我想知道命令式编程语言是否是函数式编程语言的超集。
One of the main characteristics of functional programming is the use of side-effectless functions. However, this can be done in an imperative language also. The same is true for recursion and lambda functions (for example C++0x). Therefore I wonder whether imperative programming languages are a superset of functional ones.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
我真的不能说它们是否是彼此的子集。不过,我可以告诉你的是(除了真正深奥的语言)它们都是图灵完备 ,这意味着最终它们都同样强大,但不一定具有同样的表现力。
I can't really say whether they are subset of one another. What I can tell, though, that (except for really esoteric languages) they are all Turing-complete, which means that in the end they're all equally powerful, but not neccesarily equally expressive.
一般来说,不会;函数式编程是声明式编程的子集(包括逻辑编程语言,如 Prolog)。许多命令式语言借用了函数式编程语言的元素,但仅仅拥有 lambda 或引用透明函数并不能使命令式语言具有函数式功能;函数式编程不仅仅涉及这些元素。
Generally speaking, no; functional programming is a subset of declarative programming (which includes logic programming languages, like Prolog). Many imperative languages borrow elements from functional programming languages, but simply having lambdas or referentially-transparent functions does not make an imperative language functional; functional programming is about more than just these elements.
可以用本身不支持编程范式的语言来实现某种编程范式。例如,可以用 C 语言编写面向对象代码,但它并不是为此目的而设计的。
函数式编程本身就是一种成熟的编程范式,最好通过 Haskell、LISP 等语言来学习。在你学好它们之后,即使你不经常使用这些语言,你也可以开始在您定期使用的日常语言。
有些人可能喜欢在 Google 上搜索 C 语言面向对象编程
It is possible to implement a certain programming paradigm in a language which doesn't support the programming paradigm natively. For example its possible to write Object Oriented Code in C while it is not designed for this purpose.
Functional programming is a well developed programming paradigm of its own and is best learnt through languages like Haskell, LISP etc. And after you have learnt them well, even though you don't use these languages regularly, you may start using those principles in the day to day language you use on regular basis.
Some people may like to Google for Object oriented programming in C
范式是一种做事的方式,有两种主要的编程范式:命令式和声明式。某些语言允许混合两种范式这一事实并不意味着一种语言包含在另一种范式中,而是这些语言是多范式的。
为了进一步澄清这一点,让我继续你的类比:如果 Lisp 和 OCaml(例如)被视为函数式语言,并且它们都允许命令式风格……那么命令式是否应该被视为函数式语言的子集?
A paradigm is a way of doing things, and there are two main programming paradigms: imperative and declarative. The fact that some languages allow to mix both paradigms doesn't mean that one is included in the other, but that the languages are multi-paradigm.
To clarify it a little bit more, let me continue with your analogy: if Lisp and OCaml (for example) are considered functional languages, and both of them allow imperative style... then should imperative be considered a subset of functional?
大多数命令式语言没有作为一阶类型的函数,而大多数函数式语言都具有一阶类型。 (与 C++ 一样,通过 boost::function。)
通过一阶类型,这意味着值/变量可以是任何类型,int、bool、int->bool 中的函数。它通常还包括闭包或绑定值,其中您具有相同的函数,但已经填充了一些参数。
恕我直言,这两个是函数式编程的主要内容。
Most imperative languages don't have functions as first-order types, whereas most functionald o. (As does C++, via boost::function.)
By first-order type, this meas a value/variable can be of any type, an int, a bool, a function from int->bool. It usually also includes closures or bound values as well, where you have the same function, but some arguments are already filled in.
Those two are what functional programming is mostly about, IMHO.
我认为区分范式和语言可能会有所帮助。
对我来说,范式代表“思维方式”(概念和抽象,例如函数、对象、递归),而语言提供 “做事的方式”(语法、变量、评估)。
所有真正的编程语言都是等价的,因为它们都是图灵完备的,并且理论上能够计算任何图灵可计算的函数以及模拟或被模拟通用图灵机。
有趣的是,用某些语言或范式完成某些任务有多困难,工具对任务有多合适。即使康威的生命游戏也是图灵完备的,但这并不会让我想用它来编程。
许多语言支持多种范式。 C++ 被设计为 C 的面向对象扩展,但可以在其中编写纯过程代码。
随着时间的推移,一些语言借用/获取了其他语言或范例的功能(只需看看 Java 的演变)。
有些语言,比如 Common Lisp,是令人印象深刻的多范式语言。在 Lisp 中可以编写函数式、面向对象或过程式代码。可以说,面向方面已经是 Common Lisp 对象系统的一部分,因此“没什么特别的”。在 Lisp 中,很容易扩展语言本身来完成您需要它做的任何事情,因此它有时被称为“可编程编程语言”。 (我会在这里指出,Lisp 描述了一系列语言,而 Common Lisp 只是其中一种方言)。
我认为声明性、命令式、功能性或程序性等术语中的哪一个是其中的子集并不重要。更重要的是了解您正在使用的工具语言,以及它们与其他工具的不同之处。更重要的是理解范式所代表的不同思维方式,因为这些是你的思维工具。与生活中的大多数其他事情一样,您了解得越多,您就会变得越有效。
I think it might be helpful to draw a distinction between paradigm and language.
To me, paradigms represent "ways of thinking" (concepts and abstractions such as functions, objects, recursion), whereas languages offer "ways of doing" (syntax, variables, evaluations).
All true programming languages are equivalent in the sense that they are Turing-complete and able, in theory, to compute any Turing-computable function as well as simulate or be simulated by a universal Turing machine.
The interesting thing is how difficult it is to accomplish certain tasks in certain languages or paradigms, how appropriate the tool is to the task. Even Conway's Game of Life is Turing-complete, but that does not make me want to program with it.
Many languages support a number of paradigms. C++ was designed as an object-oriented extension for C, but it is possible to write purely procedural code in it.
Some languages borrow/acquire features from other languages or paradigms over time (just look at the evolution of Java).
A few languages, like Common Lisp, are impressively multi-paradigm languages. It is possible to write code that is functional, object oriented or procedural in Lisp. Arguably, aspect-orientation is already part of the common lisp object system, and therefore "nothing special". In Lisp, it is easy to extend the language itself to do whatever you need it to do, thus it is sometimes called the "programmable programming language". (I'll point out here that Lisp describes a family of languages of which Common Lisp is only one dialect).
I think it doesn't matter which of the terms, declarative, imperative, functional or procedural, is a subset of which. What matters more is to understand the tools languages you're working with, and how those are different from other tools. Even more important is to understand the different ways of thinking that the paradigms represent, since those are your thought-tools. As with most other things in life, the more you understand, the more effective you become.
看待它的一种方法(并不是说这是正确的方法,因为我无论如何都不是语言设计师或理论家)是如果语言本质上被转换为其他东西,那么“某种东西” else' 必须是源的超集。所以字节码必然是Java的超集。 .NET IL 是 C# 和 F# 的超集。因此,C# 中的函数结构(即 LINQ)是 IL 命令式结构的子集。
由于机器语言是命令式的,因此您可以采取这样的立场:所有语言都是命令式的,因为它们只是对人类有用的抽象,然后由编译器将其分解为过程式命令式机器代码。
One way to look at it (not saying it's the right way 'cos I'm not a lang designer or theorist by any means) is that if the language is essentially converted to something else then that 'something else' must be the superset of the source. So bytecode is necessarily a superset of Java. .NET IL is a superset of C# and of F#. The functional constructs in C# (i.e. LINQ) are thus a subset of the imperative constructs of IL.
Since machine language is imperative, you could take the position that, therefore, all languages are imperative, because they are just abstractions useful for humans that are then boiled away by the compiler to procedural, imperative machine code.
例如,模式映射之类的
东西在命令式语言中是不可用的。
还具有类似柯里化函数的构造:
在大多数命令式语言中不可用
Pattern mapping like
is something that is for instance one thing that is not available in imperative languages.
Also constructs like curried functions:
is not available in most imperative languages
是的,函数式编程是命令式编程的一个子集,但是...
是的,因为函数式编程中没有任何东西是你不能在命令式编程中执行(尽管存在语法差异)。您可以用命令式语言“进行”函数式编程。
但是...
你不能做的事情是函数式编程的关键特性。
通过限制你能做的事情,
函数式编程的其他好处更加主观。
你经常听到这些争论。
这是一个可疑的好处。
首先,只有意外副作用才是不好的。正确的编程实践,例如限制对特权代码的状态修改,可以减轻副作用问题。
其次,函数式编程没有内部状态。如果程序有 IO(访问文件、网络、硬件),那么您就有外部状态,因此可能会产生副作用。
在某些方面是的,比如知道异常的显式路径。
但是,检查状态是函数式编程所不具备的调试优势。
仅当您流利函数式编程并且不流利命令式编程时,这才是正确的。
作为一个人,我对命令式编程更加熟练,发现这个论点是错误。
Yes, functional programming is a subset of imperative programming, but...
Yes, because there is nothing in functional programming that you can't do in imperative programming (syntax differences notwithstanding). You can "do" functional programming in an imperative language.
But...
The things you can't do are the key features of functional programming.
By limiting what you can do,
Other benefits of functional programming are more subjective.
You often hear these arguments.
This is a dubious benefit.
First, only unintended side effects are bad. Proper programming practices, such as limiting modification of state to privileged code, alleviate side effect issues.
Second, functional programming only has no internal state. If the program has IO (accessing files, network, hardware) you have external state, thus the potential of side effects.
In some ways yes, like knowing the explicit path to an exception.
But having state to examine is a debugging benefit that functional programming does not have.
This is only true if you are fluent in functional programming and not fluent in imperative programming.
I for one, being more fluent in imperative programming, find this argument to be false.