小编mik*_*era的帖子

用于构造Clojure源代码的惯用法

我对人们如何构建他们的Clojure源代码感兴趣.

习惯于Java,我非常熟悉每个源代码文件一个类的范例,将所有数据和方法定义与适当的注释和注释等捆绑在一起.

然而,Clojure提供了更多的灵活性,我不确定我应该如何构建我的项目(可能最终成为一个中等大小的应用程序,可能是5,000行,有三个或四个不同的子系统)

特别是我正在努力:

  • 我应该使用什么准则来确定代码是否应该在单个命名空间中而不是分隔到不同的命名空间中?
  • 每个协议/数据类型是否应该拥有自己的命名空间+源文件以及相关的一组函数?
  • 我应该何时需要使用其他名称空间?

clojure code-structure

11
推荐指数
1
解决办法
583
查看次数

使用Clojure宏内联函数

更多的是出于对其他任何事情的好奇(但期望它可能偶尔会成为性能调优的有用技巧),是否可以使用Clojure宏来"内联"现有函数?

即我希望能够做到这样的事情:

(defn my-function [a b] (+ a b))

(defn add-3-numbers [a b c] 
  (inline (my-function 
    a 
    (inline (my-function 
      b 
      c)))))
Run Code Online (Sandbox Code Playgroud)

并且它产生(在编译时)完全相同的功能,如同我自己内联添加内容,例如:

(defn add-3-numbers [a b c] 
  (+ a (+ b c)))
Run Code Online (Sandbox Code Playgroud)

compiler-construction macros performance clojure

11
推荐指数
1
解决办法
1585
查看次数

"dotimes"和"for"功能之间的交叉?

我经常发现自己想要使用整数索引(如"dotimes")多次有效地运行Clojure函数,但也将结果作为现成的序列/列表(如"for")得到.

即我想做这样的事情:

(fortimes [i 10] (* i i))

=> (0 1 4 9 16 25 36 49 64 81)
Run Code Online (Sandbox Code Playgroud)

显然,有可能做到:

(for [i (range 10)] (* i i))
Run Code Online (Sandbox Code Playgroud)

但是,如果可能的话,我想避免创建和丢弃临时范围列表.

在Clojure中实现这一目标的最佳方法是什么?

macros loops clojure

11
推荐指数
2
解决办法
1084
查看次数

API设计中的(开始,结束)与(开始,长度)

我已经看到了在指定一系列索引时使用的两种替代约定,例如

subString(int startIndex, int length);
Run Code Online (Sandbox Code Playgroud)

subString(int startIndex, int endIndex);
Run Code Online (Sandbox Code Playgroud)

它们在你可以用它们做什么方面显然是等价的,唯一的区别在于你是指定结束索引还是指定范围的长度.

我假设在所有情况下startIndex都是包容性的,而endIndex是独占的.

在定义API时,是否有任何令人信服的理由更喜欢一个而不是另一个?

language-agnostic api coding-style api-design

11
推荐指数
1
解决办法
415
查看次数

在Clojure deftype中覆盖equals,hashCode和toString

我正在尝试使用deftype在Clojure中创建一个新类型来实现一个二维(x,y)坐标,它实现了一个"位置"协议.

我还想让它实现标准的Java equals,hashCode和toString方法.

我最初的尝试是:

 (defprotocol Location   
   (get-x [p])  
   (get-y [p])   
   (add [p q]))


 (deftype Point [#^Integer x #^Integer y]   
     Location
       (get-x [p] x)
       (get-y [p] y) 
       (add [p q] 
         (let [x2 (get-x q)
               y2 (get-y q)]
           (Point. (+ x x2) (+ y y2))))   
     Object
       (toString [self] (str "(" x "," y ")"))
       (hashCode [self] (unchecked-add x (Integer/rotateRight y 16)))
       (equals [self b] 
         (and 
           (XXXinstanceofXXX Location b) 
           (= x (get-x b)) 
           (= y (get-y b)))))
Run Code Online (Sandbox Code Playgroud)

但是,如果b参数实现了Location协议,则equals方法仍需要一些方法.

什么是正确的方法?我是在正确的轨道上吗?

protocols equals clojure deftype

10
推荐指数
1
解决办法
2851
查看次数

在Clojure中输入函数的提示

我正在尝试解决Clojure中的反射警告,这似乎是由于缺少对普通Java对象的函数返回值的类型推断.

演示此问题的简单示例代码:

(set! *warn-on-reflection* true)    

(defn foo [#^Integer x] (+ 3 x))

(.equals (foo 2) (foo 2))

=> Reflection warning, NO_SOURCE_PATH:10 - call to equals can't be resolved.
   true
Run Code Online (Sandbox Code Playgroud)

解决这个问题的最佳方法是什么?这可以用类型提示完成吗?

java reflection function clojure type-hinting

10
推荐指数
1
解决办法
5279
查看次数

什么是Java中的"公共静态最终"常量的Clojure等价物

我正在编写一些依赖于许多常量的Clojure代码.

它们将在紧密的内部循环中使用,因此通过Clojure编译器+ JVM组合尽可能高效地使用和优化它们非常重要.我通常会在Java中使用"public static final"常量来达到同样的目的.

申报这些的最佳方式是什么?

java optimization performance constants clojure

10
推荐指数
2
解决办法
1800
查看次数

获得适当级别的接口粒度

我目前正在做一些API设计工作,涉及将许多接口的规范作为抽象,稍后将由各种具体类实现.

碰巧,我正在使用Java,但我认为这个问题与任何支持类似界面概念的语言相关.

我注意到之间通常有一个选项:

  • 使用各种方法创建大型界面
  • 创建多个接口,每个接口包含所有方法的子集(单个具体类可能必须实现几个或所有这些接口)

每种方法的优缺点是什么?

java language-agnostic architecture api-design interface

10
推荐指数
1
解决办法
2872
查看次数

如何将Clojure协议扩展到另一个协议?

假设我有两个协议:

(defprotocol A 
  (f [this]))

(defprotocol B 
  (g [x y]))
Run Code Online (Sandbox Code Playgroud)

我想将协议B扩展到支持协议A的所有实例:

(extend-protocol A 
  String 
    (f [this] (.length this)))

(extend-protocol B 
  user.A
    (g [x y] (* (f x) (f y))))
Run Code Online (Sandbox Code Playgroud)

主要动机是避免必须将B分别扩展到A可能扩展到的所有可能的类,或者甚至是其他人可能扩展到A的未知未来类(例如,如果A是公共API的一部分,例如) .

但是这不起作用 - 你会得到如下内容:

(g "abc" "abcd")
=> #<IllegalArgumentException java.lang.IllegalArgumentException: 
No implementation of method: :g of protocol: #'user/B found for 
class: java.lang.String>
Run Code Online (Sandbox Code Playgroud)

这有可能吗?如果没有,是否有一个合理的解决方法来实现相同的目标?

abstraction protocols clojure

10
推荐指数
2
解决办法
2226
查看次数

Java中的键绑定与键侦听器

我注意到在Java/Swing中,似乎至少有两种不同的方法来处理关键事件:

每个人的优点/缺点是什么,何时你更喜欢一个而不是另一个?

java swing key-events keylistener key-bindings

10
推荐指数
2
解决办法
7103
查看次数