From: Mark Tarver
Subject: type secure CLOS?
Date: 
Message-ID: <1192652187.471656.203880@i38g2000prf.googlegroups.com>
OK; this is a demo with a serious question to CLOS users.

I've been looking at introducing a type secure version of CLOS into
Qi.  You can see what I've got on this page.  Its not long to read.

www.lambdassociates.org/qi-clos.htm

You'll see I've got a type secure chunk of CLOS which handles
inheritance, slot allocation etc. with great ease and includes
subtyping too. All in 91 lines of Qi and 9 lines of Lisp which load
into the Qi package.

Before I receive the dim cheers and obligatory shower of fruit, I have
a serious question.

Lisp contains plenty of destructive operations but I avoid all but the
simplest. Qi was actually developed as a language of automated
reasoning (AR). In AR often you want to try tactic X and if that fails
backtrack and try Y.  So if tactic X actually destroys your original
problem, you're in trouble.  Ergo destructive operations are a no-no.

I wanted to see if CLOS technology had shady dealings with destructive
operations so I set this little test.

First I declare a class object and a variable *ob* to hold an instance
of that class.

(defclass object ()
  weight number;)

(datatype globals

  _________________________________
  (value *ob*) : (instance object);)

Then a dumb function foo that receives a list of object instances,
changes the value of the weight slot and then throws away its effort
(apparently) by returning the head of the original input list.

(define foo
  {[(instance object)] --> (instance object)}
  Objects -> (let Change (map (/. Object (change-slot Object weight
1000)) Objects)
                  (set *ob* (head Objects))))

test just feeds foo a sample input.

(define test
  {A --> (instance object)}
   _ -> (let Objects [(make-instance object)
                      (make-instance object)
                      (make-instance object)]
             (foo Objects)))

Now the value Objects entering foo consists of instances in which the
weight slot has not been given a value.  Right?  And the output of foo
is just the head of that list which will, if the process is
declarative and non-destructive, be an instance which also does not
have a value in this slot.  But if I type

(slot-value (value *ob*) weight)

I get

1000 : number

and not an error message Condition of type UNBOUND-SLOT. telling me
that there is no value.

My provisional conclusion is that CLOS looks fairly destructive and is
thus not suitable for the task I have in mind.

Questions .....

1.  Have I made a mistake in my diagnosis of CLOs?
2.  Have I made a mistake in my coding - is this problem a result of
the code?   Can it be gotten around by another form of coding?

If the answer to both of these is 'no' - it looks as if CLOS is not
what I want.

Apologies if there is something obvious I've missed.

Mark

N.B.

To make this question simpler - here is the code for the vital bits.
Lisp system functions in uppercase.

(define make-instance
  Class -> (MAKE-INSTANCE Class))

(define slot-value
   Instance Slot -> (SLOT-VALUE Instance Slot))

(define change-slot
   Instance Slot Value -> (SETF (SLOT-VALUE Instance Slot) Value))

(define slot-bound?
   Instance Slot -> (IF (SLOT-BOUNDP Instance Slot) true false))

From: Ken Tilton
Subject: Re: type secure CLOS?
Date: 
Message-ID: <kquRi.66$V76.64@newsfe12.lga>
Mark Tarver wrote:
> OK; this is a demo with a serious question to CLOS users.
> 
> I've been looking at introducing a type secure version of CLOS into
> Qi.  You can see what I've got on this page.  Its not long to read.
> 
> www.lambdassociates.org/qi-clos.htm
> 
> You'll see I've got a type secure chunk of CLOS which handles
> inheritance, slot allocation etc. with great ease and includes
> subtyping too. All in 91 lines of Qi and 9 lines of Lisp which load
> into the Qi package.
> 
> Before I receive the dim cheers and obligatory shower of fruit, I have
> a serious question.
> 
> Lisp contains plenty of destructive operations but I avoid all but the
> simplest. Qi was actually developed as a language of automated
> reasoning (AR). In AR often you want to try tactic X and if that fails
> backtrack and try Y.  So if tactic X actually destroys your original
> problem, you're in trouble.  Ergo destructive operations are a no-no.
> 
> I wanted to see if CLOS technology had shady dealings with destructive
> operations so I set this little test.
> 
> First I declare a class object and a variable *ob* to hold an instance
> of that class.
> 
> (defclass object ()
>   weight number;)
> 
> (datatype globals
> 
>   _________________________________
>   (value *ob*) : (instance object);)
> 
> Then a dumb function foo that receives a list of object instances,
> changes the value of the weight slot and then throws away its effort
> (apparently) by returning the head of the original input list.
> 
> (define foo
>   {[(instance object)] --> (instance object)}
>   Objects -> (let Change (map (/. Object (change-slot Object weight
> 1000)) Objects)
>                   (set *ob* (head Objects))))
> 
> test just feeds foo a sample input.
> 
> (define test
>   {A --> (instance object)}
>    _ -> (let Objects [(make-instance object)
>                       (make-instance object)
>                       (make-instance object)]
>              (foo Objects)))
> 
> Now the value Objects entering foo consists of instances in which the
> weight slot has not been given a value.  Right?  And the output of foo
> is just the head of that list which will, if the process is
> declarative and non-destructive, be an instance which also does not
> have a value in this slot.  But if I type
> 
> (slot-value (value *ob*) weight)
> 
> I get
> 
> 1000 : number
> 
> and not an error message Condition of type UNBOUND-SLOT. telling me
> that there is no value.
> 
> My provisional conclusion is that CLOS looks fairly destructive and is
> thus not suitable for the task I have in mind.
> 
> Questions .....
> 
> 1.  Have I made a mistake in my diagnosis of CLOs?

yes.

> 2.  Have I made a mistake in my coding - is this problem a result of
> the code?   Can it be gotten around by another form of coding?

no. no.

> 
> If the answer to both of these is 'no' - it looks as if CLOS is not
> what I want.

yes.

> 
> Apologies if there is something obvious I've missed.

I am just surprised that you had so little idea how CLOS or even Lisp 
works that you made this post, so my apologies if I completely 
misunderstood.

If foo were passed a list of symbols and foo did a setf to a property on 
the first symbol would you expect that to be discarded because foo 
returned the same list it received?

kt


-- 
http://www.theoryyalgebra.com/

"Career highlights? I had two. I got an intentional walk
from Sandy Koufax and I got out of a rundown against the Mets."."
                                                   - Bob Uecker
