This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

Inline Functions on CCL-1.6

9 posts · 1852 views

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 declaime 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 bar is recompiled within the current package on CCL-1.6.
(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

Last edited by ramarren on , edited 1 time in total. Reason: Added code tags

Re: Inline Functions on CCL-1.6

I have added code tags to your post. Please use them in the future when quoting code.

This is a bit interesting. I can't see anything in the specification which would say what exactly is inlined, but is seems that the raw forms are inserted, at least in SBCL, so that the macro is expanded only when the function containing the call to the inline function is compiled. Which leads to the effect you describe.

Macros in general shouldn't depend on dynamic variables. Your macro depends on the *package* variable. Such dependencies, and manipulating global state from macros, are brittle, since macro expansion can happen when it is not necessarily expected. Especially when using the interpreter it can happen on every call of any form containing a macro.

Re: Inline Functions on CCL-1.6

Hmm well everything non trivial depends on *package*; that dependency is impossible to avoid (or you have to use qualified names for everything). For example some macro uses CAR which of course depends on *package* to find CAR...

Re: Inline Functions on CCL-1.6

I posted this also on comp.lang.lisp...

Re: Inline Functions on CCL-1.6

FAU wrote:Hmm well everything non trivial depends on *package*; that dependency is impossible to avoid (or you have to use qualified names for everything). For example some macro uses CAR which of course depends on *package* to find CAR...
That is not how Common Lisp works. Macros do not operate on textual representation of the code, but on the list-and-atoms one which is created by the reader. The reader does depends on the value of *package*, but reader is ran predictably, so it is not a problem. By the time macros are expanded the symbols and other objects are fully realized. Symbols have a unique identity which, once the they are read, doesn't depend on their textual representation.

Your issue is caused by using INTERN at macro expansion time, which explicitly depends on *package* unless the optional argument is provided.

Re: Inline Functions on CCL-1.6

Thanks for your reply.

Well the program is just to demonstrate the behaviour I encountered. The example doesn't make much sense as it stands here but is derived from something more realistic.

What I'm trying to find out is whether the behaviour of the above program is defined by the standard. What do you think?

I do think it is a bug.

Re: Inline Functions on CCL-1.6

As I wrote before I don't see anything in the INLINE specification that would require insertion of the compiled code in the caller. I would have perhaps expected that, but it doesn't seem to happen even on SBCL when doing file compilation. Still, I don't think it is a bug as such.

Re: Inline Functions on CCL-1.6

FAU wrote:What I'm trying to find out is whether the behaviour of the above program is defined by the standard. What do you think?
I don't think so:
CLHS wrote:inline specifies that it is desirable for the compiler to produce inline calls to the functions named by function-names; that is, the code for a specified function-name should be integrated into the calling routine, appearing ``in line'' in place of a procedure call.
Note that macro expanders are run in the evaluation environment that is current at the time of their expansion. So, apparently, the semantics between inline code and a function call may differ in the presence of macro expansion whenever the evaluation environments of the inline code and the function definition are not equivalent—and there is nothing in the standard that compels them to be in this case (quite the contrary, in fact, since in-package expressly modifies the evaluation environment when compiled as a top-level form).

Re: Inline Functions on CCL-1.6

Thank you all for your opinions. I do understand the problematic involved here better now.

This was quite a surprise to me that in fact the semantic may change between the inline and the notinline version of a function due to the presence of a macro inside.

The nature of the problem here is that an implementation is given the total freedom to choose how to implement inline functions.

Someone might want to think twice before inlining a function containing a macro.