我想学习Lisp的内部,所以我想看看一切是如何实现的.
例如,
(macroexpand '(loop for i upto 10 collect i))
Run Code Online (Sandbox Code Playgroud)
给了我(在SBCL)
(BLOCK NIL
(LET ((I 0))
(DECLARE (TYPE (AND NUMBER REAL) I))
(SB-LOOP::WITH-LOOP-LIST-COLLECTION-HEAD (#:LOOP-LIST-HEAD-1026
#:LOOP-LIST-TAIL-1027)
(SB-LOOP::LOOP-BODY NIL
(NIL NIL (WHEN (> I '10) (GO SB-LOOP::END-LOOP)) NIL)
((SB-LOOP::LOOP-COLLECT-RPLACD
(#:LOOP-LIST-HEAD-1026 #:LOOP-LIST-TAIL-1027)
(LIST I)))
(NIL (SB-LOOP::LOOP-REALLY-DESETQ I (1+ I))
(WHEN (> I '10) (GO SB-LOOP::END-LOOP)) NIL)
((RETURN-FROM NIL
(SB-LOOP::LOOP-COLLECT-ANSWER
#:LOOP-LIST-HEAD-1026)))))))
Run Code Online (Sandbox Code Playgroud)
但是LOOP-BODY,WITH-LOOP-LIST-COLLECTION-HEAD等仍然是宏.如何完全展开宏窗体?
Common Lisp中有一些读取宏' #' #P,但是如何编写读取宏呢?
像这样:
#T"hello world"
====================>
(gettext "hello world")
Run Code Online (Sandbox Code Playgroud) 我正在学习Common Lisp的宏系统,突然发现了一个问题
(defun hello () (format t "hello ~%"))
(defun world () (format t "world ~%"))
(defmacro call-2-func (func1 func2)
`(,func1)
`(,func2))
(macroexpand-1 '(call-2-func hello world))
(WORLD)
T
Run Code Online (Sandbox Code Playgroud)
好.为什么我不能只从一个宏生成2个LoC?我该如何解决?(预测不会在更复杂的情况下发挥作用......)
(setf list (loop for i from 1 to 12 collect i))
(defun removef (item seq)
(setf seq (remove item seq)))
CL-USER> (removef 2 list)
(1 3 4 5 6 7 8 9 10 11 12)
CL-USER> (removef 3 list)
(1 2 4 5 6 7 8 9 10 11 12)
Run Code Online (Sandbox Code Playgroud)
为什么不removef真正修改变量?
我知道def*可以有docstrings,所以我只是尝试一下lambdas.
令人尴尬的是,以下内容返回NIL.
(documentation (lambda () "a function which always returns nil" nil) 'function)
Run Code Online (Sandbox Code Playgroud)
怎么了?lambdas不能有docstrings吗?有办法吗?
我正在做一个小项目只是为了好玩,我添加eval了对它的支持,使调试更容易.但后来我发现了一个问题:
(let ((x 1))
(eval (1+ x)))
(defun foo (x form)
(eval form))
(foo 1 '(1+ x))
Run Code Online (Sandbox Code Playgroud)
上面的代码不起作用.有人可以解释为什么以及如何解决它?非常感谢.
有没有办法回到运行时的最后状态?简而言之,保存运行时并重新加载它.但核心形象太大了(我正在做一个小游戏:-),所以我提出了一个想法,保存了一些重要的数据,并开始在某一行(也许还有堆栈信息)运行.
例如:
(defun save ()
_do-some-magic-to-save-the-state-and-then-exit_)
(defvar data (list 'a 'b 'c)) ; important data
(format t "Hello ")
(save)
(format t "World!~%")
Run Code Online (Sandbox Code Playgroud)
下次,软件可以从停止的位置开始.
$ software
Hello $ software
Hello $ software --load saved_state
World!
Run Code Online (Sandbox Code Playgroud)
但我根本不知道如何在Common Lisp中做到这一点......有人可以给我一些想法吗?
我想写一些特殊的读者宏:
[hello "world"] ; <=> (funcall #'|hello| "world")
{hello "my" ("world")} ; <=> (apply #'|hello| "my" ("world"))
Run Code Online (Sandbox Code Playgroud)
这可以实施吗?你会怎么做?
我正在写一个服务器(在C中),它服务于不同的机器.我想通过互联网使用D-Bus进行远程过程调用,但我听说D-Bus不能用于很多机器,而是用于一台机器.是对的吗?我可以在这种情况下使用D-Bus吗?