Inline Functions on CCL-1.6

Discussion of Common Lisp
Post Reply
FAU

Inline Functions on CCL-1.6

Post by FAU » Fri Feb 11, 2011 2:48 pm

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.

Code: Select all

(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 Fri Feb 11, 2011 3:01 pm, edited 1 time in total.
Reason: Added code tags

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Inline Functions on CCL-1.6

Post by ramarren » Fri Feb 11, 2011 3:20 pm

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.

FAU

Re: Inline Functions on CCL-1.6

Post by FAU » Fri Feb 11, 2011 6:32 pm

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...

FAU

Re: Inline Functions on CCL-1.6

Post by FAU » Fri Feb 11, 2011 6:46 pm

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

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Inline Functions on CCL-1.6

Post by ramarren » Sat Feb 12, 2011 1:13 am

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.

FAU

Re: Inline Functions on CCL-1.6

Post by FAU » Sat Feb 12, 2011 1:36 am

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.

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Inline Functions on CCL-1.6

Post by ramarren » Sat Feb 12, 2011 2:50 am

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.

Kompottkin
Posts: 94
Joined: Mon Jul 21, 2008 7:26 am
Location: München, Germany
Contact:

Re: Inline Functions on CCL-1.6

Post by Kompottkin » Sun Feb 13, 2011 4:12 am

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).

FAU

Re: Inline Functions on CCL-1.6

Post by FAU » Sun Feb 13, 2011 2:55 pm

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.

Post Reply