From: Mark Tarver
Subject: Re: type secure CLOS?
Date: 
Message-ID: <1192655299.241026.219590@z24g2000prh.googlegroups.com>
On 17 Oct, 21:39, Ken Tilton <···········@optonline.net> wrote:
> Mark Tarver wrote:
> > OK; this is a demo with a serious question to CLOS users.
>
> > I've been looking at introducing a type secure version of CLOS into
> > Qi.  You can see what I've got on this page.  Its not long to read.
>
> >www.lambdassociates.org/qi-clos.htm
>
> > You'll see I've got a type secure chunk of CLOS which handles
> > inheritance, slot allocation etc. with great ease and includes
> > subtyping too. All in 91 lines of Qi and 9 lines of Lisp which load
> > into the Qi package.
>
> > Before I receive the dim cheers and obligatory shower of fruit, I have
> > a serious question.
>
> > Lisp contains plenty of destructive operations but I avoid all but the
> > simplest. Qi was actually developed as a language of automated
> > reasoning (AR). In AR often you want to try tactic X and if that fails
> > backtrack and try Y.  So if tactic X actually destroys your original
> > problem, you're in trouble.  Ergo destructive operations are a no-no.
>
> > I wanted to see if CLOS technology had shady dealings with destructive
> > operations so I set this little test.
>
> > First I declare a class object and a variable *ob* to hold an instance
> > of that class.
>
> > (defclass object ()
> >   weight number;)
>
> > (datatype globals
>
> >   _________________________________
> >   (value *ob*) : (instance object);)
>
> > Then a dumb function foo that receives a list of object instances,
> > changes the value of the weight slot and then throws away its effort
> > (apparently) by returning the head of the original input list.
>
> > (define foo
> >   {[(instance object)] --> (instance object)}
> >   Objects -> (let Change (map (/. Object (change-slot Object weight
> > 1000)) Objects)
> >                   (set *ob* (head Objects))))
>
> > test just feeds foo a sample input.
>
> > (define test
> >   {A --> (instance object)}
> >    _ -> (let Objects [(make-instance object)
> >                       (make-instance object)
> >                       (make-instance object)]
> >              (foo Objects)))
>
> > Now the value Objects entering foo consists of instances in which the
> > weight slot has not been given a value.  Right?  And the output of foo
> > is just the head of that list which will, if the process is
> > declarative and non-destructive, be an instance which also does not
> > have a value in this slot.  But if I type
>
> > (slot-value (value *ob*) weight)
>
> > I get
>
> > 1000 : number
>
> > and not an error message Condition of type UNBOUND-SLOT. telling me
> > that there is no value.
>
> > My provisional conclusion is that CLOS looks fairly destructive and is
> > thus not suitable for the task I have in mind.
>
> > Questions .....
>
> > 1.  Have I made a mistake in my diagnosis of CLOs?
>
> yes.
>
> > 2.  Have I made a mistake in my coding - is this problem a result of
> > the code?   Can it be gotten around by another form of coding?
>
> no. no.
>
>
>
> > If the answer to both of these is 'no' - it looks as if CLOS is not
> > what I want.
>
> yes.
>
>
>
> > Apologies if there is something obvious I've missed.
>
> I am just surprised that you had so little idea how CLOS or even Lisp
> works that you made this post, so my apologies if I completely
> misunderstood.
>
> If foo were passed a list of symbols and foo did a setf to a property on
> the first symbol would you expect that to be discarded because foo
> returned the same list it received?
>
> kt
>
> --http://www.theoryyalgebra.com/
>
> "Career highlights? I had two. I got an intentional walk
> from Sandy Koufax and I got out of a rundown against the Mets."."
>                                                    - Bob Uecker- Hide quoted text -
>
> - Show quoted text -

I was pretty certain I was right;  however I did not want to dismiss
CLOS out of hand since I hardly use it. You can always miss something
in front of your face. Particularly see my question about whether
there was any way of using CLOS in a non-destructive manner which is
more important to me.  You're saying 'no' to that which rather ends
this for me.

Mark
From: David Golden
Subject: Re: type secure CLOS?
Date: 
Message-ID: <2xvRi.22666$j7.429106@news.indigo.ie>
Mark Tarver wrote:

> Questions .....
> 
> 1.  Have I made a mistake in my diagnosis of CLOs?

I'm not quite sure what you expected: Objects in OO are typically
bundles of mutable state with identity.
 
> 2.  Have I made a mistake in my coding - is this problem a result of
> the code?   Can it be gotten around by another form of coding?

This is your immediate problem, depending on how you look at it:

(define change-slot
   Instance Slot Value -> (SETF (SLOT-VALUE Instance Slot) Value))

_You're_ explicitly invoking a destructively mutating operation! 
Uh, setf ?

Sooo... You _could_ have change-slot return a new instance rather than
mutating the original one.  (But N.B. you'd lose object identity, so
it might be silly to call it change-slot.)

(define make-instance-with-a-changed-slot-relative-to-a-prototype
   Instance Slot Value ->
        (SETF (SLOT-VALUE (SOMEHOW-CLONE Instance) Slot) Value))

This isn't really different to other mutable lisp data, except that 
SOMEHOW-CLONE  because, well, for starters, should you do a shallow or
deep copy? Different per class? Per slot?  It's up to the programmer to
write SOMEHOW-CLONE at CLOS level, because only they know what they
really want.  This is little different to the Java requirement to write
.clone() methods.

(Note that copy-structure is defined (as a shallow copy) for mere
defstruct structures though)
From: Mark Tarver
Subject: Re: type secure CLOS?
Date: 
Message-ID: <1192658894.799406.208990@e9g2000prf.googlegroups.com>
> Sooo... You _could_ have change-slot return a new instance rather than
> mutating the original one.  (But N.B. you'd lose object identity, so
> it might be silly to call it change-slot.)
>
> (define make-instance-with-a-changed-slot-relative-to-a-prototype
>    Instance Slot Value ->
>         (SETF (SLOT-VALUE (SOMEHOW-CLONE Instance) Slot) Value))
>
> This isn't really different to other mutable lisp data, except that
> SOMEHOW-CLONE  because, well, for starters, should you do a shallow or
> deep copy? Different per class? Per slot?  It's up to the programmer to
> write SOMEHOW-CLONE at CLOS level, because only they know what they
> really want.  This is little different to the Java requirement to write
> .clone() methods.
>
> (Note that copy-structure is defined (as a shallow copy) for mere
> defstruct structures though)

Well, yes, my real point was whether there was some standard way of
doing this which was not destructive in CL.  What you're telling me is
that change-slot has to remake the instance and then copy all the
existing slot values into the clone (using something from CL - what?
Does anybody know?) and then use SETF to change the slot value.  Got
the idea.  Does sound rather heavy though on resources.

Mark
From: Pascal Costanza
Subject: Re: type secure CLOS?
Date: 
Message-ID: <5no96tFj8ihoU2@mid.individual.net>
Mark Tarver wrote:
>> Sooo... You _could_ have change-slot return a new instance rather than
>> mutating the original one.  (But N.B. you'd lose object identity, so
>> it might be silly to call it change-slot.)
>>
>> (define make-instance-with-a-changed-slot-relative-to-a-prototype
>>    Instance Slot Value ->
>>         (SETF (SLOT-VALUE (SOMEHOW-CLONE Instance) Slot) Value))
>>
>> This isn't really different to other mutable lisp data, except that
>> SOMEHOW-CLONE  because, well, for starters, should you do a shallow or
>> deep copy? Different per class? Per slot?  It's up to the programmer to
>> write SOMEHOW-CLONE at CLOS level, because only they know what they
>> really want.  This is little different to the Java requirement to write
>> .clone() methods.
>>
>> (Note that copy-structure is defined (as a shallow copy) for mere
>> defstruct structures though)
> 
> Well, yes, my real point was whether there was some standard way of
> doing this which was not destructive in CL.  What you're telling me is
> that change-slot has to remake the instance and then copy all the
> existing slot values into the clone (using something from CL - what?
> Does anybody know?) and then use SETF to change the slot value.  Got
> the idea.  Does sound rather heavy though on resources.

