Closed bluejay77 closed 6 years ago
I'm able to reproduce the problem while shortening ooEx.shen
to just:
(defclass int (object) val number 0)
(defclass fl (int))
The second line causes the error. If ooEx.shen
is only:
(defclass int (object) val number 0)
Then there is no error. This also works:
(defclass int (object) val number 0)
(set i (make-instance int i))
So we can create an instance of the int
class after it has been defined, we just can't extend it (I infer class fl
is trying to extend int
)...
... and that's only true when trying to load
those statements from a file. If I (load "oo.shen")
and then enter the 2 statements from the first snippet into the repl, there's no error. So the problem occurs when using set
/value
/put
/get
in some particular way while loading a file.
Shen, copyright (C) 2010-2015 Mark Tarver
www.shenlanguage.org, Shen 21
running under Common Lisp, implementation: SBCL
port 2.2 ported by Mark Tarver
(0-) (load "oo.shen")
defclass-macro
process-slots
instance
oo.type#o-o
attribute-type
class?
create-class
instance
assign
cl-slots
cl-parents
cl-name
make-instance
iget
iput
[]
run time: 0.31300000101327896 secs
loaded
(1-) (defclass int (object) val number 0)
int
(2-) (defclass fl (int))
fl
(3-) (set f (make-instance fl f))
f
Tried it again - it works when I make ooEx.shen
just:
(defclass int (object) val number 0)
(oo.create-class fl [int] [[]])
but this doesn't:
(defclass int (object) val number 0)
(defclass fl (int))
So if you inline the second use of the defclass
macro in ooEx.shen
, it works, and it works if you input the contents of ooEx.shen
directly into the repl.
And removing the package oo
from around the definitions in oo.shen
doesn't change anything.
The defclass-macro
is side-effectful and each declaration depends on the effects of the previous one. But the Shen reader expands macros from right to left, this is what is causing the error when loading the file but not in the REPL.
The macro should instead generate the code that will create the class instead of calling it at expansion time, that way you ensure that the order is respected. It would look something like this but not exactly:
(defmacro defclass-macro
[defclass Class SuperClasses | Slots]
-> [create-class Class SuperClasses [process-slots Class Slots]])
The reason I say not exactly is that you have to make sure the Slots
part gets generated as a literal list and not a function call ([val number 0]
instead of (val number 0)
in the case of the int
definition).
You can use this:
(define consify
[X | Y] -> [cons (consify X) (consify Y)]
X -> X)
(defmacro defclass-macro
[defclass Class SuperClasses | Slots]
-> [create-class Class (consify SuperClasses) [process-slots Class (consify Slots)]])
After making these changes it works for me:
(0-) (load "oo.shen")
oo.consify
defclass-macro
process-slots
instance
oo.type#o-o
attribute-type
class?
oo.create-class
instance
assign
cl-slots
cl-parents
cl-name
make-instance
iget
iput
[]
run time: 0.083874 secs
loaded
(1-) (load "ooEx.shen")
File begins.
[]
defclass definitions
[]
int
fl
cmx
make-instance definitions
[]
o
i
f
c
run time: 0.0023029999999999995 secs
loaded
(2-)
Closing this btw because it is not a bug, either in Shen/CL or the Shen Kernel.
Btw, the right-to-left macro expansion order is probably just an accidental implementation detail, and not something that Mark made work like that by design. I don't know how hard it is to change, or if it is even worth it (I myself don't like the idea of macros having side effects much, and because of that I don't write code that does it, and because of that expansion order is never an issue).
But I also understand that the right-to-left expansion order is kinda confusing and unexpected.
In the case that an macro expansion order change is something that needs to be discussed, the place to do so is in the mailing list, because introducing that change in the ShenBSD kernel would introduce a huge incompatibility with ShenProfessional, unless Mark also thinks it is a good idea to enforce left-to-right expansion order and does it too.
Dr Tarver made the "o-o.shen" OO capability. I have in my hands the Paul Graham book On Lisp, and its Ch 25 contains a discussion of object oriented LISP.
I have been tinkering with making a Paul Graham type version of the o-o.shen. This one would be called oo.shen.
The file oo.shen is what I have made so far. The file ooEx.shen are some examples.
There is something strange here. Below is a copy of the output.
Attachments: oo.shen ooEx.shen
File oo.shen
File ooEx.shen