IMHO the majority of Sage doesn't actually use dynamic category refinement 
and/or make the category depend on the arguments. And the latter is just a 
special case of the former.

If you really need to dynamically change the category then let the 
metaclass construct a suitable class and assign to __class__ or use a 
getattr hack. You still don't need differently-named classes Foo and 
Foo_with_category. 



On Friday, August 8, 2014 4:44:23 PM UTC+1, Simon King wrote:
>
> Hi Volker, 
>
> some remark: 
>
> On 2014-08-08, Volker Braun <vbrau...@gmail.com <javascript:>> wrote: 
> > IMHO the category 
> > functionality would have been better implemented by a proper metaclass 
> than 
> > by dynamically assigning to __class__ to dynamically construct the class 
> at 
> > import time, not at construction time. 
>
> This would mean: You provide the category functionality during the 
> construction of the *class*, rather than during the construction time of 
> the *instance* of the class. 
>
> Let Foo be a class whose instances may be objects in different categories 
> (such as matrix spaces, which are algebras if the matrices are square, and 
> modules otherwise). A metaclass can easily add methods of, say, 
> Modules(Rings()).parent_class to Foo (until recently, you would have 
> needed 
> to explicitly provide a base ring, rather than just saying that it belongs 
> to Rings()). 
>
> But what would you do if Foo(args) has more structure and in fact belongs 
> to 
> Algebras(Rings())? I don't think that this can be solved on the level of 
> the class Foo, unless of course you provide Foo with a classcall 
> metaclass that, depending an the given arguments, dynamically creates a 
> new 
> class Foo_algebras adding the methods from Algebras(Rings()).parent_class, 
> and 
> then Foo(args) returns an instance of this new class Foo_algebras. 
>
> But then, how would this be any better than what the category framework is 
> currently doing? 
>
> Hmm. Perhaps actually it *is* better. Currently, the following happens: 
>
> 1) Foo.__init__ choses a category CAT depending on the given arguments. 
> 2) _init_category_ replaces self.__class__ by a sub-class Foo_cat, that is 
> dynamically created using Foo and CAT. If Foo is a cython class, then 
> overriding self.__class__ by Foo_cat is impossible. 
>
> With a (classcall) metaclass, we could make the following work: 
>
> 1) When Foo(args) is called, we defer to Foo.__classcall__. 
> 2) In Foo.__classcall__, the category CAT is chosen depending on the 
> given args. Perhaps this could be done in some static method 
> Foo._choose_category_. 
> 3) Depending on CAT, a sub-class Foo_cat of Foo will be created and an 
> instance 
> O of it will be created and initialised. 
> 4) __classcall__ returns O. 
>
> Advantages of the second scenario: 
> - Chosing the category is done in a separate method. Looks cleaner than 
>   doing it in __init__. 
> - There will be no change of O.__class__ after creation of O, since O is 
>   created as an instance of Foo_cat right away. 
> - This would work even if Foo was a Cython class. 
>
> However, it would be an awful lot of work to change... 
>
> Best regards, 
> Simon 
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"sage-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-devel+unsubscr...@googlegroups.com.
To post to this group, send email to sage-devel@googlegroups.com.
Visit this group at http://groups.google.com/group/sage-devel.
For more options, visit https://groups.google.com/d/optout.

Reply via email to