从Quicklisp包中的宏调用函数 [英] Calling function from macro inside Quicklisp package

查看:83
本文介绍了从Quicklisp包中的宏调用函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我放入了 failing.asd

(in-package :asdf-user)                    

(defsystem "failing"                       
  :description "some code destined to fail"
  :version "0.1"                           
  :author "me"                      
  :components ((:file "package")))         

package.lisp

(defpackage :failing  
  (:export :foo :bar))

(in-package :failing) 

(defun foo () 42)     

(defmacro bar ()      
  (let ((x (foo)))    
    `(print ,x)))     

(bar)                 

进入〜/quicklisp/local-projects/failing .使用安装了Quicklisp的Clozure CL,我运行

into ~/quicklisp/local-projects/failing. Using Clozure CL with Quicklisp installed, I run

(ql:quickload :failing)

这给了我

To load "failing":
  Load 1 ASDF system:
    failing
; Loading "failing"
[package failing]
> Error: Undefined function FOO called with arguments () .
> While executing: BAR, in process listener(1).
> Type :GO to continue, :POP to abort, :R for a list of available restarts.
> If continued: Retry applying FOO to NIL.
> Type :? for other options.

似乎我无法从包内的宏调用函数.为什么不呢?

It seems I can't call a function from a macro inside the package. Why not?

推荐答案

只有在加载文件之前对其进行编译时,才会发生这种情况.通常,它与ASDF(用于管理文件依赖性和编译/加载代码的工具)或程序包(它们是名称空间,与ASDF无关)无关.

That can only happen when the file gets compiled before loaded. Generally it has nothing to do with ASDF (which is a tool to manage file dependencies and to compile/load code) or packages (which are namespaces and are not in any way related to ASDF).

与Common Lisp中文件编译的工作方式有关:

文件编译器看到函数foo并对其进行编译->将其代码写入文件. 它不会(!)将代码加载到编译时环境中.

The file compiler sees the function foo and compiles it -> the code for it gets written to a file. It does not (!) load the code into the compile-time environment.

文件编译器然后看到宏栏并进行编译->代码被写入文件. 确实(!)将代码加载到编译时环境中.

The file compiler then sees the macro bar and compiles it -> the code gets written to a file. It does (!) load the code into the compile-time environment.

文件编译器随后会看到宏格式(bar),并希望对其进行扩展.它调用宏函数bar.哪个会调用foo,它是未定义的,因为它不在编译时环境中.

The file compiler then sees the macro form (bar) and wants to expand it. It calls the macro function bar. Which calls foo, which is undefined, since it is not in the compile-time environment.

解决方案:

  • 将功能定义放入ASDF系统中的单独文件中,并尽早进行编译/加载.

  • put the function definition in a separate file in the ASDF system and compile/load it earlier.

将宏内部的函数作为局部函数

put the function inside the macro as a local function

(EVAL-WHEN (:COMPILE-TOPLEVEL :LOAD-TOPLEVEL :EXECUTE) ...)放在函数定义周围.它使定义在编译时执行.

put (EVAL-WHEN (:COMPILE-TOPLEVEL :LOAD-TOPLEVEL :EXECUTE) ...) around the function definition. It causes the definition to be executed at compile-time.

记住:文件编译器需要了解宏函数->否则,将无法对代码进行宏扩展.普通功能只是在文件的编译过程中被编译而未在编译时加载.

Remember: the file compiler needs to know macro functions -> otherwise it would not be able to macroexpand code. Ordinary functions just get compiled, but not loaded at compile time, during compilation of a file.

这篇关于从Quicklisp包中的宏调用函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