- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
总而言之,我开始研究 Clojure 语言,并且对我正在尝试做的事情有几个问题。主要目标是将序列函数 every?
别名为 all?
。我确信有一个函数或宏可以执行别名(或类似的操作),但我想看看到目前为止我所知道的一些基本构造是否可能。我的方法是定义一个名为 all?
的函数,将其参数应用于 every?
实现。
我很好奇这是否可以变得不可知,所以我想参数化我的别名函数以采用两个参数,新名称(作为关键字)和旧名称(作为函数引用)。在实现这一目标的过程中,我遇到了两个问题。
1) 使用关键字定义命名函数会引发错误。显然它需要 clojure.lang.IObj
。
user=> (defn :foo "bar")
java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.IObj (NO_SOURCE_FILE:0)
是否有一个函数可以将关键字转换为 IObj,或者是否有其他方法可以使用某些提供的值来参数化新定义的函数的名称? (在 Ruby 中,define_method 以及其他技术可以实现此目的)
irb(main)> self.class.instance_eval do
irb(main)* define_method(:foo) { "bar" }
irb(main)> end
=> #<Proc>
irb(main)> foo
=> "bar"
2) 将函数的所有参数收集到单个变量中。即使像 (+ 1 2 3 4)
这样的基本函数也采用可变数量的参数。到目前为止,我见过的所有函数定义技术都采用特定数量的参数,无法将所有内容聚合到列表中以便在函数体中进行处理。再说一遍,我想要的事情是用 Ruby 完成的,如下所示:
irb(main)> def foo(*args)
irb(main)> p args
irb(main)> end
=> nil
irb(main)> foo(1, 2, 3)
[1, 2, 3]
=> nil
感谢您为我提供的任何帮助!
最佳答案
我将用要点来回答,因为这些问题可以整齐地分成许多单独的问题。
隐式包含在接下来的内容中的东西,但也许值得一提:由 def
& Co. 创建的顶级对象(特别是由defn
) 是变量。所以你真正想要做的是给 Var 起一个别名;函数只是没有真正名称的常规值(除非它们可能有一个在其体内本地绑定(bind)到自身的名称;但这与当前的问题无关)。
Clojure 中确实有一个可用的“别名宏”——clojure.contrib.def/defalias
:
(use '[clojure.contrib.def :only [defalias]])
(defalias foo bar)
; => foo can now be used in place of bar
与 (def foo bar)
相比,它的优点是它复制元数据(例如文档字符串);它甚至似乎可以与当前 HEAD 中的宏一起使用,尽管我记得在早期版本中有一个错误阻止了这一点。
变量由符号命名,而不是关键字。 Clojure(和其他 Lisp)中的符号文字不以冒号开头(:foo
是关键字,而不是符号)。因此,要定义一个名为 foo
的函数,您应该编写
(defn foo [...] ...)
defn
是一个帮助宏,允许程序员混合使用 def
,从而简化新函数保持变量的创建> & fn
语法。因此,用预先存在的值(可能是函数)创建 Var 是不可能的,正如创建别名所需要的那样;使用 defalias
或简单地使用 def
来代替。
要创建可变参数函数,请使用以下语法:
(fn [x y & args] ...)
x
和 y
将是必需的位置参数;传递给函数的其余参数(任意数量)将被收集到一个 seq 中,并在名称 args
下可用。如果不需要,则不必指定任何“必需的位置参数”:(fn [& args] ...)
。
要创建一个包含可变参数函数的 Var,请使用
(defn foo [x y & args] ...)
要将函数应用于已组装成可序列对象的某些参数(例如上面示例中的 args
seq 或向量 &c。),请使用 申请
:
(defn all? [& args]
(apply every? args))
如果您想编写函数来创建别名(而不是宏),您需要研究函数 intern
、with-meta
、meta
- 可能还有 resolve
/ns-resolve
,具体取决于函数是否接受符号或变量。我将把填写详细信息作为练习留给读者。 :-)
关于Clojure 元编程问题(针对初学者!),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3183256/
为什么该语言的名称是“Clojure”? 我用谷歌搜索了一下,在#clojure 中询问。到目前为止,还没有运气。 最佳答案 Rich Hickey(他是 Clojure 的设计者)对此的评论是 wi
我不明白为什么升级后会出现以下编译错误: Compiling addr-verify.core Exception in thread "main" java.lang.NoClassDefFound
我试图将从映射操作返回的(惰性)序列传递给另一个映射操作,以便我可以在第一个序列中查找元素。代码从文本文件(以行/列格式)解析一些足球装置,清理它,然后返回一张 map 。 这是代码: (ns fix
我想过滤一组,例如: (filter-set even? #{1 2 3 4 5}) ; => #{2 4} 如果我使用clojure.core/filter我得到一个不是集合的seq: (filte
(defn hi[](+ 5 6)) (hi) (defn hi[](+ 6 7)) (hi) 你好,我是 clojure 的新手。如上所述,我编写了两个具有相同名称的函数。我们可以在 cloj
我按照这个伪代码递归地将十进制转换为二进制。 findBinary(decimal) if (decimal == 0) binary = 0 else binar
我正在尝试学习 Clojure 并尝试定义这个简单的函数: user=> (defn triple [arg] (* 3 arg)) #'user/triple user=> (triple 1) 3
是->和 ->>宏只是为了使代码更具可读性还是它们还有其他特定功能? 最佳答案 线程优先( -> )和线程最后( ->> )是为了使代码更具可读性。但这已经很重要了! 它允许取消嵌套函数调用(示例取自
我在 http://www.learningclojure.com/2010/11/yet-another-way-to-write-factorial.html 上找到了这个代码,但我不明白 pop
我正在阅读 Programming Clojure 2nd edition,在第 49 页它涵盖了 Clojure 的 for 循环结构,它说它实际上是一个序列理解。 作者建议使用以下代码: (def
Clojure 中有双端队列吗?我的印象是 Clojure 的 PersistentQueue 是单端的(我错了吗?)。我需要能够从队列的任一端删除(即“pop”)和“peek”数据。我所说的双端队列
换句话说,有没有办法在看起来不像 (MACRO arg* ...) 的表单上触发宏扩展? . 举一个假设的例子: (defmacro my-var (do (printf "Using my-va
我很难理解懒惰。 有人能帮我理解为什么我下面的函数不是懒惰的吗 (defn my-red ([f coll] (my-red f (first coll) (rest coll) ))
在 Clojure 核心中决定参数函数顺序的规则是什么(如果有的话)? 类似 map 的函数和 filter期望数据结构作为最后一个 争论。 类似 assoc 的函数和 select-keys期待数据
我在 clojuredocs 上遇到过 completing 函数,但目前没有文档。 你能提供一些例子吗? 最佳答案 completing 用于扩充可能没有具有一元“完成”元数的一元重载的二元归约函数
这个现在支持吗?我能找到的唯一信息是来自维基的示例( https://github.com/clojure/core.match/wiki/Deftype-and-defrecord-matching
我正在关注“Clojure in Action”,对此我感到困惑: (defn with-log [function-to-call log-statement ] (fn [& args
对于下面的代码,箭头是宏还是函数名称中的简单字符? (来自 here) (defn file->map [file] ;; TODO ) 最佳答案 箭头是函数名称的一部分。有一个函数定义,不是
Clojure 的 range函数包含来自 start独家在end (如果提供)。核心库中是否有一个函数可以提供完全包含(开始和结束)的范围? 我发现在某些情况下必须调整最终值的代码 - 例如向下而不
当我尝试从 REPL 运行以下代码时(使用动态记录): (defrecord (symbol "rec2") (vec (map symbol ["f1" "f2"]))) 我收到错误 Compile
我是一名优秀的程序员,十分优秀!