How else should it work?


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Mark Tarver
Subject: Re: type secure CLOS?
Date: 
Message-ID: <1192687028.479496.187920@v23g2000prn.googlegroups.com>
On 18 Oct, 06:27, Pascal Costanza <····@p-cos.net> wrote:
> Mark Tarver wrote:
> >> Sooo... You _could_ have change-slot return a new instance rather than
> >> mutating the original one.  (But N.B. you'd lose object identity, so
> >> it might be silly to call it change-slot.)
>
> >> (define make-instance-with-a-changed-slot-relative-to-a-prototype
> >>    Instance Slot Value ->
> >>         (SETF (SLOT-VALUE (SOMEHOW-CLONE Instance) Slot) Value))
>
> >> This isn't really different to other mutable lisp data, except that
> >> SOMEHOW-CLONE  because, well, for starters, should you do a shallow or
> >> deep copy? Different per class? Per slot?  It's up to the programmer to
> >> write SOMEHOW-CLONE at CLOS level, because only they know what they
> >> really want.  This is little different to the Java requirement to write
> >> .clone() methods.
>
> >> (Note that copy-structure is defined (as a shallow copy) for mere
> >> defstruct structures though)
>
> > Well, yes, my real point was whether there was some standard way of
> > doing this which was not destructive in CL.  What you're telling me is
> > that change-slot has to remake the instance and then copy all the
> > existing slot values into the clone (using something from CL - what?
> > Does anybody know?) and then use SETF to change the slot value.  Got
> > the idea.  Does sound rather heavy though on resources.
>
> How else should it work?
>
> Pascal
>
> --
> My website:http://p-cos.net
> Common Lisp Document Repository:http://cdr.eurolisp.org
> Closer to MOP & ContextL:http://common-lisp.net/project/closer/- Hide quoted text -
>
> - Show quoted text -

Within CLOS - I would guess this is probably the right thing.  I can't
see any other way.  However outside of CLOS is different.

Mark
From: Pascal Costanza
Subject: Re: type secure CLOS?
Date: 
Message-ID: <5nomp6Fjfi7uU1@mid.individual.net>
Mark Tarver wrote:

> Within CLOS - I would guess this is probably the right thing.  I can't
> see any other way.  However outside of CLOS is different.

Hm, I have this idea that dynamic scoping may actually be better than 
side effects for functional programming. Dynamic scoping introduces 
effects as well, but they are more controlled than side effects.

So in ContextL you can do the following:

(define-layered-class object ()
   ((weight :special t)
    (number :special t)))

This declares the slots 'weight and 'number as special (dynamically scoped).

This allows you to do the following:

