On Aug 12, 6:40 pm, Ryan Hinton <iob...@email.com> wrote: > Hello, Johan. > > I'm a little confused at your restatement of my idea as well as your > description of your idea. Let me provide some code fragments to be > concrete. > > class Code: > def __init__(..., encode_algorithm=['alg_name', args], > decode_algorithm=['alg_name', args], ...): > # handle encoding algorithm; the real implementation should > allow just > # passing in the name instead of a list containing the name > and > # arguments to initialize the requtesd algorithm > enc_alg_name = encode_algorithm[0] > if 'generator-matrix' == enc_alg_name: > # initialization for generator matrix, may use the > accompanying arguments > ... > elif ('none' == enc_alg_name) or None is enc_alg_name: > # no encoding provided; when base classes handle the > encoding > # algorithm, they can use this code path or just catch the > # exception from the next path > self.encoder = lambda ...: raise ValueError('encoding not > allowed on this Code instance.') > else: > raise NotImplementedError('requested encoding algorithm %s > not provided.' % enc_alg_name) > > # similar pattern for decoding algorithm specification > ... > > def encode(*args, **kwds): > # just delegate the encode requests > self.encoder(self, *args, **kwds) > > def decode(*args, **kwds): > # similarly delegate the decode requests > self.decoder(self, *args, **kwds) > > So each Code instance keeps a reference to one callable object each > for encoding and decoding. My assumption is that these objects are > relatively small/cheap. If lots of space is required (large tables?), > this information could be cached and shared between encoder/decoder > objects (i.e. in a singleton with lookup by encode/decode > parameters). Or we could provide another __init__ keyword argument to > provide the encoder/decoder object directly so that multiple code > instances actually return the same object. On third thought, these > two ideas can be combined so the if/elif chain will somehow find the > same object (at least if the objects are expensive) given the same > code parameters. (But why do you need multiple instances of the same > code?) > > I think I see the confusion on rereading your post again. My idea -- > as described above -- is to create/store a reference to the encoder > and decoder objects *in the Code constructor*. They can be omitted > altogether if encoding/decoding is not required. Or they can be > created externally and provided through setters (i.e. set_encoder(), > set_decoder()). This also provides a path to change the encoding/ > decoding algorithm at runtime if desired. Again, expensive > initialization can be delayed until the first call to encode/decode in > case a Code subclass specifies default encoder/decoder defaults. > > Hope this is clearer. :-) > > - Ryan
Ok, so now I understand your idea, and mine is actually not too far from to yours. I'll demonstrate by commenting yours and amending it until we arrive at mine :-) My primary objection is that for object-oriented ideology, I think that constructors should specify what inherently _defines_ some object. I don't think that the encoder/decoder algorithms do this for a code. Therefore, I wouldn't really want them to be in the constructor. If that is accepted, then the set_en/decoder functions you suggest should always be used for specifying the algorithms by user-instantiated objects. But in that case, why does the Code object even need to bother about these De/Encoder objects? They work perfectly well on their own. The reason could be the user-friendly intention of your constructor: put the name-to-algorithm check in your constructor into a function get_en/decoder in the Code object, which constructs and returns the specified algorithm, constructed in the correct way and from the intended class; without the user having to find out what such a En/Decoder class might be called in the Sage tree. These are then used for en/decoding. Also, this is a guarantee to the user, that he is using a correct en/decoder for the code in question, even if he wants to change algorithm in midstream. This way, we can scrap the set_en/decoder functions, and in the case that the user really wants to use a en/decoder that is not intended (e.g. written by himself), he simply constructs it outside of the Code object and uses it directly. If it works, it can later be added to Sage and built into the Code class as a possibility. A secondary objection is easily amendable: I think it is very important according to Sage methodology, that the Code objects work out-of-the-box for both encoding and decoding without the user having to worry about different algorithms existing. This could of course be done in your model by replacing the error-throwing with a sensible default. If we want to amend the above idea, then we could let Code classes have en/decode() functions which chooses, constructs, caches and uses a sensible default algorithm. Voilá, and we arrive at my idea :-) So, I guess both ideas have the same flexibility and scalability, so which to use is largely a matter of taste. I still like mine best, but I gladly listen to arguments against it; I hope we can agree on something. If you are as confused as it turned out I was when reading your idea, I can quickly cook up some example-code ;-) > I think I see the confusion on rereading your post again. My idea -- > as described above -- is to create/store a reference to the encoder > and decoder objects *in the Code constructor*. They can be omitted > altogether if encoding/decoding is not required. Or they can be > created externally and provided through setters (i.e. set_encoder(), > set_decoder()). This also provides a path to change the encoding/ > decoding algorithm at runtime if desired. Again, expensive > initialization can be delayed until the first call to encode/decode in > case a Code subclass specifies default encoder/decoder defaults. I don't think we really have to worry about this much. The intention is for En/Decoder objects to be constructed only rarely (~once per code object), and they will almost always be different. Adding checks for uniqueness will most likely end up adding overhead in the usual case with only miniscule savings in the rare case. If it turned out that some en/decodes often seemed to require the same pre-computation, the singleton caching and checking could be implemented separately for each such (very rare) case, I think. Cheers, Johan -- To post to this group, send an email to sage-devel@googlegroups.com To unsubscribe from this group, send an email to sage-devel+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sage-devel URL: http://www.sagemath.org