[Openmcl-devel] [off-topic] Adding a slot to a class using the MOP
Pascal Costanza
pc at p-cos.net
Wed Apr 24 00:19:10 PDT 2013
It may not be well-defined what "the first slot" in a class definition is. This depends a lot on what other metaclasses may be mixed in. There is a subprotocol in the MOP for determining the order of slots, and that may mess things up.
While the other potential problems we discussed so far are more theoretical in my experience, I have actually encountered this particular one of slot order a few times already.
There is a reason why the recommended way is recommended. ;)
I agree with you that this should be simpler. The reason why it's not simple is that the CLOS MOP is an operational set of protocols. It would be good to have some form of declarative layer on top of that. It's not straightforward to capture everything useful in such a layer, but I believe such a layer would be possible. Thomas Kühne did some work some time ago on such a declarative layer (for Java, not for CL, unfortunately, called DeepJava) which I found very promising…
Pascal
On 23 Apr 2013, at 18:50, Ron Garret <ron at flownet.com> wrote:
> Just for the record, I do understand that there is a good reason for this rule. I guess I should have added a winky emoticon, but I was actually feeling pretty grumpy about it at the time. Actually, I'm still feeling grumpy. It bothers me when things that should be simple turn out to be hard. This is usually my complaint about *other* programming languages, not CL.
>
> For the purposes of my current project I decided to simply dictate that the first slot in a class definition is the primary key, and that if the name of that slot starts with an underscore it will be auto-generated. It's not an ideal solution, but it does have the advantage of being light weight :-)
>
> Thanks for all the replies.
>
> rg
>
> On Apr 23, 2013, at 12:24 AM, Pascal Costanza wrote:
>
>> The rule is not only there to say that something is undefined (har! har! now deal with this, suckers! ;).
>>
>> The rule is there so that different libraries don't interfere with each other. If you specialize at least one argument on one of "your own" classes or objects, then your method is less likely to interfere with other methods from other libraries. If you don't specialize, and other libraries also don't specialize, then you may end up just overriding each other's methods, which is not good.
>>
>> Pascal
>>
>> On 23 Apr 2013, at 09:04, Ron Garret <ron at flownet.com> wrote:
>>
>>> Damn language lawyers. :-(
>>>
>>> Oh well, CCL is the One True Common Lisp, so I don't care about portability. Besides, it seems to work in SBCL and CLisp too, so fie on your silly standards!
>>>
>>> rg
>>>
>>> On Apr 22, 2013, at 11:32 PM, Pascal Costanza wrote:
>>>
>>>> You're invoking undefined behavior here, because your method on ensure-class-using-class doesn't specialize on any of your own metaclasses. See bullet one in "Restrictions on Portable Programs" in the CLOS MOP specification.
>>>>
>>>> Pascal
>>>>
>>>> On 23 Apr 2013, at 08:29, Ron Garret <ron at flownet.com> wrote:
>>>>
>>>>> Why not this?
>>>>>
>>>>> (defmethod ensure-class-using-class :before (class name &rest args)
>>>>> (setf (get 'class-info name) (list* class args)))
>>>>>
>>>>> (defun add-slot (class-name slotspec)
>>>>> (destructuring-bind (class . args) (get 'class-info class-name)
>>>>> (push slotspec (getf args :direct-slots args))
>>>>> (apply 'ensure-class-using-class class class-name args)))
>>>>>
>>>>> It seems to work:
>>>>>
>>>>> ? (defclass foo () (x y z))
>>>>> #<STANDARD-CLASS FOO>
>>>>> ? (add-slot 'foo '(:name q))
>>>>> #<STANDARD-CLASS FOO>
>>>>> ? (describe (make-instance 'foo))
>>>>> #<FOO #x3020028B7DAD>
>>>>> Class: #<STANDARD-CLASS FOO>
>>>>> Wrapper: #<CCL::CLASS-WRAPPER FOO #x3020028B9EBD>
>>>>> Instance slots
>>>>> Q: #<Unbound>
>>>>> X: #<Unbound>
>>>>> Y: #<Unbound>
>>>>> Z: #<Unbound>
>>>>>
>>>>> On Apr 22, 2013, at 1:23 PM, Pascal Costanza wrote:
>>>>>
>>>>>> Check out AspectL, it provides exactly what you want.
>>>>>>
>>>>>> However, it's also worthwhile spending some time on thinking about whether there is a better design for your problem. Adding slots like this creates a lot of problems. Maybe a typical hash table based meta class already provides what you need...
>>>>>>
>>>>>> Pascal
>>>>>>
>>>>>> Sent from my iPad
>>>>>>
>>>>>> On 22 Apr 2013, at 19:32, Ron Garret <ron at flownet.com> wrote:
>>>>>>
>>>>>>> Apologies for the non-CCL-related question, but c.l.l. is slow today and I'm really stuck on this.
>>>>>>>
>>>>>>> I need to dynamically add a slot to a class using the MOP. There doesn't seem to be a standard add-slot method, so I figure I need to use something like ensure-class. To do that, I need to reconstruct the argument to :direct-slots from the existing class definition so I can add a slot without disturbing the existing slots. Before I went down this rabbit hole I thought I'd ask: is there a better/easier way to do this? Surely I'm not the first person to want to do this.
>>>>>>>
>>>>>>> Many thanks,
>>>>>>> rg
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> Openmcl-devel mailing list
>>>>>>> Openmcl-devel at clozure.com
>>>>>>> http://clozure.com/mailman/listinfo/openmcl-devel
>>>>>
>>>>
>>>> --
>>>> Pascal Costanza
>>>>
>>>>
>>>>
>>>
>>
>> --
>> Pascal Costanza
>>
>>
>>
>
--
Pascal Costanza
More information about the Openmcl-devel
mailing list