Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macros Clojure宏以常量形式收集字符串_Macros_Clojure - Fatal编程技术网

Macros Clojure宏以常量形式收集字符串

Macros Clojure宏以常量形式收集字符串,macros,clojure,Macros,Clojure,我有一个Clojure文件,里面有很多字符串常量。我想通过将这些字符串包装到宏中,将它们收集到集合中。经过几次尝试,我成功了,但我的解决方案看起来相当可怕 (ns Memorable) (def MEMORY (atom [])) (defmacro memorize [s] (swap! MEMORY conj s) s) (prn (str (memorize "hello") " brave new " (memorize "world"))) ; test (defmacro m

我有一个Clojure文件,里面有很多字符串常量。我想通过将这些字符串包装到宏中,将它们收集到集合中。经过几次尝试,我成功了,但我的解决方案看起来相当可怕

(ns Memorable)
(def MEMORY (atom []))
(defmacro memorize [s] (swap! MEMORY conj s) s)

(prn (str (memorize "hello") " brave new " (memorize "world")))  ;  test

(defmacro make-memories-constant [] `(def MEMORIES ~(deref MEMORY)))
(make-memories-constant)

对于这个问题有更优雅的解决方案吗?

就代码清理而言,我会删除
使内存保持常量
宏——您可以这样做

(def MEMORIES @MEMORY)
甚至

(def MEMORY @MEMORY)
为了避免另一个变量将名称空间弄得杂乱无章。只要您在所有调用
MEMORY
之后放置此变量,这将保存
内存
的快照,其中包含所有
MEMORY
d字符串

我想说这实际上是相当干净的,运行时执行的实际代码与没有任何
记忆的情况下没有什么不同

另一种方法是准备一种“记忆框架”,作为一个单独的名称空间,导出一个名为
setup memoration
的宏,比如说,它可能看起来像这样(只是一个粗略的草图,如果没有一些润色,它将无法工作…更新为(不是很彻底)经过测试的版本——这确实有效!…不过,请根据您的需要调整它):

然后你要使用
记忆框架
名称空间,朝名称空间的顶部做
(设置记忆)
来设置事情,调用
记忆
,就像在示例代码中那样,记忆东西,最后使用
结束记忆
定义记忆
将字符串集合存储在变量中的某个位置,并删除用于存储用于构造时存储的原子的临时变量,以及进一步调用
从此名称空间中记住
。(当调用集合时,
end memory
宏的目的是在没有参数的情况下将集合返回到调用它的位置,或者定义一个新的变量来存储它(如果给定一个参数),该参数必须是用于命名变量的符号。更新:我只测试了
defmemtories
版本,因此我将它留在这里并删除。)“就地返回”变量。)

REPL在命名空间
foo
中的交互示例(注意我在
用户
命名空间中定义了
设置记忆
):

这些“评估已中止”。消息表明调用
get memory
memory
会在调用
defmemory
后引发异常。如上所述,这是设计的。另外,
get memory
主要用于简化测试/调试


如果您只打算使用一次,那么设置记忆方法可能会有点过头,但我想如果您更多地使用它,它会为您删除一些样板文件。

就代码清理而言,我会删除
使记忆保持不变
宏——您可以这样做

(def MEMORIES @MEMORY)
甚至

(def MEMORY @MEMORY)
为了避免另一个变量将名称空间弄得杂乱无章。只要您在所有调用
MEMORY
之后放置此变量,这将保存
内存
的快照,其中包含所有
MEMORY
d字符串

我想说这实际上是相当干净的,运行时执行的实际代码与没有任何
记忆的情况下没有什么不同

另一种方法是准备一种“记忆框架”,作为一个单独的名称空间,导出一个名为
setup memoration
的宏,比如说,它可能看起来像这样(只是一个粗略的草图,如果没有一些润色,它将无法工作…更新为(不是很彻底)经过测试的版本——这确实有效!…不过,请根据您的需要调整它):

然后你要使用
记忆框架
名称空间,朝名称空间的顶部做
(设置记忆)
来设置事情,调用
记忆
,就像在示例代码中那样,记忆东西,最后使用
结束记忆
定义记忆
将字符串集合存储在变量中的某个位置,并删除用于存储用于构造时存储的原子的临时变量,以及进一步调用
从此名称空间中记住
。(当调用集合时,
end memory
宏的目的是在没有参数的情况下将集合返回到调用它的位置,或者定义一个新的变量来存储它(如果给定一个参数),该参数必须是用于命名变量的符号。更新:我只测试了
defmemtories
版本,因此我将它留在这里并删除。)“就地返回”变量。)

REPL在命名空间
foo
中的交互示例(注意我在
用户
命名空间中定义了
设置记忆
):

这些“评估已中止”。消息表明调用
get memory
memory
会在调用
defmemory
后引发异常。如上所述,这是设计的。另外,
get memory
主要用于简化测试/调试


如果您只打算使用一次所有这些,那么
设置记忆
方法可能会有些过火,但我想如果您更多地使用它,它会为您删除一些样板文件。

为什么
记忆
是一个宏?为什么要在一个向量上映射
identity
,然后创建一个新的结果向量?@Mike Douglas:make
MEMORY
宏可以消除运行时的函数调用开销(当宏展开时,
conj
MEMORY
)。同意第二点,这是为了什么?你想收集字符串以进行翻译吗?地图没有必要,我现在已经删除了它。宏是必需的,不是为了性能,而是因为在编译代码时,宏扩展阶段被跳过,内存将为空。@Stuart我有一个clojure文件w