(defparameter *ob* (make-instance 'object))

(slot-value *ob* 'weight) => error: unbound slot

(dletf (((slot-value *ob* 'weight) 1000))
   (slot-value *ob* 'weight))
                           => 1000

(slot-value *ob* 'weight) => error: unbound slot

So:

- In the dynamic extent of a dletf form, a special slot can be rebound, 
but ater returning from that dletf form, the special slot has its old 
state again (either unbound, or the old value).

- Furthermore, the rebinding is confined to the current thread in 
multi-threaded implementations of Common Lisp. Other threads see the 
previous value/state, or their own value/state if they happened to 
rebind the respective slot as well.

In other words, such special slots behave exactly like special 
variables, and dletf works on special slots like let works on special 
variables.

See http://p-cos.net/documents/special-full.pdf for more information. 
(That paper mentions this as a feature of AspectL, but it is now part of 
ContextL.)


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: David Golden
Subject: Re: type secure CLOS?
Date: 
Message-ID: <_awRi.22667$j7.429106@news.indigo.ie>
David Golden wrote, idiotically:

> (define make-instance-with-a-changed-slot-relative-to-a-prototype
>    Instance Slot Value ->
>         (SETF (SLOT-VALUE (SOMEHOW-CLONE Instance) Slot) Value))
> 

[This is Wrong (See Pascal's correct code...),
the return value of (setf (slot-value instance slot) value) isn't the
instance, it's the slot value. ]
From: Pascal Costanza
Subject: Re: type secure CLOS?
Date: 
Message-ID: <5nnfaeFj6186U1@mid.individual.net>
Mark Tarver wrote:
> OK; this is a demo with a serious question to CLOS users.
> 
> I've been looking at introducing a type secure version of CLOS into
> Qi.  You can see what I've got on this page.  Its not long to read.
> 
> www.lambdassociates.org/qi-clos.htm
> 
> You'll see I've got a type secure chunk of CLOS which handles
> inheritance, slot allocation etc. with great ease and includes
> subtyping too. All in 91 lines of Qi and 9 lines of Lisp which load
> into the Qi package.
> 
> Before I receive the dim cheers and obligatory shower of fruit, I have
> a serious question.
> 
> Lisp contains plenty of destructive operations but I avoid all but the
> simplest. Qi was actually developed as a language of automated
> reasoning (AR). In AR often you want to try tactic X and if that fails
> backtrack and try Y.  So if tactic X actually destroys your original
> problem, you're in trouble.  Ergo destructive operations are a no-no.

...unless you have transactions, which would allow you to undo 
destructive operations.

> I wanted to see if CLOS technology had shady dealings with destructive
> operations so I set this little test.
> 
> First I declare a class object and a variable *ob* to hold an instance
> of that class.
> 
> (defclass object ()
>   weight number;)
> 
> (datatype globals
> 
>   _________________________________
>   (value *ob*) : (instance object);)
> 
> Then a dumb function foo that receives a list of object instances,
> changes the value of the weight slot and then throws away its effort
> (apparently) by returning the head of the original input list.
> 
> (define foo
>   {[(instance object)] --> (instance object)}
>   Objects -> (let Change (map (/. Object (change-slot Object weight
> 1000)) Objects)
>                   (set *ob* (head Objects))))
> 
> test just feeds foo a sample input.
> 
> (define test
>   {A --> (instance object)}
>    _ -> (let Objects [(make-instance object)
>                       (make-instance object)
>                       (make-instance object)]
>              (foo Objects)))
> 
> Now the value Objects entering foo consists of instances in which the
> weight slot has not been given a value.  Right?  And the output of foo
> is just the head of that list which will, if the process is
> declarative and non-destructive, be an instance which also does not
> have a value in this slot.  But if I type
> 
> (slot-value (value *ob*) weight)
> 
> I get
> 
> 1000 : number
> 
> and not an error message Condition of type UNBOUND-SLOT. telling me
> that there is no value.

What you want is a way to copy objects, with some slot value being 
replaced. That's fairly simple to achieve:

(defun copy-instance (object &rest initargs)
   (declare (dynamic-extent initargs))
   (let ((copy (make-instance (class-of object))))
     (loop for slot in (class-slots (class-of object))
           for slot-name = (slot-definition-name slot) do
           (setf (slot-value copy slot-name)
                 (slot-value object slot-name)))
     (apply #'reinitialize-instance copy initargs)))

For example:

(let ((obj (make-instance 'object)))
   (values
     obj
     (copy-instance obj :weight 1000)))

That gives you two different objects of the same class 'object, where 
the first has an unbound slot 'weight, and the second has a slot value 
of 1000 for the slot 'weight.

You need the CLOS MOP for doing this, or resort to manual 
implementations for copy-instance for each class.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Mark Tarver
Subject: Re: type secure CLOS?
Date: 
Message-ID: <1192661680.607761.90640@e9g2000prf.googlegroups.com>
On 17 Oct, 23:06, Pascal Costanza <····@p-cos.net> wrote:
> Mark Tarver wrote:
> > OK; this is a demo with a serious question to CLOS users.
>
> > I've been looking at introducing a type secure version of CLOS into
> > Qi.  You can see what I've got on this page.  Its not long to read.
>
> >www.lambdassociates.org/qi-clos.htm
>
> > You'll see I've got a type secure chunk of CLOS which handles
> > inheritance, slot allocation etc. with great ease and includes
> > subtyping too. All in 91 lines of Qi and 9 lines of Lisp which load
> > into the Qi package.
>
> > Before I receive the dim cheers and obligatory shower of fruit, I have
> > a serious question.
>
> > Lisp contains plenty of destructive operations but I avoid all but the
> > simplest. Qi was actually developed as a language of automated
> > reasoning (AR). In AR often you want to try tactic X and if that fails
> > backtrack and try Y.  So if tactic X actually destroys your original
> > problem, you're in trouble.  Ergo destructive operations are a no-no.
>
> ...unless you have transactions, which would allow you to undo
> destructive operations.
>
>
>
>
>
> > I wanted to see if CLOS technology had shady dealings with destructive
> > operations so I set this little test.
>
> > First I declare a class object and a variable *ob* to hold an instance
> > of that class.
>
> > (defclass object ()
> >   weight number;)
>
> > (datatype globals
>
> >   _________________________________
> >   (value *ob*) : (instance object);)
>
> > Then a dumb function foo that receives a list of object instances,
> > changes the value of the weight slot and then throws away its effort
> > (apparently) by returning the head of the original input list.
>
> > (define foo
> >   {[(instance object)] --> (instance object)}
> >   Objects -> (let Change (map (/. Object (change-slot Object weight
> > 1000)) Objects)
> >                   (set *ob* (head Objects))))
>
> > test just feeds foo a sample input.
>
> > (define test
> >   {A --> (instance object)}
> >    _ -> (let Objects [(make-instance object)
> >                       (make-instance object)
> >                       (make-instance object)]
> >              (foo Objects)))
>
> > Now the value Objects entering foo consists of instances in which the
> > weight slot has not been given a value.  Right?  And the output of foo
> > is just the head of that list which will, if the process is
> > declarative and non-destructive, be an instance which also does not
> > have a value in this slot.  But if I type
>
> > (slot-value (value *ob*) weight)
>
> > I get
>
> > 1000 : number
>
> > and not an error message Condition of type UNBOUND-SLOT. telling me
> > that there is no value.
>
> What you want is a way to copy objects, with some slot value being
> replaced. That's fairly simple to achieve:
>
> (defun copy-instance (object &rest initargs)
>    (declare (dynamic-extent initargs))
>    (let ((copy (make-instance (class-of object))))
>      (loop for slot in (class-slots (class-of object))
>            for slot-name = (slot-definition-name slot) do
>            (setf (slot-value copy slot-name)
>                  (slot-value object slot-name)))
>      (apply #'reinitialize-instance copy initargs)))
>
> For example:
>
> (let ((obj (make-instance 'object)))
>    (values
>      obj
>      (copy-instance obj :weight 1000)))
>
> That gives you two different objects of the same class 'object, where
> the first has an unbound slot 'weight, and the second has a slot value
> of 1000 for the slot 'weight.
>
> You need the CLOS MOP for doing this, or resort to manual
> implementations for copy-instance for each class.
>
> Pascal
>
> --
> My website:http://p-cos.net
> Common Lisp Document Repository:http://cdr.eurolisp.org
> Closer to MOP & ContextL:http://common-lisp.net/project/closer/- Hide quoted text -
>
> - Show quoted text -- Hide quoted text -
>
> - Show quoted text -

Very good; but now my next question.   What happens w.r.t. garbage
collection to these clones?  Are they global objects which remain
uncollected?  If so, there could be problems with an AR application
using instances.  Qi ATPs clock 10^5 inferences per second which would
potentially lead to a severe memory leak if these clones are not gced.

Mark
From: David Golden
Subject: Re: type secure CLOS?
Date: 
Message-ID: <YmxRi.22669$j7.429086@news.indigo.ie>
Mark Tarver wrote:

> Very good; but now my next question.   What happens w.r.t. garbage
> collection to these clones?  Are they global objects which remain
> uncollected? 

If they become unreferenced, they'll presumably be collected?

Somewhat related, let's plod through the horror of the losing object
identity point, though you very likely understand this, it's maybe
worth spelling out:

Say the old instance was referenced by another object ("in" a slot of
another object) - making a new instance that's a copy of the old
instance doesn't magically update any references to the old instance in
other objects to the new instance.

Now, that's okay if you're just going to throw the copy instance away
after operating on it in isolation.

But if [for some reason] you expected other preexisting objects in the
execution environment following the clone operation to reference the
new clone instead of the old instance, well, they won't, not without
further intervention. That is to say, merely cloning the instance then
mutating the clone is [of course] not in itself a replacement for setf
slot-value.  [Duh, you say, but hey].  Pretty soon, you decide you want
transactions (or to write your code some other way, of course...).
From: Mark Tarver
Subject: Re: type secure CLOS?
Date: 
Message-ID: <1192682113.232433.141650@e9g2000prf.googlegroups.com>
On 18 Oct, 01:00, David Golden <············@oceanfree.net> wrote:
> Mark Tarver wrote:
> > Very good; but now my next question.   What happens w.r.t. garbage
> > collection to these clones?  Are they global objects which remain
> > uncollected?
>
> If they become unreferenced, they'll presumably be collected?
>
> Somewhat related, let's plod through the horror of the losing object
> identity point, though you very likely understand this, it's maybe
> worth spelling out:
>
> Say the old instance was referenced by another object ("in" a slot of
> another object) - making a new instance that's a copy of the old
> instance doesn't magically update any references to the old instance in
> other objects to the new instance.
>
> Now, that's okay if you're just going to throw the copy instance away
> after operating on it in isolation.
>
> But if [for some reason] you expected other preexisting objects in the
> execution environment following the clone operation to reference the
> new clone instead of the old instance, well, they won't, not without
> further intervention. That is to say, merely cloning the instance then
> mutating the clone is [of course] not in itself a replacement for setf
> slot-value.  [Duh, you say, but hey].  Pretty soon, you decide you want
> transactions (or to write your code some other way, of course...).

What I'm picking up here is the CLOS is generating a fair amount of
procedural murk that is detracting from the simple, powerful and
elegant idea of class inheritance I want. Being a simple mammal I like
simple shiny things that I can pick up and keep.

> Pretty soon, you decide you want
> transactions (or to write your code some other way, of course...).

Right. The easiest is to implement my ideas without using CLOS.  In
fact, suffering insomnia again tonight I've already done that.  Case
closed.  But thanks to all here.

Mark
From: Pascal Costanza
Subject: Re: type secure CLOS?
Date: 
Message-ID: <5non2bFj9cagU1@mid.individual.net>
Mark Tarver wrote:

> What I'm picking up here is the CLOS is generating a fair amount of
> procedural murk that is detracting from the simple, powerful and
> elegant idea of class inheritance I want. Being a simple mammal I like
> simple shiny things that I can pick up and keep.
[...]
> 
> The easiest is to implement my ideas without using CLOS.  In
> fact, suffering insomnia again tonight I've already done that.  Case
> closed.  But thanks to all here.

You're giving up on CLOS too early, IMHO. CLOS itself provides default 
semantics which comply with what people typically expect from 
object-oriented languages (and then some). This includes the notion of 
object identity, which always remains the same even if you change other 
properties of an object, which is a pretty standard feature of OOP.

However, most CL implementations also provide the CLOS Metaobject 
Protocol, which allows you to change the semantics of CLOS and define 
your own object system, without having to implement everything from 
scratch yourself. Unless you want to turn CLOS into an elephant, it's 
pretty likely that you can get what you want.

It's just not really clear yet what it is that you actually want. (At 
least not to me...)


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Mark Tarver
Subject: Re: type secure CLOS?
Date: 
Message-ID: <1192704439.665895.203480@t8g2000prg.googlegroups.com>
On 18 Oct, 10:24, Pascal Costanza <····@p-cos.net> wrote:
> Mark Tarver wrote:
> > What I'm picking up here is the CLOS is generating a fair amount of
> > procedural murk that is detracting from the simple, powerful and
> > elegant idea of class inheritance I want. Being a simple mammal I like
> > simple shiny things that I can pick up and keep.
> [...]
>
> > The easiest is to implement my ideas without using CLOS.  In
> > fact, suffering insomnia again tonight I've already done that.  Case
> > closed.  But thanks to all here.
>
> You're giving up on CLOS too early, IMHO. CLOS itself provides default
> semantics which comply with what people typically expect from
> object-oriented languages (and then some). This includes the notion of
> object identity, which always remains the same even if you change other
> properties of an object, which is a pretty standard feature of OOP.
>
> However, most CL implementations also provide the CLOS Metaobject
> Protocol, which allows you to change the semantics of CLOS and define
> your own object system, without having to implement everything from
> scratch yourself. Unless you want to turn CLOS into an elephant, it's
> pretty likely that you can get what you want.
>
> It's just not really clear yet what it is that you actually want. (At
> least not to me...)
>
> Pascal
>
> --
> My website:http://p-cos.net
> Common Lisp Document Repository:http://cdr.eurolisp.org
> Closer to MOP & ContextL:http://common-lisp.net/project/closer/

Right; sitting down with proverbial English tea.  Gorgeous day.

What I've done is implement classes as closures or abstractions that
return A-lists of dotted pairs when instantiated.  This has several
advantages.

1.  It stays within the functional paradigm and avoids destructive
operations.
2.  Instantiating a class produces an object which contents you can
immediately see.
3.  It gives the user the option of using Qi pattern-matching over
class instances.
4.  It is clear and simple.

This model needed only a small revision of the code for Qi-CLOS
(except CLOS is gone so it should be Qi Classes or some such).  All
the type theory stuff is still good.  Total LOC 125.

Here is a script:

(10+) (defclass object ()
        weight number;)
#<COMPILED-CLOSURE class-function-1> : unit

(11+) (make-instance object)
[[weight . #\Escape]] : (instance object)

(12+) (slot-value (make-instance object) weight)
error: weight does not have a value

(13+) (change-slot (make-instance object) weight 1000)
[[weight . 1000]] : (instance object)

(14+) (defclass ship (object)
         weight string;)
error: type clash in inheritance with class ship and slot weight

(15+) (defclass ship (object)
         name string;)
#<COMPILED-CLOSURE class-function-1> : unit

(16+) (make-instance ship)
[[name . #\Escape] [weight . #\Escape]] : (instance ship)

(17+) (defclass battleship (ship)
         weight number 100000;)
#<COMPILED-CLOSURE class-function-1> : unit

(18+) (make-instance battleship)
[[weight . 100000] [name . #\Escape] [weight . #\Escape]] : (instance
battleship)

Mark
From: Pascal Costanza
Subject: Re: type secure CLOS?
Date: 
Message-ID: <5notp4Fjedq7U1@mid.individual.net>
Mark Tarver wrote:
> On 18 Oct, 10:24, Pascal Costanza <····@p-cos.net> wrote:
>> Mark Tarver wrote:
>>> What I'm picking up here is the CLOS is generating a fair amount of
>>> procedural murk that is detracting from the simple, powerful and
>>> elegant idea of class inheritance I want. Being a simple mammal I like
>>> simple shiny things that I can pick up and keep.
>> [...]
>>
>>> The easiest is to implement my ideas without using CLOS.  In
>>> fact, suffering insomnia again tonight I've already done that.  Case
>>> closed.  But thanks to all here.
>> You're giving up on CLOS too early, IMHO. CLOS itself provides default
>> semantics which comply with what people typically expect from
>> object-oriented languages (and then some). This includes the notion of
>> object identity, which always remains the same even if you change other
>> properties of an object, which is a pretty standard feature of OOP.
>>
>> However, most CL implementations also provide the CLOS Metaobject
>> Protocol, which allows you to change the semantics of CLOS and define
>> your own object system, without having to implement everything from
>> scratch yourself. Unless you want to turn CLOS into an elephant, it's
>> pretty likely that you can get what you want.
>>
>> It's just not really clear yet what it is that you actually want. (At
>> least not to me...)
>>
>> Pascal
>>
>> --
>> My website:http://p-cos.net
>> Common Lisp Document Repository:http://cdr.eurolisp.org
>> Closer to MOP & ContextL:http://common-lisp.net/project/closer/
> 
> Right; sitting down with proverbial English tea.  Gorgeous day.
> 
> What I've done is implement classes as closures or abstractions that
> return A-lists of dotted pairs when instantiated.  This has several
> advantages.
> 
> 1.  It stays within the functional paradigm and avoids destructive
> operations.
> 2.  Instantiating a class produces an object which contents you can
> immediately see.
> 3.  It gives the user the option of using Qi pattern-matching over
> class instances.
> 4.  It is clear and simple.
> 
> This model needed only a small revision of the code for Qi-CLOS
> (except CLOS is gone so it should be Qi Classes or some such).  All
> the type theory stuff is still good.  Total LOC 125.

Sure, but now you can't define methods anymore. And as soon as you 
provide all the bells and whistles of CLOS (like multiple inheritance, 
multiple dispatch, eql specializers, method combinations, etc.), which 
all fit perfectly in a purely functional programming style, you will be 
much beyond 125 LOC.

You also deviate from basic CLOS semantics, which may be confusing for 
some. In CLOS, you don't get a type error when a subclass specifies the 
same slot as a superclass - instead, the slot specifications are merged, 
including their types in a way that should be good enough for static 
type systems.

It seems to me that you would be better off with my copy-instance 
function, because it seems to give the same semantics as your 
alist-producing classes, but by staying within CLOS.

In general, I have the impression (but I might be wrong) that you have 
the same knee-jerk reaction against OOP that many fans of functional 
programming have. However, their judgement typically stems from "lesser" 
OOP approaches, like Smalltalk, Java, etc. CLOS goes much further than 
that, and it is not advisable to try to recreate it all. CLOS is 
particularly remarkable because it blends extremely well with functional 
programming, so you're giving up a lot when you start from scratch.

The sad thing is that functional programmers who start to build OOP 
extensions typically only recreate the simplistic OOP approaches they 
actually despise. That's a pity.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Mark Tarver
Subject: Re: type secure CLOS?
Date: 
Message-ID: <1192710977.085781.324690@v23g2000prn.googlegroups.com>
On 18 Oct, 12:19, Pascal Costanza <····@p-cos.net> wrote:
> Mark Tarver wrote:
> > On 18 Oct, 10:24, Pascal Costanza <····@p-cos.net> wrote:
> >> Mark Tarver wrote:
> >>> What I'm picking up here is the CLOS is generating a fair amount of
> >>> procedural murk that is detracting from the simple, powerful and
> >>> elegant idea of class inheritance I want. Being a simple mammal I like
> >>> simple shiny things that I can pick up and keep.
> >> [...]
>
> >>> The easiest is to implement my ideas without using CLOS.  In
> >>> fact, suffering insomnia again tonight I've already done that.  Case
> >>> closed.  But thanks to all here.
> >> You're giving up on CLOS too early, IMHO. CLOS itself provides default
> >> semantics which comply with what people typically expect from
> >> object-oriented languages (and then some). This includes the notion of
> >> object identity, which always remains the same even if you change other
> >> properties of an object, which is a pretty standard feature of OOP.
>
> >> However, most CL implementations also provide the CLOS Metaobject
> >> Protocol, which allows you to change the semantics of CLOS and define
> >> your own object system, without having to implement everything from
> >> scratch yourself. Unless you want to turn CLOS into an elephant, it's
> >> pretty likely that you can get what you want.
>
> >> It's just not really clear yet what it is that you actually want. (At
> >> least not to me...)
>
> >> Pascal
>
> >> --
> >> My website:http://p-cos.net
> >> Common Lisp Document Repository:http://cdr.eurolisp.org
> >> Closer to MOP & ContextL:http://common-lisp.net/project/closer/
>
> > Right; sitting down with proverbial English tea.  Gorgeous day.
>
> > What I've done is implement classes as closures or abstractions that
> > return A-lists of dotted pairs when instantiated.  This has several
> > advantages.
>
> > 1.  It stays within the functional paradigm and avoids destructive
> > operations.
> > 2.  Instantiating a class produces an object which contents you can
> > immediately see.
> > 3.  It gives the user the option of using Qi pattern-matching over
> > class instances.
> > 4.  It is clear and simple.
>
> > This model needed only a small revision of the code for Qi-CLOS
> > (except CLOS is gone so it should be Qi Classes or some such).  All
> > the type theory stuff is still good.  Total LOC 125.
>
> Sure, but now you can't define methods anymore. And as soon as you
> provide all the bells and whistles of CLOS (like multiple inheritance,
> multiple dispatch, eql specializers, method combinations, etc.), which
> all fit perfectly in a purely functional programming style, you will be
> much beyond 125 LOC.
>
> You also deviate from basic CLOS semantics, which may be confusing for
> some. In CLOS, you don't get a type error when a subclass specifies the
> same slot as a superclass - instead, the slot specifications are merged,
> including their types in a way that should be good enough for static
> type systems.

Well no; in my system you don't get an error when a subclass specifies
the same slot as a superclass unless the type constraints don't match
i.e. the new type is not a subtype of the old one.  Strings are not a
subtype of numbers which is why you get an error here.

Multiple inheritance is in the system too; I just didn't put an
example in the script.

IMO destructive operations are to be avoided at all costs in FP except
in the very simplest cases like simple assignments because it breaks
the whole model which makes FP work.  So having destructive operations
so early in the game is not a good thing even if you can fudge your
way around it.  Recycling the data structures of FP and using closures
and lists makes for transparency and the attendant advantage of being
able to pattern-match over an instance is not inconsiderable.

Mark

>
> It seems to me that you would be better off with my copy-instance
> function, because it seems to give the same semantics as your
> alist-producing classes, but by staying within CLOS.
>
> In general, I have the impression (but I might be wrong) that you have
> the same knee-jerk reaction against OOP that many fans of functional
> programming have. However, their judgement typically stems from "lesser"
> OOP approaches, like Smalltalk, Java, etc. CLOS goes much further than
> that, and it is not advisable to try to recreate it all. CLOS is
> particularly remarkable because it blends extremely well with functional
> programming, so you're giving up a lot when you start from scratch.
>
> The sad thing is that functional programmers who start to build OOP
> extensions typically only recreate the simplistic OOP approaches they
> actually despise. That's a pity.
>
> Pascal
>
> --
> My website:http://p-cos.net
> Common Lisp Document Repository:http://cdr.eurolisp.org
> Closer to MOP & ContextL:http://common-lisp.net/project/closer/- Hide quoted text -
>
> - Show quoted text -
From: Pascal Costanza
Subject: Re: type secure CLOS?
Date: 
Message-ID: <5nq518FjjupbU1@mid.individual.net>
Mark Tarver wrote:

>> You also deviate from basic CLOS semantics, which may be confusing for
>> some. In CLOS, you don't get a type error when a subclass specifies the
>> same slot as a superclass - instead, the slot specifications are merged,
>> including their types in a way that should be good enough for static
>> type systems.
> 
> Well no; in my system you don't get an error when a subclass specifies
> the same slot as a superclass unless the type constraints don't match
> i.e. the new type is not a subtype of the old one.  Strings are not a
> subtype of numbers which is why you get an error here.

OK, then I misunderstood that part. Sorry.

> Multiple inheritance is in the system too; I just didn't put an
> example in the script.

OK

> IMO destructive operations are to be avoided at all costs in FP except
> in the very simplest cases like simple assignments because it breaks
> the whole model which makes FP work.  So having destructive operations
> so early in the game is not a good thing even if you can fudge your
> way around it.  Recycling the data structures of FP and using closures
> and lists makes for transparency and the attendant advantage of being
> able to pattern-match over an instance is not inconsiderable.

You only have destructive operations early in the game if you actually 
use them. It's not the fault of CLOS if you use SETF when you actually 
don't want to use SETF. The only difference between CLOS and your object 
system in that regard is that you don't use RPLACD on slot entries, but 
I could turn your argument against your object system as well by giving 
an example that actually uses RPLACD.

And you are still underestimating what you could achieve with CLOS MOP. 
Replacing the internal slot structure of CLOS objects with lists in the 
way you do, while retaining the full power of CLOS is a trivial exercise:

(defclass list-class (standard-class) ())

(defmethod validate-superclass
   ((class list-class) (superclass standard-class))
   t)

(defclass list-object (standard-object)
   ((slot-list :initform '()))

(defmethod initialize-instance :around
   ((class list-class) &rest initargs
    &key direct-superclasses)
   (declare (dynamic-extent initargs))
   (if (loop for direct-superclass in direct-superclasses
             thereis (subtypep direct-superclass 'list-object))
     (call-next-method)
     (apply #'call-next-method class
            :direct-superclasses
            (append direct-superclasses
                    (list (find-class 'list-object)))
            initargs)))

(defmethod reinitialize-instance :around
   ((class list-class) &rest initargs
    &key (direct-superclasses '() direct-superclasses-p))
   (declare (dynamic-extent initargs))
   (if (or (not direct-superclasses-p)
           (loop for direct-superclass in direct-superclasses
                 thereis (subtypep direct-superclass 'list-object)))
     (call-next-method)
     (apply #'call-next-method class
            :direct-superclasses
            (append direct-superclasses
                    (list (find-class 'list-object)))
            initargs)))

(defmethod slot-value-using-class
   ((class list-class) object slot)
   (if (eq (slot-definition-name slot) 'slot-list)
     (call-next-method)
     (cdr (assoc (slot-definition-name slot)
                 (slot-value object 'slot-list)))))

(defmethod (setf slot-value-using-class)
   (new-value (class list-class) object slot)
   (error "This metaclass does not support side effects."))

(defmethod slot-boundp-using-class
   ((class list-class) object slot)
   (if (eq (slot-definition-name slot) 'slot-list)
     (call-next-method)
     (assoc (slot-definition-name slot)
            (slot-value object 'slot-list))))

(defmethod slot-makunbound-using-class
   ((class list-class) object slot)
   (error "This metaclass does not support side effects."))


[Untested, and could be improved, but I hope this gets the idea across.]



Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Mark Tarver
Subject: Re: type secure CLOS?
Date: 
Message-ID: <1192790957.462637.241690@t8g2000prg.googlegroups.com>
On 18 Oct, 23:28, Pascal Costanza <····@p-cos.net> wrote:
> Mark Tarver wrote:
> >> You also deviate from basic CLOS semantics, which may be confusing for
> >> some. In CLOS, you don't get a type error when a subclass specifies the
> >> same slot as a superclass - instead, the slot specifications are merged,
> >> including their types in a way that should be good enough for static
> >> type systems.
>
> > Well no; in my system you don't get an error when a subclass specifies
> > the same slot as a superclass unless the type constraints don't match
> > i.e. the new type is not a subtype of the old one.  Strings are not a
> > subtype of numbers which is why you get an error here.
>
> OK, then I misunderstood that part. Sorry.
>
> > Multiple inheritance is in the system too; I just didn't put an
> > example in the script.
>
> OK
>
> > IMO destructive operations are to be avoided at all costs in FP except
> > in the very simplest cases like simple assignments because it breaks
> > the whole model which makes FP work.  So having destructive operations
> > so early in the game is not a good thing even if you can fudge your
> > way around it.  Recycling the data structures of FP and using closures
> > and lists makes for transparency and the attendant advantage of being
> > able to pattern-match over an instance is not inconsiderable.
>
> You only have destructive operations early in the game if you actually
> use them. It's not the fault of CLOS if you use SETF when you actually
> don't want to use SETF. The only difference between CLOS and your object
> system in that regard is that you don't use RPLACD on slot entries, but
> I could turn your argument against your object system as well by giving
> an example that actually uses RPLACD.
>
> And you are still underestimating what you could achieve with CLOS MOP.
> Replacing the internal slot structure of CLOS objects with lists in the
> way you do, while retaining the full power of CLOS is a trivial exercise:
>
> (defclass list-class (standard-class) ())
>
> (defmethod validate-superclass
>    ((class list-class) (superclass standard-class))
>    t)
>
> (defclass list-object (standard-object)
>    ((slot-list :initform '()))
>
> (defmethod initialize-instance :around
>    ((class list-class) &rest initargs
>     &key direct-superclasses)
>    (declare (dynamic-extent initargs))
>    (if (loop for direct-superclass in direct-superclasses
>              thereis (subtypep direct-superclass 'list-object))
>      (call-next-method)
>      (apply #'call-next-method class
>             :direct-superclasses
>             (append direct-superclasses
>                     (list (find-class 'list-object)))
>             initargs)))
>
> (defmethod reinitialize-instance :around
>    ((class list-class) &rest initargs
>     &key (direct-superclasses '() direct-superclasses-p))
>    (declare (dynamic-extent initargs))
>    (if (or (not direct-superclasses-p)
>            (loop for direct-superclass in direct-superclasses
>                  thereis (subtypep direct-superclass 'list-object)))
>      (call-next-method)
>      (apply #'call-next-method class
>             :direct-superclasses
>             (append direct-superclasses
>                     (list (find-class 'list-object)))
>             initargs)))
>
> (defmethod slot-value-using-class
>    ((class list-class) object slot)
>    (if (eq (slot-definition-name slot) 'slot-list)
>      (call-next-method)
>      (cdr (assoc (slot-definition-name slot)
>                  (slot-value object 'slot-list)))))
>
> (defmethod (setf slot-value-using-class)
>    (new-value (class list-class) object slot)
>    (error "This metaclass does not support side effects."))
>
> (defmethod slot-boundp-using-class
>    ((class list-class) object slot)
>    (if (eq (slot-definition-name slot) 'slot-list)
>      (call-next-method)
>      (assoc (slot-definition-name slot)
>             (slot-value object 'slot-list))))
>
> (defmethod slot-makunbound-using-class
>    ((class list-class) object slot)
>    (error "This metaclass does not support side effects."))
>
> [Untested, and could be improved, but I hope this gets the idea across.]
>
> Pascal
>
> --
> My website:http://p-cos.net
> Common Lisp Document Repository:http://cdr.eurolisp.org
> Closer to MOP & ContextL:http://common-lisp.net/project/closer/

W.r.t. SETF, it has not disappeared from the code. Your's and David's
solutions both use the destructive SETF but within a clever stop-and-
copy model that hopefully protects the user from the harmful
consequences.

My feeling is that the harmful consequences should not have been there
in the first place.  If I buy a new car the first thing I do not want
to do is to insulate the electricals to prevent me getting a shock.  I
expect the factory to do that for me.

FP and Lisp already contain all the tools for doing this job
elegantly.  Closures and A-lists precede CLOS by a generation.  There
are strong arguments for using them. So why spend so much effort on
applying foundation makeup to CLOS to make it look like the solution I
offer when the right thing is there for the taking? No need to worry
that the makeup will fall away and the truth be revealed because
WYSIWYG.

Yes, you can screw up my version by using RPLACD on it.  But the
difference is that you have to *try* to screw it up. Equivalently, its
like buying a new car and then removing the insulation and getting a
shock.  That's not covered by warranty and you'd have a hard time
making a claim in court.  Though even here Qi will stop you if type
checking is enabled, since RPLACD is not part of the inbuilt type
theory.

Mark
From: Pascal Costanza
Subject: Re: type secure CLOS?
Date: 
Message-ID: <5nrkfaFjl6a4U1@mid.individual.net>
Mark Tarver wrote:

> So why spend so much effort on
> applying foundation makeup to CLOS to make it look like the solution I
> offer when the right thing is there for the taking? 

To take advantage of the rest of CLOS, and to not have to reimplement it 
all from scratch.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ken Tilton
Subject: Re: type secure CLOS?
Date: 
Message-ID: <DO1Si.33$aK3.30@newsfe12.lga>
Pascal Costanza wrote:
> Mark Tarver wrote:
> 
>> So why spend so much effort on
>> applying foundation makeup to CLOS to make it look like the solution I
>> offer when the right thing is there for the taking? 
> 
> 
> To take advantage of the rest of CLOS, and to not have to reimplement it 
> all from scratch.

Right. I think it is a toss-up. Mark has these deep theoretical goals 
that might make it better to build his own OO model (if he even calls it 
that, but you get my drift) from a few primitives. The quick win of 
having the CLOS ball of mud straight off the shelf is less quick if he 
has to post hoc impose a theory thingy on it all.

In Mark's shoes I'd reinvent the wheel. Continuous theoretical basis, it 
will go fast as PG showed in On Lisp, and it will be more fun anyway, 
always the trump card for me.

kenny

-- 
http://www.theoryyalgebra.com/

"Career highlights? I had two. I got an intentional walk
from Sandy Koufax and I got out of a rundown against the Mets."."
                                                   - Bob Uecker
From: Pascal Costanza
Subject: Re: type secure CLOS?
Date: 
Message-ID: <5ns2ieFk350mU1@mid.individual.net>
Ken Tilton wrote:
> 
> 
> Pascal Costanza wrote:
>> Mark Tarver wrote:
>>
>>> So why spend so much effort on
>>> applying foundation makeup to CLOS to make it look like the solution I
>>> offer when the right thing is there for the taking? 
>>
>>
>> To take advantage of the rest of CLOS, and to not have to reimplement 
>> it all from scratch.
> 
> Right. I think it is a toss-up. Mark has these deep theoretical goals 
> that might make it better to build his own OO model (if he even calls it 
> that, but you get my drift) from a few primitives. The quick win of 
> having the CLOS ball of mud straight off the shelf is less quick if he 
> has to post hoc impose a theory thingy on it all.
> 
> In Mark's shoes I'd reinvent the wheel. Continuous theoretical basis, it 
> will go fast as PG showed in On Lisp, and it will be more fun anyway, 
> always the trump card for me.

Subtle. ;)

Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ken Tilton
Subject: Re: type secure CLOS?
Date: 
Message-ID: <1W4Si.2$wP5.1@newsfe12.lga>
Pascal Costanza wrote:
> Ken Tilton wrote:
> 
>>
>>
>> Pascal Costanza wrote:
>>
>>> Mark Tarver wrote:
>>>
>>>> So why spend so much effort on
>>>> applying foundation makeup to CLOS to make it look like the solution I
>>>> offer when the right thing is there for the taking? 
>>>
>>>
>>>
>>> To take advantage of the rest of CLOS, and to not have to reimplement 
>>> it all from scratch.
>>
>>
>> Right. I think it is a toss-up. Mark has these deep theoretical goals 
>> that might make it better to build his own OO model (if he even calls 
>> it that, but you get my drift) from a few primitives. The quick win of 
>> having the CLOS ball of mud straight off the shelf is less quick if he 
>> has to post hoc impose a theory thingy on it all.
>>
>> In Mark's shoes I'd reinvent the wheel. Continuous theoretical basis, 
>> it will go fast as PG showed in On Lisp, and it will be more fun 
>> anyway, always the trump card for me.
> 
> 
> Subtle. ;)

I was going to say "near genius insight into another developer's wants 
and desires" after seeing Mark had posted the same conclusion at the 
same time I was composing mine.

You thought I was being ironic because everything looks like a nail to 
your CLOS hammer, a big mistake if you ever hope to get certified as a 
Real Lisper.

In this very special case (the theory thing) building up from the solid 
foundation Mark sees in core Lisp is the way to go.

kt

-- 
http://www.theoryyalgebra.com/

"Career highlights? I had two. I got an intentional walk
from Sandy Koufax and I got out of a rundown against the Mets."."
                                                   - Bob Uecker
From: Pascal Costanza
Subject: Re: type secure CLOS?
Date: 
Message-ID: <5nske4Fk3jkvU1@mid.individual.net>
Ken Tilton wrote:
> 
> 
> Pascal Costanza wrote:
>> Ken Tilton wrote:
>>
>>>
>>>
>>> Pascal Costanza wrote:
>>>
>>>> Mark Tarver wrote:
>>>>
>>>>> So why spend so much effort on
>>>>> applying foundation makeup to CLOS to make it look like the solution I
>>>>> offer when the right thing is there for the taking? 
>>>>
>>>>
>>>>
>>>> To take advantage of the rest of CLOS, and to not have to 
>>>> reimplement it all from scratch.
>>>
>>>
>>> Right. I think it is a toss-up. Mark has these deep theoretical goals 
>>> that might make it better to build his own OO model (if he even calls 
>>> it that, but you get my drift) from a few primitives. The quick win 
>>> of having the CLOS ball of mud straight off the shelf is less quick 
>>> if he has to post hoc impose a theory thingy on it all.
>>>
>>> In Mark's shoes I'd reinvent the wheel. Continuous theoretical basis, 
>>> it will go fast as PG showed in On Lisp, and it will be more fun 
>>> anyway, always the trump card for me.
>>
>>
>> Subtle. ;)
> 
> I was going to say "near genius insight into another developer's wants 
> and desires" after seeing Mark had posted the same conclusion at the 
> same time I was composing mine.
> 
> You thought I was being ironic

No.

> because everything looks like a nail to 
> your CLOS hammer, a big mistake if you ever hope to get certified as a 
> Real Lisper.
> 
> In this very special case (the theory thing) building up from the solid 
> foundation Mark sees in core Lisp is the way to go.
> 
> kt
> 


-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Mark Tarver
Subject: Re: type secure CLOS?
Date: 
Message-ID: <1192798062.443926.273110@e34g2000pro.googlegroups.com>
On 19 Oct, 12:58, Pascal Costanza <····@p-cos.net> wrote:
> Mark Tarver wrote:
> > So why spend so much effort on
> > applying foundation makeup to CLOS to make it look like the solution I
> > offer when the right thing is there for the taking?
>
> To take advantage of the rest of CLOS, and to not have to reimplement it
> all from scratch.
>
> Pascal
>
> --
> My website:http://p-cos.net
> Common Lisp Document Repository:http://cdr.eurolisp.org
> Closer to MOP & ContextL:http://common-lisp.net/project/closer/

That is a good argument and at this point a value judgement is needed.
Go with a non-standard elegant model that uses well-tried FP concepts
or adopt CLOS because of the bells and whistles and because it is
generally used.

I'll choose elegance very time because that is what drives me but it
is
not a provably correct choice.

Re: bells and whistles though, you can generally recover all these
pretty
quickly if you have the right representation and the right set of
primitives. Elegance does bring power in the long run.

Mark
From: Mark Tarver
Subject: Re: type secure CLOS?
Date: 
Message-ID: <1192812773.824443.150100@y27g2000pre.googlegroups.com>
On 19 Oct, 12:58, Pascal Costanza <····@p-cos.net> wrote:
> Mark Tarver wrote:
> > So why spend so much effort on
> > applying foundation makeup to CLOS to make it look like the solution I
> > offer when the right thing is there for the taking?
>
> To take advantage of the rest of CLOS, and to not have to reimplement it
> all from scratch.
>
> Pascal
>
> --
> My website:http://p-cos.net
> Common Lisp Document Repository:http://cdr.eurolisp.org
> Closer to MOP & ContextL:http://common-lisp.net/project/closer/

The only catch with my model is that closures are a bit opaque.  How
do you find what is in the class ship for instance?

The solution is to design instances so that they tell you all you need
to know about the class from which they were generated.  Rather like
the task of reading the inscription on a metal seal which is printed
backwards and you can't really read it.  You can't read the seal
(class)but if you use the seal and press it into hot wax to get an
impression (instance)  then the impression will give you all you need
to know about the seal.

Here is an example;

(5+) (defclass object ()
        weight number;)
#<COMPILED-CLOSURE class-function-1> : unit

(6+) (make-instance object)
[[inherit [list class] object] [weight number . #\Escape]] : (instance
object)

(7+) (slot-value (make-instance object) inherit)
[object] : (list class)

(8+) (defclass ship (object)
           name string;)
#<COMPILED-CLOSURE class-function-1> : unit

There are only really 4 important basic primitives in my system and
they are very easy to code.

1. make-instance
type:

      Class : class;
      ______________________________
      (make-instance Class) : (instance Class);

Makes an instance of a class

2. slot-bound?
type: (instance Class) --> (slot Class A) --> boolean
 Returns true iff there is a slot with a value in that instance.

3. slot-value
 type:  (instance Class) --> (slot Class A) --> A
 Returns the value of a slot or an error if there is no slot with a
value.

4. change-slot
 type: (instance Class) --> (slot Class A) --> A --> (instance Class)
 Change the slot and return the resulting instance.

Because an instance in Qi classes is a wax impression of the class
definition you can find all about the class from the instance.  Here
for  is a program that computes all the superclasses of a class.

\Give me all the superclasses of a given class.\
(define superclasses
  {class --> [class]}
   Class -> (let Classes (immediate-superclasses Class)
                      (fix superclass-loop Classes)))

\Find the superclasses of the superclasses\
(define superclass-loop
  {[class] --> [class]}
    Classes -> (mapunion immediate-superclasses Classes))

\Find the immediate superclasses by creating an instance and
 looking in the inheritance slot.\
(define immediate-superclasses
  {class --> [class]}
   Class -> (let Instance (make-instance Class)
                      Classes (slot-value Instance inherit)
                      Classes))

(define mapunion
  {(A --> [A]) --> [A] --> [A]}
  _ [] -> []
  F [X | Y] -> (union (F X) (mapunion F Y)))

(17+) (superclasses object)
[object] : (list class)

(18+) (superclasses ship)
[ship object] : (list class)

Mark
From: David Golden
Subject: Re: type secure CLOS?
Date: 
Message-ID: <1BJRi.22682$j7.429142@news.indigo.ie>
Mark Tarver wrote:

> 
> What I'm picking up here is the CLOS is generating a fair amount of
> procedural murk 

I don't think it's quite fair to characterise it as "murk", it's
procedural, but right there out in the open and in CLOS's case, pretty
carefully defined. 

You may be trying to formalise OO in the "wrong" mindset - maybe look to
the process calculi:
e.g. Davide Sangiorgi's 1997 "An interpretation of Typed Objects into
Typed pi-calculus" 
http://www.cs.unibo.it/~sangio/mypapers.html
[piOCtyped.ps.gz]
From: Pascal Costanza
Subject: Re: type secure CLOS?
Date: 
Message-ID: <5no91vFj8ihoU1@mid.individual.net>
Mark Tarver wrote:

> Very good; but now my next question.   What happens w.r.t. garbage
> collection to these clones?  Are they global objects which remain
> uncollected?  

No, why should they remain uncollected? CLOS objects pretty much behave 
like structs in that regard...


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/