From: ········@gmail.com
Subject: Non-toplevel defstruct
Date: 
Message-ID: <1140286145.669127.127380@o13g2000cwo.googlegroups.com>
This should work, right?

(prog1
    (defstruct foo
      a b c))

(prog1
    (defstruct (bar (:include foo))
      x y z))

or

(let ((fib (defstruct fib a))))

(let ((fact (defstruct (fact (:include fib))))))

Both throw an error ("Cannot find description of structure FOO to use
for inclusion") when loaded or compiled in ACL 7.0 Trial.

thanks

Nick

From: Pascal Costanza
Subject: Re: Non-toplevel defstruct
Date: 
Message-ID: <45p7ehF7mmfnU1@individual.net>
········@gmail.com wrote:
> This should work, right?
> 
> (prog1
>     (defstruct foo
>       a b c))
> 
> (prog1
>     (defstruct (bar (:include foo))
>       x y z))
> 
> or
> 
> (let ((fib (defstruct fib a))))
> 
> (let ((fact (defstruct (fact (:include fib))))))
> 
> Both throw an error ("Cannot find description of structure FOO to use
> for inclusion") when loaded or compiled in ACL 7.0 Trial.

No, they don't throw errors when loaded. If you have compiled a file, 
say "test.lisp" before, and say just (load "test"), then you will get 
the compiled file. If you want to make sure that you load the source 
(uncompiled) version, say (load "test.lisp"), or delete the compiled 
file beforehand.

Apart from that, your code looks pretty weird - it's very unusual to 
define structs not at the toplevel of a program. What are you trying to 
achieve? (It is probably easier to help if you tell us your actual goal.)


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: ········@gmail.com
Subject: Re: Non-toplevel defstruct
Date: 
Message-ID: <1140292552.676659.233470@f14g2000cwb.googlegroups.com>
>No, they don't throw errors when loaded. If you have compiled a file,
>say "test.lisp" before, and say just (load "test"), then you will get
>the compiled file. If you want to make sure that you load the source
>(uncompiled) version, say (load "test.lisp"), or delete the compiled
>file beforehand.

ah, hrm... embarrassing... you're right. It does not error when loaded.
It does, however,
error when calling COMPILE-FILE with either of those two examples in
ACL, Lispworks, or OpenMCL if the definitions had not been loaded
before, or a compile-time error when loading the compiled file in SBCL.

Am I missing something about the behavior of COMPILE-FILE?

>Apart from that, your code looks pretty weird - it's very unusual to
>define structs not at the toplevel of a program. What are you trying to
>achieve? (It is probably easier to help if you tell us your actual goal.)

A wrapper over DEFSTRUCT to allow for some side effects among other
things. The orignal problem was something like

(defmacro make-foo (1st)
  `(prog1
       (defstruct ,1st
	 x y z)
     (side-effects)))

(defmacro make-second-generation-foo (1st 2nd)
  `(prog1
       (defstruct (,1st (:include ,2nd))
	 a b c)
     (side-effects)))

(make-foo fib)
(make-second-generation-foo fact fib)

I used PROGN instead of PROG1 (it doesn't expand to a LET and the
compiler considers forms of a top level PROGN as top level) but it
seems kludgy now...

thanks

Nick

>Pascal
From: Pascal Bourguignon
Subject: Re: Non-toplevel defstruct
Date: 
Message-ID: <874q2w1lk8.fsf@thalassa.informatimago.com>
········@gmail.com writes:

>>No, they don't throw errors when loaded. If you have compiled a file,
>>say "test.lisp" before, and say just (load "test"), then you will get
>>the compiled file. If you want to make sure that you load the source
>>(uncompiled) version, say (load "test.lisp"), or delete the compiled
>>file beforehand.
>
> ah, hrm... embarrassing... you're right. It does not error when loaded.
> It does, however,
> error when calling COMPILE-FILE with either of those two examples in
> ACL, Lispworks, or OpenMCL if the definitions had not been loaded
> before, or a compile-time error when loading the compiled file in SBCL.
>
> Am I missing something about the behavior of COMPILE-FILE?
>
>>Apart from that, your code looks pretty weird - it's very unusual to
>>define structs not at the toplevel of a program. What are you trying to
>>achieve? (It is probably easier to help if you tell us your actual goal.)
>
> A wrapper over DEFSTRUCT to allow for some side effects among other
> things. The orignal problem was something like
>
> (defmacro make-foo (1st)
>   `(prog1
>        (defstruct ,1st
> 	 x y z)
>      (side-effects)))

You're being extra-lazy on this one!

 (defmacro make-foo (1st)
   `(progn
        (defstruct ,1st x y z)
        (side-effects)
        ',1st))


> I used PROGN instead of PROG1 (it doesn't expand to a LET and the
> compiler considers forms of a top level PROGN as top level) but it
> seems kludgy now...

No, it's designed to be used this way.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Grace personified,
I leap into the window.
I meant to do that.
From: ········@gmail.com
Subject: Re: Non-toplevel defstruct
Date: 
Message-ID: <1140309910.747877.324190@g43g2000cwa.googlegroups.com>
Pascall B. wrote:
>You're being extra-lazy on this one!
> (defmacro make-foo (1st)
>   `(progn
>        (defstruct ,1st x y z)
>        (side-effects)
>        ',1st))

>> I used PROGN instead of PROG1 (it doesn't expand to a LET and the
>> compiler considers forms of a top level PROGN as top level) but it
>> seems kludgy now...

>No, it's designed to be used this way.

Yes I know. It's just that aesthetically this seems exactly what PROG1
was designed for ;-)

How about this:

What if I wanted

(defmacro make-foo (1st)
  `(handler-case (defstruct ,1st
		   x y z)
     (,1st () (side-effects))
     (:some-condition () (some-stuff))
     (error () nil)))

(defmacro make-second-generation-foo (1st 2nd)
  `(handler-case (defstruct (,1st (:include ,2nd))
		   a b c)
     (,1st () (side-effects))
     (:some-condition () (some-stuff))
     (error () nil)))

so I could ignore my automated generational Foo Definer and dynamically
feed my Foo Instantiator restart-cases based on the state of my
unstable network of Foo structures?

Nick
From: Pascal Costanza
Subject: Re: Non-toplevel defstruct
Date: 
Message-ID: <45ptvnF7v4arU1@individual.net>
········@gmail.com wrote:
>>No, they don't throw errors when loaded. If you have compiled a file,
>>say "test.lisp" before, and say just (load "test"), then you will get
>>the compiled file. If you want to make sure that you load the source
>>(uncompiled) version, say (load "test.lisp"), or delete the compiled
>>file beforehand.
> 
> 
> ah, hrm... embarrassing... you're right. It does not error when loaded.
> It does, however,
> error when calling COMPILE-FILE with either of those two examples in
> ACL, Lispworks, or OpenMCL if the definitions had not been loaded
> before, or a compile-time error when loading the compiled file in SBCL.
> 
> Am I missing something about the behavior of COMPILE-FILE?

No, you are missing something about defstruct. The HyperSpec says this: 
"The argument to :include is required and must be the name of some 
previously defined structure." If the first defstruct is not in a 
toplevel position, the second defstruct that tries to include the first 
cannot recognize the first as an already defined structure. I think 
implementations are correct in interpreting this requirement very strictly.

>>Apart from that, your code looks pretty weird - it's very unusual to
>>define structs not at the toplevel of a program. What are you trying to
>>achieve? (It is probably easier to help if you tell us your actual goal.)
> 
> A wrapper over DEFSTRUCT to allow for some side effects among other
> things. The orignal problem was something like
> 
> (defmacro make-foo (1st)
>   `(prog1
>        (defstruct ,1st
> 	 x y z)
>      (side-effects)))
> 
> (defmacro make-second-generation-foo (1st 2nd)
>   `(prog1
>        (defstruct (,1st (:include ,2nd))
> 	 a b c)
>      (side-effects)))
> 
> (make-foo fib)
> (make-second-generation-foo fact fib)
> 
> I used PROGN instead of PROG1 (it doesn't expand to a LET and the
> compiler considers forms of a top level PROGN as top level) but it
> seems kludgy now...

Consider using CLOS classes instead of structs. They are much more 
flexible. (For example, superclasses don't have to exist when a class is 
defined, etc.)


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Pascal Bourguignon
Subject: Re: Non-toplevel defstruct
Date: 
Message-ID: <878xs81na8.fsf@thalassa.informatimago.com>
········@gmail.com writes:

> This should work, right?
>
> (prog1
>     (defstruct foo
>       a b c))
>
> (prog1
>     (defstruct (bar (:include foo))
>       x y z))
>
> or
>
> (let ((fib (defstruct fib a))))
>
> (let ((fact (defstruct (fact (:include fib))))))
>
> Both throw an error ("Cannot find description of structure FOO to use
> for inclusion") when loaded or compiled in ACL 7.0 Trial.

I would write:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (prog1
     (defstruct foo
       a b c)))

(prog1
     (defstruct (bar (:include foo))
       x y z))

and:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (let ((fib (defstruct fib a)))))

(let ((fact (defstruct (fact (:include fib))))))



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

Pour moi, la grande question n'a jamais �t�: �Qui suis-je? O� vais-je?� 
comme l'a formul� si adroitement notre ami Pascal, mais plut�t: 
�Comment vais-je m'en tirer?� -- Jean Yanne
From: ········@gmail.com
Subject: Re: Non-toplevel defstruct
Date: 
Message-ID: <1140313245.107479.26250@g47g2000cwa.googlegroups.com>
>No, you are missing something about defstruct. The HyperSpec says this:
>"The argument to :include is required and must be the name of some
>previously defined structure." If the first defstruct is not in a
>toplevel position, the second defstruct that tries to include the first
>cannot recognize the first as an already defined structure. I think
>implementations are correct in interpreting this requirement very strictly.

I read that, too. My plebeian worldview just expected two procedures
executed in sequence to provide the necessary semantics for the 1st to
be regarded as "previous" from context of the 2nd. It does make sense
though, now, from the pov of implementation.

thanks

Nick