>> But, in sympy, the printer class has all of these methods for all the >> classes that need to be printed. Why is it done this way? > > See issue 908 for some details. ( > http://code.google.com/p/sympy/issues/detail?id=908 )
I skimmed quickly through some of this and it does sound like there are some subtle issues with printers - especially when there are Python builtins (list, dict, tuple) that also have to be handled. I do think that building the printers as they are now is probably fine for Sympy built-ins. In that case 1) there are a finite number of classes that need to be handled and 2) all of them are under the control of Sympy. >> The difficulty is that if I implement a new subclass of basic, I also >> have to add methods to the various printer classes. This seems a bit >> silly as 1) it really breaks encasulation 2) it spreads the code for >> an object all over the code base > > Well the encapsulation is just different, its an action on the object. > There are a lot of special things that is going on in some of the > printers, such as how each printer would like to represent a paren. > Rather than making all the code know this it is "encapsulated' in the > printer. I believe this is pretty standard in the Model, View, > Controller world. > > On the flip side this design does make it much easier to make a new > printer. If I have some special coding environment I don't have to go > through every class and add _print_foo someplace, I can do it all in > one place. Unfortunately there is a bit of a bug in the design, one > can't just overload __str__ with a printer because the default seems > to call that, we should probably make __repr__ the default. Yes, and printers should be easy to extend. However, the current design makes it more difficult for users to create their own Sympy classes. Let's say I create a sub-class of basic to handle a certain type of Operator in quantum mechanics, and this lives in my own project outside of sympy. Currently I have to 1) patch Sympy's built-in printers so that they know about my Operator class (probably not going to happen) or 2) subclass Sympy's printer to handle the printing of my class. This is all fine and dandy until I have to integrate with someone else's custom Sympy classes that have their own printers. Then, you are in a nasty mess of multiple inheritance and circular dependencies between different projects (I need your printer, you need mine). Here is a proposal. Keep the Sympy printer as they are today. However, if a printer encounter's an object that it doesn't know how to print, it asks the object itself if knows how to print itself. For instance, the Sympy latex printer could look at my fictitious Operator class for: Operator._latex_ And call it to get the latex representation. This would be a trivial mod of the current printers and would open the door to make it much easier to extend sympy. >> So, why doesn't sympy use more informal protocols to enforce >> encasulation rather than spreading the logic for an object all over >> the place? > > > Do you have some examples of these protocols? Sure in Python itself: __str__ __int__ __float__ etc. In Sage (which Sympy tries to interoperate with), they use informal protocols all over the place. Their printing is based on this idea (_latex_ methods) and so is their coertion system (_pari_, etc). --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sympy" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sympy?hl=en -~----------~----~----~----~------~----~------~--~---
