我理解reduce和之间的概念差异apply:
(reduce + (list 1 2 3 4 5))
; translates to: (+ (+ (+ (+ 1 2) 3) 4) 5)
(apply + (list 1 2 3 4 5))
; translates to: (+ 1 2 3 4 5)
Run Code Online (Sandbox Code Playgroud)
然而,哪一个更惯用的clojure?这种方式或其他方式有什么不同吗?从我的(有限的)性能测试来看,似乎reduce更快一些.
我知道cons返回一个seq并conj返回一个集合.我也知道conj将项目"添加"到集合的最佳末端,并cons始终将项目"添加"到前面.这个例子说明了这两点:
user=> (conj [1 2 3] 4) //returns a collection
[1 2 3 4]
user=> (cons 4 [1 2 3]) //returns a seq
(4 1 2 3)
Run Code Online (Sandbox Code Playgroud)
对于矢量,地图和集合,这些差异对我来说很有意义.但是,对于列表,它们似乎相同.
user=> (conj (list 3 2 1) 4) //returns a list
(4 3 2 1)
user=> (cons 4 (list 3 2 1)) //returns a seq
(4 3 2 1)
Run Code Online (Sandbox Code Playgroud)
是否有任何使用列表的示例,其中conjvs cons表现出不同的行为,或者它们是否真的可以互换?换句话说,有一个例子,列表和seq不能等效使用吗?
我正在尝试编写一个简单的筛子函数来计算clojure中的素数.我已经看到了这个关于编写高效的筛分功能的问题,但我不是为了那点呢.现在我只想写一个非常简单(缓慢)的筛子.以下是我的想法:
(defn sieve [potentials primes]
(if-let [p (first potentials)]
(recur (filter #(not= (mod % p) 0) potentials) (conj primes p))
primes))
Run Code Online (Sandbox Code Playgroud)
对于小范围,它工作正常,但导致堆栈溢出大范围:
user=> (sieve (range 2 30) [])
[2 3 5 7 11 13 17 19 23 29]
user=> (sieve (range 2 15000) [])
java.lang.StackOverflowError (NO_SOURCE_FILE:0)
Run Code Online (Sandbox Code Playgroud)
我认为通过使用recur这将是一个非堆栈消耗循环结构?我错过了什么?
我是一个终身面向对象的程序员.我的工作主要是java开发,但我有多种语言的经验.Ruby给了我第一次真正的函数式编程.我喜欢Ruby从功能范例中借用的功能,例如闭包和延续.最终,我毕业于斯卡拉.这是逐步学习以功能性方式处理非平凡问题的好方法.
现在我对Clojure很感兴趣.我知道所有诱人的性感功能(软件事务内存,宏等),但我不能习惯"在lisp中思考".我见过Rich Hickey针对java程序员的截屏视频,但它们主要用于解释语言功能而不是解决现实问题.
我正在寻找任何建议或资源,使其他人更容易过渡.
在完成整个"企业"编程一段时间之后,我对语言本身感到非常失望,如果我不得不回到它,我总是感到非常受阻.你的普通Android应用程序的项目大小并不太吓人,而且库的编码风格实际上相当不错,但如果我能避免使用Java,我肯定会这么做.
这就是问题:我可以避免吗?虽然桌面和服务器上有很多JVM语言可供选择,但Dalvik VM和设备本身也有一些限制.在JIT中2.2这似乎有点好一点,但限制自己到最前沿将是一个相当苛刻的决定.
我所知道的唯一替代方案似乎是Scala.我有可能失踪吗?Clojure似乎完全符合我在Dalvik上面所说明的问题,但由于AppInventor是基于Kawa构建的,因此移动平台上的Lisp可能有希望吗?
还有哪些其他语言可以使用或朝这个方向迈进?
我是Scala的新手,遇到了一个让我烦恼的小打嗝.
并行初始化两个变量很有用: var (x,y) = (1,2)
但是,我无法找到并行分配新值的方法: (x,y) = (x+y,y-x) //invalid syntax
我最终写了这样的东西: val xtmp = x+y; y = x-y; x = xtmp
我意识到编写功能代码是避免这种情况的一种方法,但在某些情况下,vars只是更有意义.
我有两个问题:
1)有更好的方法吗?我错过了什么吗?
2)不允许真正的并行分配的原因是什么?
我正在查看一些示例Fibonacci序列clojure代码:
(def fibs (lazy-cat [1 2] (map + fibs (rest fibs))))
Run Code Online (Sandbox Code Playgroud)
我一般都明白发生了什么,但不明白lazy-cat.我知道这lazy-cat是一个宏,正在翻译成这样的东西:
(def fibs (concat (lazy-seq [1 2]) (lazy-seq (map + fibs (rest fibs)))))
Run Code Online (Sandbox Code Playgroud)
究竟是什么lazy-seq实现的?即使没有,它仍会被懒惰地评估lazy-seq?这是否严格用于缓存目的?
编辑:谢谢你的答案.令我感到困惑的是,它与concatREPL中的一个普通模式一起工作,因为我之前已经在范围内绑定了fibs.
总是提到的软件事务存储器的主要优点之一是可组合性和模块性.可以组合不同的片段以产生更大的组分.在基于锁的程序中,通常情况并非如此.
我正在寻找一个用实际代码说明这一点的简单示例.我更喜欢Clojure中的一个例子,但Haskell也很好.如果该示例还展示了一些无法轻松编写的基于锁的代码,则会获得奖励积分.
什么是创造一个最好的方式Map[K,V]从一个Set[K]从和功能K来V?
例如,假设我有
scala> val s = Set(2, 3, 5)
s: scala.collection.immutable.Set[Int] = Set(2, 3, 5)
Run Code Online (Sandbox Code Playgroud)
和
scala> def func(i: Int) = "" + i + i
func: (i: Int)java.lang.String
Run Code Online (Sandbox Code Playgroud)
什么是最简单的创建方式 Map[Int, String](2 -> "22", 3 -> "33", 5 -> "55")