在阅读了很多关于Lisp eval-when运算符的文档后,我仍然无法理解它的用法,我知道使用这个运算符我可以控制表达式的评估时间,但是我无法弄清楚这可能适用的任何例子?
最诚挚的问候,utxeee.
64位Windows 7
Clozure Common Lisp版本1.9 WindowsX8632
Emacs 24.3.1
史莱姆更改日期2014-06-17
我有一个示例.lisp文件,开头如下:
(ql:quickload 'qt)
(in-package "QT")
Run Code Online (Sandbox Code Playgroud)
程序的其余部分显示一个对话框.当我从命令行运行wx86cl -load helloqt.lisp它时,它似乎工作正常.当我从Emacs Slime(C-x C-k)运行它时,它说没有包"QT".但是,如果我首先单独评估第一行(C-x C-e)然后我可以编译整个事情并且它可以工作,模拟尝试在Windows上的Slime内运行QT线程的正常问题.
我如何制作它以便我可以从emacs编译/运行该文件而无需先手动评估第一行?
另外,为什么不在(in-package ...)Slime会话中更改当前包?如果我想与包内容进行交互,我必须手动更改它.
必要的用途eval-when是确保宏编译和使用宏时所依赖的函数是可用的.但是,我想不出一个可以证明不使用后果的例子eval-when.
(defpackage :eval-when
(:use :cl))
(in-package :eval-when)
(defun util-fun (x) (* x x))
(defmacro needs-help (x) `(let ((a (util-fun ,x))) a))
;; use it in the same file
(defun use-the-macro (x) (needs-help x))
(use-the-macro 5)
Run Code Online (Sandbox Code Playgroud)
如果我理解正确,(defun util-fun ...)应该用eval-when.
编辑: 正如你在答案中看到的那样,这个例子有一个问题:它在编译时实际上并没有调用UTIL-FUN.这解释了为什么没有给出错误,因为它不是错误.但问题仍然有效,因为它突出了新用户的困惑.
但是,从REPL开始,在编译,加载或使用期间不会发出错误或警告(SBCL 1.3.20):
; SLIME 2.19
CL-USER> (uiop:getcwd)
#P"/home/anticrisis/dev/common-lisp/eval-when/"
CL-USER> (compile-file "eval-when.lisp")
; compiling file "/home/anticrisis/dev/common-lisp/eval-when/eval-when.lisp" (written 14 AUG 2017 11:30:49 AM):
; compiling (DEFPACKAGE :EVAL-WHEN ...)
; compiling (IN-PACKAGE :EVAL-WHEN)
; compiling …Run Code Online (Sandbox Code Playgroud) common-lisp ×3
eval-when ×3
ccl ×1
compilation ×1
compile-time ×1
emacs ×1
lisp ×1
macros ×1
slime ×1