随着新的clojure 1.7我决定了解我可以使用传感器的位置.我明白他们能给予什么好处,但我找不到正常的编写自定义传感器的例子.
好的,我试着测试发生了什么.我打开了clojure文档.并且有一些例子xf用作参数.第一:这个xf或xfrom是什么意思?这个东西产生了身份传感器
(defn my-identity [xf]
(fn
([]
(println "Arity 0.")
(xf))
([result]
(println "Arity 1: " result " = " (xf result))
(xf result))
([result input]
(println "Arity 2: " result input " = " (xf result input))
(xf result input))))
Run Code Online (Sandbox Code Playgroud)
我[result input]从文档示例中获取了变量的命名.我认为它在减少功能的地方result是减少部分并且input是新的集合元素.
所以,当我(transduce my-identity + (range 5))得到结果时10,我期待的结果.然后我读到了eduction,但我无法理解它是什么.无论如何,我做了(eduction my-identity (range 5))并得到了:
Arity 2: nil 0 = nil
Arity 2: nil 1 = nil …Run Code Online (Sandbox Code Playgroud) 关于Common lisp,我无法理解.
假设我正在编写一个类似于此的宏:
(defmacro test-macro ()
(let ((result (gensym)))
`(let ((,result 1))
(print (incf ,result)))))
Run Code Online (Sandbox Code Playgroud)
比我能做的
> (test-macro)
2
2
Run Code Online (Sandbox Code Playgroud)
现在我想看看它是如何扩展的
> (macroexpand-1 '(test-macro))
(LET ((#:G4315 1)) (PRINT (INCF #:G4315))) ;
T
Run Code Online (Sandbox Code Playgroud)
好.使用gensym生成的唯一符号打印为uninterned.
因此,据我所知,未分隔符号是评估者不在内部创建符号数据绑定的符号.
所以,如果我们宏扩展到那个形式,那么应该有一个错误(incf#:G4315).为了测试这个,我们可以在REPL中评估该表单:
> (LET ((#:G4315 1)) (PRINT (INCF #:G4315)))
*** - SETQ: variable #:G4315 has no value
Run Code Online (Sandbox Code Playgroud)
那么为什么扩展到这个字符串的宏工作得很好而表单本身没有呢?
我有一个脚本,需要命令名称和该命令的参数作为参数。
所以我想编写一个完成函数来完成命令的名称并完成该命令的参数。
所以我可以像这样完成命令的名称
if [[ "$COMP_CWORD" == 1 ]]; then
COMPREPLY=( $( compgen -c ${COMP_WORDS[COMP_CWORD]} ))
else
#Don't know what to write here
fi
Run Code Online (Sandbox Code Playgroud)
因此,这将完成可运行的 shell 命令列表的第一个参数。对于第二个和其他参数,我需要完成
${COMP_WORDS[COMP_CWORD]}命令。
我考虑过从 中删除第一个元素COMP_WORDS,减少COMP_CWORD一个并调用一个名称_${COMP_WORDS[0]}
以“_”为命令前缀的函数,因为在许多示例中完成命令的函数都有这样的名称,但是当我complete -p在 bash 中执行时,我发现很多命令由具有不同名称的函数完成。对我来说,这样的解决方案看起来真的很糟糕。
我不是 bash 脚本专家,所以我只是不知道从哪里开始搜索解决方案。
我在空闲时间学习常见的口齿不清,对条件系统有疑问.
当我们处理常见的lisp中的错误时,我们在处理程序中指定错误类型以确定要处理的错误.在引发和处理错误之间,我可以进行一些重启(例如使用restart-case),但我无法在重启时指定错误类型.
例如,假设我有一个带字符串和流的函数,将字符串发送到流并从流中读取响应并返回它.假设如果我的消息错误,我会从流中读取错误响应.我想提出一个错误并绑定一个重新启动,要求这样的新消息:
(defun process-message (stream raw-message)
(let ((response (get-response stream raw-message)))
(restart-case
(when (response-error-p response)
(error 'message-error :text response))
(change-raw-message (msg)
(process-message stream msg)))))
Run Code Online (Sandbox Code Playgroud)
现在假设消息很复杂,我send-command在更高级别获得了另一个函数,可以从某些参数创建消息并调用process-message.我想绑定另一个重启recreate-command-message,允许用户在'message-error获取时从参数发送新命令.这种重启可能是重启的情况process-message,但不完全正确,因为process-message不应该知道这样的高级函数send-command,并且返回值可能不同.
但是现在流错误(例如EOF等)将被抛出recreate-command-message,如果套接字失败,recreate-command-message重启将在某些超级高级socket-error处理程序中可用,并且此重启将是无用的并且惯用错误.
这是一个程序设计问题,应该设计一个程序来避免这样的问题,或者我只是找不到如何将重启绑定到错误类型或者我不正确理解条件系统?
谢谢.
我是clojure的新手,在某个时刻我遇到了问题.
我的程序中有这样的代码:
(let [ ... ]
(map (fn [[v f]] (do-side-effect v f)) {:v1 f1, :v2 f2})
(do-the-job ...))
Run Code Online (Sandbox Code Playgroud)
do-side-effect例如,这可以是println另一种副作用功能intern.问题是副作用不会发生.
但是,如果我改变行
(println (map #(fn [[v f]] (do-side-effect v f)) {:v1 f1, :v2 f2}))
Run Code Online (Sandbox Code Playgroud)
一切都好.所以我最后的想法是,clojure只是优化了map因为它认为它的结果是无用的,因为我不使用它.
如果实际发生这种情况,我怎么能显示这种形式可以产生副作用以阻止编译器优化它?
如果它是一个错误,我怎么能找到错误的位置?