【发布时间】:2010-02-25 23:05:03
【问题描述】:
我有一个包含大量字符串常量的 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)
这个问题有更优雅的解决方案吗?
【问题讨论】:
-
为什么
memorize是一个宏?为什么要将identity映射到一个向量,然后创建一个新的结果向量? -
@Mike Douglas:将
memorize设为宏可以消除运行时的函数调用开销(当宏展开时,conj会发生在MEMORY上)。不过同意第二点。 -
这样做的目的是什么?是否要收集字符串用于翻译目的?
-
地图是不必要的,我现在已经删除了。宏是必需的,不是为了性能,而是因为在编译代码时,会跳过宏扩展阶段,MEMORY 将为空。
-
@Stuart 我有一个带有法语语法命名规则的 clojure 文件。一个例子是:在以“[aou]”开头的结尾之前将“c”变成“ç”。我需要一个规则列表,给定法语句子的代码,可以判断应用了哪些规则,以及给定命名规则可以使用该规则生成法语句子的代码(例如“Nous commençons”)。我希望在一个地方定义每个规则的所有数据。