#389 defpackage code executed at non-top-level compilation

closed-fixed
clisp (525)
5
2006-12-19
2006-12-09
No

CLISP can't correctly compile the following example:

(in-package #:cl-user)

(defmacro my-defpackage (name use)
`(eval-when (:compile-toplevel :load-toplevel :execute)
(let ((pkg (defpackage ,name (:use))))
(use-package '(,use) pkg)
pkg)))

(my-defpackage #:bar #:cl)

(in-package #:bar)

(defun baz (x) x)

IMHO, the code is correct (and it is correctly compiled by Allegro, CMUCL, and SBCL).

I tried both:

2.38 (2006-01-24) (built 3354011090) (memory 3361272513)

and the latest CVS:

2.41 (2006-10-13) (built 3374670403) (memory 3374670592)

Discussion

  • Sam Steingold

    Sam Steingold - 2006-12-11

    Logged In: YES
    user_id=5735
    Originator: NO

    This bug report is now marked as "pending"/"invalid".
    This means that we think that the problem you report
    is not a problem with CLISP.
    Unless you - the reporter - act within 2 weeks,
    the bug will be permanently closed.
    Sorry about the inconvenience -
    we hope your silence means that
    you agree that this is not a bug in CLISP.

     
  • Sam Steingold

    Sam Steingold - 2006-12-11

    Logged In: YES
    user_id=5735
    Originator: NO

    I am not sure this is actually a bug.

    EVAL-WHEN is not evaluated at compile time, so, although the package BAR is defined as a result of
    (my-defpackage #:bar #:cl)
    (due to some internal defpackage magic) the USE-PACKAGE is not evaluated which causes the problem you observe.

    I think what you meant to write was something like
    (defmacro my-defpackage (name use) (let ((pkg (defpackage ,name (:use)))) (use-package '(,use) pkg) pkg))
    (eval-when (:compile-toplevel :load-toplevel :execute) (my-defpackage #:bar #:cl))

    the reason other implementations accept your code may be that they do more that is required by the ANSI spec when macroexpanding a top-level macro.

    finally, I don't see that the behavior you are asking for is all that useful since you can just do
    (defmacro my-defpackage (name use) `(defpackage name (:use ,use))
    which is both more clear and more robust.

     
  • Sam Steingold

    Sam Steingold - 2006-12-11
    • status: open --> pending-invalid
     
  • Antonio Leitao

    Antonio Leitao - 2006-12-11
    • status: pending-invalid --> open-invalid
     
  • Antonio Leitao

    Antonio Leitao - 2006-12-11

    Logged In: YES
    user_id=1022580
    Originator: YES

    >>Comment By: Sam Steingold (sds)
    > Date: 2006-12-10 20:16
    >
    > Message:
    > Logged In: YES
    > user_id=5735
    > Originator: NO
    >
    > I am not sure this is actually a bug.

    Can you explain your rational?

    > EVAL-WHEN is not evaluated at compile time,

    Why not?

    > so, although the package BAR is defined as a result of
    > (my-defpackage #:bar #:cl) (due to some internal defpackage magic)
    > the USE-PACKAGE is not evaluated which causes the problem you
    > observe.

    Here's my justification for claiming that it is a bug.

    From the Hyperspec:

    3.2.3.1 Processing of Top Level Forms

    Processing of top level forms in the file compiler is defined as follows:

    ...

    2. If the form is a macro form, its macro expansion is computed and
    processed as a top level form in the same processing mode
    (compile-time-too or not-compile-time).

    ...

    (my-defpackage #:bar #:cl) is a macro form, so its macro expansion is
    computed and processed as a top level form in the same processing
    mode, i.e., the compiler will process:

    (eval-when (:compile-toplevel :load-toplevel :execute)
    (let ((pkg (defpackage #:bar (:use))))
    (use-package '(#:cl) pkg) pkg))

    Again:

    Processing of top level forms in the file compiler is defined as follows:

    ...

    5. If the form is an eval-when form, it is handled according to the next figure.

    CT LT E Mode Action New Mode
    ----------

    Yes Yes --- --- Process compile-time-too
    No Yes Yes CTT Process compile-time-too
    No Yes Yes NCT Process not-compile-time
    No Yes No --- Process not-compile-time
    Yes No --- --- Evaluate ---
    No No Yes CTT Evaluate ---
    No No Yes NCT Discard ---
    No No No --- Discard ---

    ...

    So, a :compile-toplevel, :load-toplevel and :execute means that
    independently of the current mode, the action is to Process and change
    mode to compile-time-too.

    In what regards 'Process':

    Process: process the body as top level forms in the specified mode.

    So, after eval-when processing, the compiler will have to 'Process'
    the form:

    (let ((pkg (defpackage #:bar (:use))))
    (use-package '(#:cl) pkg) pkg)

    in compile-time-too mode. Again,

    Processing of top level forms in the file compiler is defined as follows:

    ...

    6. Otherwise, the form is a top level form that is not one of the
    special cases. In compile-time-too mode, the compiler first
    evaluates the form in the evaluation environment and then
    minimally compiles it. In not-compile-time mode, the form is
    simply minimally compiled. All subforms are treated as
    non-top-level forms.

    ...

    We are in compile-time-too mode, so the compiler first evaluates the
    form, meaning that the package named "BAR" is created and it uses the
    "CL" package. This obviously affects the future processing of
    forms. Then, the form is minimally compiled.

    From this point on, the compiler will process the next forms but the
    package was correctly created so the next two forms are valid and they
    should be correctly compiled.

    I would be glad if you could explain what's wrong with my explanation.

    > I think what you meant to write was something like
    > (defmacro my-defpackage (name use) (let ((pkg (defpackage ,name (:use))))
    > (use-package '(,use) pkg) pkg))
    > (eval-when (:compile-toplevel :load-toplevel :execute) (my-defpackage
    > #:bar #:cl))

    I don't need to do that.

    > the reason other implementations accept your code may be that they do more
    > that is required by the ANSI spec when macroexpanding a top-level macro.
    > finally, I don't see that the behavior you are asking for is all that
    > useful

    See below.

    > since you can just do (defmacro my-defpackage (name use)
    > `(defpackage name (:use ,use)) which is both more clear and more
    > robust.

    The example is just for demonstration purposes, so that it exposes the
    bug and nothing else. The real code that explores this is quite
    different but I thought it would be distracting to include other stuff
    when a smaller (and, admitedly, not useful) example would be enough.

     
  • Sam Steingold

    Sam Steingold - 2006-12-18
    • summary: Incorrect compilation --> defpackage code executed at non-top-level compilation
    • assigned_to: haible --> sds
    • status: open-invalid --> open
     
  • Sam Steingold

    Sam Steingold - 2006-12-19

    Logged In: YES
    user_id=5735
    Originator: NO

    thank you for your bug report.
    the bug has been fixed in the CVS tree.
    you can either wait for the next release (recommended)
    or check out the current CVS tree (see http://clisp.cons.org\)
    and build CLISP from the sources (be advised that between
    releases the CVS tree is very unstable and may not even build
    on your platform).

     
  • Sam Steingold

    Sam Steingold - 2006-12-19
    • status: open --> closed-fixed
     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks