在clojure中,这是有效的:
(loop [a 5]
(if (= a 0)
"done"
(recur (dec a))))
Run Code Online (Sandbox Code Playgroud)
但是,这不是:
(let [a 5]
(if (= a 0)
"done"
(recur (dec a))))
Run Code Online (Sandbox Code Playgroud)
所以我想知道:为什么循环和分离,因为它们(至少在概念上)引入词法绑定这一事实?也就是说,为什么循环是一个重复目标,而不是?
编辑:最初写的"循环目标"我注意到是不正确的.
我正在尝试编写一个ELisp宏来根据一些常见数据生成多个函数.例如,当我想要计算fn名称时,我会写出类似的内容(我暂时忽略了卫生,我将符号文字传递给宏,因此评估无关紧要):
(cl-defmacro def-fns (sym)
"SYM."
(let ((s1 (make-symbol (concat (symbol-name sym) "-1")))
(s2 (make-symbol (concat (symbol-name sym) "-2"))))
`(progn (defun ,s1 () (+ 1 2 3))
(defun ,s2 () "six"))))
Run Code Online (Sandbox Code Playgroud)
我希望在调用时生成2个fns,调用foo-1和foo-2.
然后我应该能够像这样调用宏和fns:
(def-fns foo)
(foo-1)
;; => 6
(foo-2)
;; -> "six
Run Code Online (Sandbox Code Playgroud)
甚至(def-fns foo)Emacs 的宏观扩张也表明情况应该是这样的:
(progn
(defun foo-1 nil (+ 1 2 3))
(defun foo-2 nil "six"))
Run Code Online (Sandbox Code Playgroud)
然而,当我评价的def-fns定义和调用它它不会产生这些功能.为什么会这样?这种技术适用于Common Lisp和Clojure(它们具有非常相似的宏系统),那么为什么不在ELisp?
use std::io::ErrorKind;
use std::net::TcpStream;
fn main() {
let address = "localhost:7000";
loop {
match TcpStream::connect(address.clone()) {
Err(err) => { match err.kind() {
ErrorKind::ConnectionRefused => { continue; },
kind => panic!("Error occurred: {:?}", kind),
}; },
Ok(_stream) => { /* do some stuff here */ },
}
}
}
Run Code Online (Sandbox Code Playgroud)
考虑上面的Rust代码.这里有趣的不是Ok分支,而是与ErrorKind::ConnectionRefused子分支相结合loop:它非常便宜,CPU方面,CPU消耗不到1%.这很棒,这就是我想要的.
但我不明白为什么它很便宜:C中的可比代码可能会消耗100%基本上NOP(不精确但足够接近).任何人都可以帮助我理解为什么这么便宜?
给定的是这个s-exp:
(let [temp 30
temp (* temp 9/5)
temp (+ temp 32)]
temp)
Run Code Online (Sandbox Code Playgroud)
忽略算术可以内联的事实,这样的重新绑定temp在Clojure中是否令人反感?为什么/为什么不呢?
假设我定义了一个名为Node的记录:(defrecord Node [tag attributes children]).
这个定义之后,根据文档字符串的defrecord称为工厂函数->Node的定义,以及另一家工厂的功能map->Node和Java类的构造函数Node..
我想知道究竟有什么区别的位置工厂之间的功能->Node和构造Node.,除了从正常的分歧,一方面一个Java类构造函数/方法和另外一个Clojure的函数之间(通过正常的差异,我想的东西就像在Clojure中函数是一流的而事实上的方法不是这样的事实.
我在C++文件中遇到过这个顶级函数.所以我的问题是:
smt2::parser那里的类型声明究竟是什么? p(ctx, is, interactive);什么不同? 这是代码:
bool parse_smt2_commands(cmd_context & ctx, std::istream & is, bool interactive) {
smt2::parser p(ctx, is, interactive);
return p();
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,到目前为止我还没有找到p()grep 的定义.当我找到定义时,我会更新帖子(跟踪标题包括手动可能需要一段时间).