What I was trying to do is to declare a function inline. That function
has a macro inside. Depending on whether I declaim it inline or
notinline I get two different outcomes.
Well I assume that we always should get the same outcome
(semantically) independent of whether we declaim something inline or
notinline. Please correct me if I'm wrong.
(in-package :cl-user)
(defpackage :test
(:use :cl))
(in-package :test)
(defmacro foo ()
`(funcall ',(intern "FOOBAR")))
(defun foobar ()
42)
(declaim (inline bar))
(defun bar ()
(foo))
(in-package :cl-user)
;; Apparently the macro inside bar is expanded within the current
package
(defun busted ()
(test::bar))
;; Just for information...
(find-symbol "FOOBAR") ; => FOOBAR, :INTERNAL
;; Error!
(busted)
;;; Lets try it with bar not being inlined.
;;; =======================================
(in-package :test)
(declaim (notinline bar))
(defun bar ()
(foo))
(in-package :cl-user)
(unintern 'foobar) ; GC that
(defun busted ()
(test::bar))
;; Runs fine this time.
(busted)
;; Just for information...
(find-symbol "FOOBAR") ; => NIL, NIL
> Environment: CCL-1.6
>
> What I was trying to do is to declare a function inline. That function
> has a macro inside. Depending on whether I declaim it inline or
> notinline I get two different outcomes.
>
> Well I assume that we always should get the same outcome
> (semantically) independent of whether we declaim something inline or
> notinline. Please correct me if I'm wrong.
Seems like there's a bug in ccl.
Minimal compilation should occur long before inlining...
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
> Seems like there's a bug in ccl.
>
> Minimal compilation should occur long before inlining...
I don't think this follows. The function will be minimally compiled by
the compiler, obviously, but it's not clear that that is what is used
for the inline code: I'd rather assume that essentially the whole
definition is kept around for that and reused, and I don't think the
spec says anything about that. Apart from anything else, you could
declare a function inline without ever compiling it at all.
--tim
I think you're right.
INLINE is specified involves "code",
"... the code for a specified function-name should be integrated into
the calling routine, ..."
but code is defined in such a vague way as to cover source forms too.
The glossary defines code as:
code n. 1. Trad. any representation of actions to be performed,
whether conceptual or as an actual object, such as forms, lambda
expressions, objects of type function, text in a source file, or
instruction sequences in a compiled file. This is a generic term;
the specific nature of the representation depends on its
context. 2. (of a character) a character code.
The section "3.1.2.1.2.2 Macro Forms" specifies that macros are expanded
in the lexical environment, and this is defined excluding special
variables:
lexical environment n. that part of the environment that contains
bindings whose names have lexical scope. A lexical environment
contains, among other things: ordinary bindings of variable names to
values, lexically established bindings of function names to
functions, macros, symbol macros, blocks, tags, and local
declarations (see declare).
including *PACKAGE*.
Therefore, a macro cannot expect *package* to be bound to anything
specific, and:
(defmacro foo ()
`(funcall ',(intern "FOOBAR")))
leads to non-conforming programs.
I would suggest writing it as:
(defmacro foo ()
`(funcall ',(intern "FOOBAR" (load-time-value *package*)))
or:
(defmacro foo ()
`(funcall ',(intern "FOOBAR" (symbol-package 'foo)))
> Therefore, a macro cannot expect *package* to be bound to anything
> specific, and:
>
> (defmacro foo ()
> `(funcall ',(intern "FOOBAR")))
>
> leads to non-conforming programs.
I think ragardless of whether I'm right or not, it certainly is the
case that this kind of thing is a problem waiting to happen!
> (defmacro foo ()
> `(funcall ',(intern "FOOBAR" (symbol-package 'foo)))
Sorry I should have added this to previous post: that's a really nice solution!