问题标签 [imperative-programming]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
performance - 编译器优化的函数式代码比命令式代码执行得更好的示例
无副作用、引用透明的函数式编程的承诺之一是可以对此类代码进行广泛优化。引用维基百科:
在许多情况下,数据的不变性可以提高执行效率,因为它允许编译器在命令式语言中做出不安全的假设,从而增加内联扩展的机会。
我希望看到函数式语言编译器通过生成更好的优化代码来胜过命令式编译器的示例。
编辑:我试图给出一个特定的场景,但显然这不是一个好主意。所以我会尝试用不同的方式来解释它。
程序员将想法(算法)翻译成机器可以理解的语言。同时,翻译的最重要方面之一是人类也可以理解生成的代码。不幸的是,在许多情况下需要权衡取舍:简洁易读的代码会受到性能缓慢的影响,需要手动优化。这是容易出错、耗时的,并且会降低代码的可读性(甚至完全不可读)。
函数式语言的基础,例如不变性和引用透明性,允许编译器执行广泛的优化,这可以取代手动优化代码并使程序员从这种权衡中解脱出来。我正在寻找想法(算法)及其实现的示例,例如:
- (功能)实现接近原始想法并且易于理解,
- 它被语言的编译器广泛优化,并且
- 如果没有降低其简洁性和可读性的手动优化,很难(或不可能)用命令式语言编写类似高效的代码。
如果有点含糊,我深表歉意,但我希望这个想法很清楚。我不想对答案进行不必要的限制。如果有人知道如何更好地表达它,我愿意接受建议。
我的兴趣不仅仅是理论上的。我想用这样的例子(除其他外)来激励学生对函数式编程产生兴趣。
起初,我对评论中建议的几个例子并不满意。再三考虑,我收回我的反对意见,这些都是很好的例子。请随时将它们扩展为完整的答案,以便人们可以评论和投票。
(一类这样的例子很可能是并行化代码,它可以利用多个 CPU 内核。通常在函数式语言中,这可以很容易地完成,而不会牺牲代码的简单性(比如在 Haskell 中通过添加par
或pseq
在适当的地方)。我是也对此类示例感兴趣,但也对其他非平行示例感兴趣。)
c - 与面向对象相比,对于像 C 这样的命令式语言,对象和实例是否意味着其他东西?
我读到一个正在运行的 C 程序可以称为“实例”。这真的正确吗?实例一词通常用于 OOP。C 也有“对象”不是吗,但它与 OOP 中的不一样。C 中的“对象”只是内存中的某种东西,例如具有某些值的联合,可以称为对象,不是吗?
ocaml - OCaml:在命令式代码中丢弃返回值
我如何成功地丢弃函数的返回值并将其视为返回单元(显然是为了副作用)。显而易见的方法是这样做:
但是,编译器抱怨(带有警告)返回类型some_ignored_thing
不是单位。
我可以发明自己的方法,例如:
这似乎至少简洁并标记了正在发生的事情,但是语言/标准库中是否有任何东西可以实现相同的目标?我原以为这将是一个相对常见的用例。
functional-programming - 具有多个文件的记录的可变字段
我正在处理多个文件,但一个可变字段有问题。在 file1.ml 中,我声明:
所以,在file2.ml 中,我有mytype 类型的元素。但是,当我尝试制作时:
返回以下错误: 错误:未绑定记录字段标签编号。
谢谢,欢迎任何帮助。
for-loop - 为什么简单的 for 循环表达式仅限于整数范围?
根据 F# 规范(参见§6.5.7),简单的 for 循环受整数(int
又名int32
aka System.Int32
)限制start
和stop
,例如
我想知道为什么这种类型的 for 循环的迭代边界必须是int32
. 为什么不允许uint32
?int64
? bigint
?
我知道序列迭代表达式(for ... in ...
)可以迭代任意序列;然而,这需要分配一个迭代器并调用MoveNext
andCurrent
什么不是,因此可能比普通循环效率低得多(增量计数器,比较,条件跳转)。为避免这种情况,您不得不使用while
和手动递增循环计数器......
奇怪的是,如果表达式包含在序列表达式中,F#确实允许非int32
循环边界,例如for
所以,我想问题是:是否有特殊原因只允许int32
循环?为什么这个限制不适用于包含在表达式中的for
循环?seq
while-loop - 在尝试后返回类型
几乎是我第一次尝试在 ocaml 中编写命令式代码来尝试回答这个网站上的问题,但我遇到了一个小问题。
他不喜欢这样,因为他认为这个函数返回单位,就像在 try 块中一样,但是 try 块返回一个 int。因此,如果我在“完成”之后添加 3,它会起作用,但它真的很难看,因为 3 真的永远不会返回。
你怎么做到这一点 ?
python - 将简单的命令式算法转换为函数式风格
我最近做了一个小算法,从一段代码中去掉函数参数,只保留最外层的函数。
我发现这个算法很容易以命令式的方式设计。
但是,我对函数式编程真的很感兴趣,我想知道你将如何以函数式的方式完成同样的事情。
如果你能告诉我这样的算法是如何工作的,那对我很有帮助,所以我可能会更好地了解函数式编程的工作原理。另外我想知道你在设计算法时的思考过程是什么。
我在 Python 中制作了命令式版本,但您的答案不一定是在 Python 中;haskell 或任何其他语言也可以。
这是它的作用(将字符串作为输入并返回一个字符串):
这是我的命令式代码:
paradigms - 命令式编程范式必须遵守前向声明规则吗?
在我的语言编程课程的考试中,这个问题是:
下一个程序在命令式编程中有效吗?
没有指定或语法,或语法,或任何额外的东西。我的回答是肯定的,因为最终可能会有一种语言、一种语法和一种语法设计来有效地使用 z 而无需声明它并稍后“重新声明”z。我的成绩是 0.0,但我仍然觉得不公平。可以帮助澄清这个问题吗?感谢。
prolog - Prolog 'is/2' 谓词实现
'is/2' Prolog 谓词是如何实现的?我知道
相当于
但是谓词是使用命令式编程实现的吗?换句话说,实现是否等同于以下 C 代码?
还是使用声明式编程和其他谓词来实现?