我一直在网上寻找声明性和命令性编程的定义,这将为我提供一些启示.但是,我发现的一些资源中使用的语言令人生畏 - 例如在维基百科上.有没有人有一个现实世界的例子,他们可以告诉我可能会给这个主题带来一些看法(也许在C#中)?
(我希望这个问题是关于主题的 - 我试图寻找答案,但没有找到明确的答案.如果这恰好是偏离主题或已经回答,请缓和/删除它.)
我记得听过/读过关于Haskell 几次是最好的命令式语言的半开玩笑的评论,这当然听起来很奇怪,因为Haskell通常以其功能特性而闻名.
所以我的问题是,Haskell的哪些特性/特性(如果有的话)有理由证明Haskell被认为是最好的命令式语言 - 或者它实际上更像是一个笑话?
这些天我正在认真学习函数式编程.
虽然我对Haskell以及它似乎提供的可能性感到非常兴奋,但我现在也可以看到它需要一段时间来学习.在如何学习Haskell的SO问题中,一个答案表明,实际上"掌握"它需要几个月甚至几年.
现在,我知道C,PHP,一些面向对象的东西等等.并且被告知Haskell在"现实世界"中没有被广泛使用,我会更好地提高我所熟悉的常规语言的技能吗?哈斯克尔值得奋斗吗?
在这个问题上为什么人们认为函数式编程会得出结论似乎是函数式编程将"流行".但是程序编程肯定会保持领先,对吧?
编辑:keparo很好地澄清了我的问题:与过程语言相反,研究Haskell和函数式编程范例对我来说是否有价值?
我遵循Exercism.io上的Rust轨道。我有大量的C / C ++经验。我喜欢Rust的“功能性”元素,但我担心相对性能。
我解决了“游程编码”问题:
pub fn encode(source: &str) -> String {
    let mut retval = String::new();
    let firstchar = source.chars().next();
    let mut currentchar = match firstchar {
        Some(x) => x,
        None => return retval,
    };
    let mut currentcharcount: u32 = 0;
    for c in source.chars() {
        if c == currentchar {
            currentcharcount += 1;
        } else {
            if currentcharcount > 1 {
                retval.push_str(¤tcharcount.to_string());
            }
            retval.push(currentchar);
            currentchar = c;
            currentcharcount = 1;
        }
    }
    if currentcharcount …我应该如何监控clojure中映射函数的进度?
当用命令语言处理记录时,我经常每隔一段时间打印一条消息,以指示事情已经走了多远,例如报告每1000条记录.基本上这是计算循环重复.
我想知道在clojure中我可以采取什么方法,我将一个函数映射到我的记录序列.在这种情况下,打印消息(甚至保持进度计数)似乎基本上是副作用.
到目前为止我想出的是:
(defn report
  [report-every val cnt]
  (if (= 0 (mod cnt report-every))
    (println "Done" cnt))
    val)
(defn report-progress
  [report-every aseq]
  (map (fn [val cnt] 
          (report report-every val cnt)) 
       aseq 
       (iterate inc 1)))
例如:
user> (doall (report-progress 2 (range 10)))
Done 2
Done 4
Done 6
Done 8
Done 10
(0 1 2 3 4 5 6 7 8 9)
是否有其他(更好)的方法来实现这种效果?
我在做什么有任何陷阱?(我认为我保留了懒惰,而不是举个例子.)
有哪些语言可以促进面向对象和函数式编程?我知道任何支持一流功能的语言都可以被认为是功能性的,但我正在寻找一种专门针对两种编码风格的语法.
使用这样的语言,我想象将所有状态更改隔离到单个代码部分,并使程序的其余部分纯粹功能.只是想到它让我流口水(调试天堂!).
到目前为止,我已经发现了Scala,虽然我刚刚听说过它(它看起来很神奇).在这种"混合风格"范式中是否有任何重要的竞争者?
无副作用,引用透明的函数编程的承诺之一是可以广泛优化这样的代码.引用维基百科:
在许多情况下,数据的不可变性可以通过允许编译器在命令式语言中做出不安全的假设来提高执行效率,从而增加强调文本在线扩展的机会.
我想看一些示例,其中函数式语言编译器通过生成更好的优化代码来优于命令式编译器.
编辑:我试图给出一个特定的场景,但显然这不是一个好主意.所以我会尝试以不同的方式解释它.
程序员将想法(算法)翻译成机器可以理解的语言.同时,翻译的一个最重要的方面是人类也可以理解产生的代码.不幸的是,在许多情况下需要权衡:简洁易读的代码会受到性能降低的影响,需要手动优化.这容易出错,耗时,并且使代码的可读性降低(完全不可读).
函数式语言的基础,例如不变性和引用透明性,允许编译器执行广泛的优化,这可以取代手动优化代码和免费程序员进行权衡.我正在寻找想法(算法)及其实现的示例,例如:
如果它有点模糊,我道歉,但我希望这个想法很明确.我不想对答案给予不必要的限制.如果有人知道如何更好地表达它,我愿意接受建议.
我的兴趣不仅仅是理论上的.我想使用这些例子(以及其他内容)来激发学生对函数式编程感兴趣.
起初,我对评论中提出的一些例子并不满意.我想再次反对,这些都是很好的例子.请随意将它们扩展为完整的答案,以便人们可以评论并投票给他们.
(一类这样的例子很可能是并行化代码,它可以利用多个CPU内核.通常在函数式语言中,这可以轻松完成而不会牺牲代码的简单性(比如在Haskell中添加par或pseq在适当的位置).我是对这些例子感兴趣,但也对其他非平行的例子感兴趣.)
optimization performance haskell functional-programming imperative-programming
好的,现在不要作弊.
不,真的,花一两分钟试试这个.
"职位"有什么作用?
编辑:根据cgrand的建议进行简化.
(defn redux [[current next] flag] [(if flag current next) (inc next)])
(defn positions [coll]
  (map first (reductions redux [1 2] (map = coll (rest coll)))))
现在,这个版本怎么样?
def positions(coll) {
  def (current, next) = [1, 1]
  def previous = coll[0]
  coll.collect {
    current = (it == previous) ? current : next
    next++
    previous = it
    current
  }
}
我正在学习Clojure,我很喜欢它,因为我一直很喜欢函数式编程.我花了更长的时间来提出Clojure解决方案,但我很高兴不得不考虑一个优雅的解决方案.Groovy解决方案没问题,但我发现这种命令式编程很无聊和机械化.经过12年的Java,我觉得Clojure的功能和编程是我需要的提升.
对,明白了.好吧,我必须诚实地说,我想知道我几个月后回到它时是否会理解Clojure代码.当然,我可以评论它,但我不需要评论我的Java代码来理解它.
所以我的问题是:这是一个越来越习惯函数式编程模式的问题吗?函数式编程大师是否正在阅读此代码并轻松理解它?您觉得哪个版本更容易理解?
编辑:这段代码的作用是根据玩家的积分计算玩家的位置,同时跟踪那些被捆绑的玩家.例如:
Pos Points
1. 36
1. 36
1. 36
4. …groovy functional-programming clojure imperative-programming
来自Scala编程(第二版),第98页的底部:
对Scala程序员的平衡态度
首选vals,不可变对象和没有副作用的方法.首先到达他们.当您有特定的需求和理由时,请使用变量,可变对象和带副作用的方法.
在前几页解释了为什么更喜欢val,不可变对象和没有副作用的方法,所以这句话很有意义.
但第二句话:"当你有特殊的需要和理由时,使用变量,可变对象和副作用的方法." 没有这么好解释.
所以我的问题是:
什么是使用变量,可变对象和具有副作用的方法的理由或特定需要?
Ps:如果有人可以为每个人提供一些例子(除了解释),那将是很棒的.
根据F#的规格(见§6.5.7),for循环简单的通过整数界(int又名int32又名System.Int32)的限制start和stop,如
for i = start to stop do
    // do sth.
我想知道为什么要求这种类型的for循环的迭代界限int32.为什么不允许uint32?int64?bigint?
我知道序列迭代表达式(for ... in ...)可以迭代任意序列; 然而,这需要分配一个迭代器和调用MoveNext,Current什么不是,因此可能比普通循环效率低得多(增量计数器,比较,条件跳转).为避免这种情况,您将无法使用while和手动递增循环计数器......
奇怪的是,如果表达式包含在序列表达式中,F#确实允许非int32循环边界for,例如
seq { for i = 0I to 10I do
        printfn "%A" i }
所以,我想问题是:是否有一个特殊的原因只允许int32循环?为什么这个限制不适用于表达式中包含的for循环seq?
haskell ×3
clojure ×2
scala ×2
c# ×1
control-flow ×1
f# ×1
for-loop ×1
groovy ×1
inline ×1
lisp ×1
optimization ×1
paradigms ×1
performance ×1
rust ×1