作为函数式语言的新手(几周前我开始接触 Erlang——我能接触到的第一种函数式语言)。
我开始写一些小算法(比如left_rotate_list
, bubble_sort,
merge_sort
ETC。)。我发现自己经常迷失在诸如“我应该使用辅助列表来存储中间结果吗?”之类的决策中。以及“我应该创建一个辅助函数来执行此操作吗?”
一段时间后,我发现函数式编程(如果我所说的根本没有意义,请耐心等待)鼓励“自上而下”的设计:即,当我进行 merge_sort 时,您首先写下所有合并排序步骤,并将它们命名为单独的辅助函数;然后一一实现这些辅助函数(如果需要进一步划分这些辅助函数,请以相同的方法进行)。
这似乎有点违背OO设计,在OO设计中你可以从底层开始构建基本的数据结构,然后将数据结构和算法组装成你想要的东西。
感谢您的评论。是的,我想获得有关如何“用函数式语言思考”的建议(就像“用 Java 思考”、“用 C++ 思考”)。
答案是函数式编程是使用数学中定义的函数进行编程(简而言之,将值从域映射到共域的无副作用的东西)。实际上将其转化为“如何思考”是一个挥手的部分,很难详尽无遗,但我将举例说明我的一些想法:
- 定义比效率更重要。也就是说,人们可以理解其所有行为的明显正确的函数实现比难以推理的复杂优化函数要好。 (并且应该尽可能长时间地被优先考虑;在有证据之前,人们必须破坏这一美好的财产。)
- 数学函数没有副作用。一个有用的程序必然有副作用。函数式程序员意识到副作用是一件非常危险和复杂的事情,并将程序设计为一堆函数,这些函数从一个副作用中获取输出值,并为下一个副作用创建输入值。
第一个与模糊相关:“优雅的代码”。列表推导式可以呈现非常简洁的数学方程,例如函数的定义。只要看一下用 LC 实现的快速排序即可。这就是我对优雅、简洁、让所有行为变得清晰的定义。不是 Perl 代码高尔夫,您通常会简洁而神秘。
第二点是我在所有编程中日常使用的东西。将代码划分为当前状态的函数(方法、例程等),这些函数是无副作用的计算,为下一个要采取的操作提供输入(即使是下一个要采取的操作)。返回值后,将其交给执行所描述操作的例程,然后重新开始。
在我的脑海中,我将 Erlang 过程绘制为状态机图,其中每个顶点都是一个副作用,也是一个函数,其输出是从顶点中选择哪条边。函数式编程范式教会了我对副作用的高度重视。特别是在 Erlang 中,因为副作用在并发性中确实很重要,而 Erlang 使并发性变得非常可用。
同样,一些孤立的部落只有一个词来表示 3 以上的数字,或者没有词来表示“我的”/“你的”。感觉流行语言没有“这会导致副作用”这样的词语,但函数式编程有。它迫使你一直意识到这一点,这是一件好事。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)