Dear Paul-Olivier, On 2012-11-26, Paul-Olivier Dehaye <pauloliv...@gmail.com> wrote: > My understanding of aspect-oriented programming in general: encourages the > developer to realize that there are several concerns that will be present > in a large project, and to organize the project in such a way to minimize, > at any location in the code, the number of concerns whose concrete > implementation is relevant. > ... Identifying these concerns > (which are just fuzzy words and not programming constructs) and structuring > the code (/concern1, /concern2, ...) around them helps guide people to the > relevant places in the code
My impression is that Sage's directory structure tries to address different concerns (meaning here: different mathematical topics). Do you think that the present directory structure does not succeed to keep different concerns apart? Sure, coercion is everywhere, and so it can easily be that a memory leak shows up in elliptic curves but is ultimately caused by caching data for coercion. > Don't confuse a plan with more docs buried in the code. There is > documentation everywhere that explains what that particular class or method > is doing, but nothing at a higher level: where is sage's outline as it > stands? (the first part of "State of Sage" speech?). Ideally, every concern of Sage (according to the directory structure, it is categories, coding, combinat, ..., structure, symbolic, tensor) should have a top-level documentation, in addition to the documentation of each class/method. I am actually not sure to what extent such top-level documentation exists. > - Separate the actual Categories framework as it currently exists into two > parts. The first would be a "Mathematical abstraction" layer, where very > abstract mathematical information is implemented. > - Force the mathematical developer to think in terms of mathematics first, > i.e. require a category to be specified in order to be able to construct a > Parent. +1. But how to enforce it? Some people (including myself) occasionally try to shift old code to the new category and coercion model. Would it be enough to ask the reviewers of a patch to take care that the category of any *new* parent is duely defined? Or should one make doctests fail on purpose, if a parent is not properly put into a category, to enforce its use? > - Doing it this way helps us automatically create a lot of tests first, > before anything concrete has been written (developer needs not be concerned > about writing the tests, they are magically created). By the way: I think automated tests are an important aspect of our category framework, and my impression is that developers should use it more often! > - Specify the coercions that should exist at the "Mathematical abstraction" > level. > - Specify for each new Parent how to coerce from the Category down to the > Parent. Could you elaborate a bit more? What does "to coerce from the category down to the parent" mean, and *what* coercions should exists at the mathematical abstraction level? There are of course tools to define coercions. > - All the coercions and tests are automatically generated from this > information. Well, coercions *are* automatically generated (by some kind of backtracking algorithm) from the output of the _coerce_map_from_ methods. > (PS: it might already be possible to use the coercion model in this way. If > so, please please please point me to where it is explained. In any case, my > point stands as I was not able to find this despite searching.) A while ago, I have created a public worksheet on "how to implement basic algebraic structures in Sage", using category framework and coercion. I think at some point it was supposed to become part of the documentation, but I think we lost momentum. > Once we agree on the desired modularity we need in the code, we can decide > on how to modify what we have to achieve separation of concern. In Python, > the answer would most likely be "with decorators and metaclasses" (indeed, > as you pointed out, cached_function and so on isolate one aspect of a > function). Both decorators and metaclasses are used in Sage. Note one problem, though: If you want to create a new class inheriting from classes with distinct metaclasses, then Python complains. I had experimental code to overcome that problem, namely by using meta-metaclasses that dynamically create a new common metaclass out of any list of metaclasses. Hence, if A and B are classes with metaclasses MA and MB, then you can define class C(A,B) so that C gets a dynamically created metaclass MC that is a sub-class of both MA and MB. The idea is that both MA and MB (which *are* metaclasses) have a common meta-metaclass MM, and MM is able to create a new metaclass MC out of MA and MB. In that way, you could have metaclasses for different purposes, and can freely combine them: You want a class that is pickled by construction and whose instances are cached? Then simply combine DynamicMetaclass and ClasscallMetaclass. No need to separately/manually define DynamicClasscallMetaclass anymore - the meta-metaclass would do that for you. But it seems people found the idea of meta-metaclasses a bit confusing... > - "This will slow down the one class I am using a lot": Not if it's done > right. In fact, if it's done very right it would speed up considerably > everything, +1. One example: One can write a FastHashMetaclass. If you then take a python class A that has a `__hash__` method, and apply to A the FastHashMetaclass, then A.__hash__ would automatically be turned into a fast Cython hash that moreover is cached (so that the hash value does not need to be computed repeatedly). Best regards, Simon -- You received this message because you are subscribed to the Google Groups "sage-devel" group. To post to this group, send email to sage-devel@googlegroups.com. To unsubscribe from this group, send email to sage-devel+unsubscr...@googlegroups.com. Visit this group at http://groups.google.com/group/sage-devel?hl=en.