Hi Nils, On Wed, Jun 17, 2015 at 4:37 PM, Nils Bruin <[email protected]> wrote: > On Wednesday, June 17, 2015 at 5:52:20 AM UTC-7, Darij Grinberg wrote: > Here is that response then. For the most part, matrix does work nicely and I > really appreciate the typing it saves. > > I think a good interface design pattern here is: > > - provide the basic object constructors, with a very rigid, unambiguous > input structure. When you use these, you know exactly what is going to > happen because the system doesn't have to guess at all. For matrices, this > should probably be the constructors belonging to the various matrix spaces.
+1. Ducktyping as a convenience option is OK, but ducktyping as the only public interface is plain wrong. Unfortunately, currently the ducktyping is not just in the matrix constructor; it is split across the three stations I mentioned (matrix constructor, matrix space, matrix class). Apparently every single of our matrix classes has its own way of recognizing "scalar matrix" input (that very matrix(n, n, c) syntax that has caused the present discussion), apparently written by different people (since the error messages differ). I suspect there is no way for sufficiently generic code to sidestep all of the ducktyping at the present time, and this is just bad. > - provide on top of that convenience constructors that do make some effort > to try and understand what you mean. That would be "matrix". A corollary is > that this routine will occasionally get it wrong and sometimes necessarily > so. I would not want to do away with the convenience of "matrix" because it > doesn't work for some more complicated constructions. In those cases the > users should be smart enough to go and read the documentation and look up > the right constructor. The "matrix" doc would ideally have some pointers. > > The problem with matrix(n,n,c) is that it's actually coming from matrix > rings! Scalars should probably coerce in there to make A - 1 work. It's > something supported on a level below. > > Oddly enough, it's matrix(n,m,<callable>) that's the hard signature to > recognize there. It is the harder one, but it is also the saner one in my opinion. Nevertheless, there is nothing wrong with making it explicit as Matrix.from_callable(n, m, <callable>) (or "from_function" or "from_family", depending on how we want to call it). Once the basic constructors have been implemented, is there a way to discourage people from using the ducktyped matrix constructor *in the Sage library*? Some kind of warnings that appear only in doctest mode and tell you what basic constructors should be used? > It seems we have the following signatures. > > [1] matrix([ring],n,n,<scalar>) > [2] matrix([ring],n,m,<callable>) > [3] matrix([ring],[n,[m]],<iterable>) > [4] matrix([ring],[n,[m]],<iterable producing iterables>) Also matrix([ring], n[, m]]) to return a zero matrix, and matrix(various kinds of objects). And [3] involves some case analysis, since the iterable can be a dictionary but can also be a flattened list of entries. > The last one includes matrix(ZZ,n,m,[[1,2],[3,4]]) which I think is > completely unambiguous, so that input should not be mistaken for something > else. > > In particular, the following element matches all four: > > sage: R.<x>=QQ[] > sage: S.<y>=R[] > sage: F=x*y*x > sage: F=x*y+x > sage: F(1,1) ##callable, with the right arity > sage: list(F) ##iterable > [x, x] > sage: map(list,list(F)) ##iterable producing iterables > [[0, 1], [0, 1]] > > We end up with sage choosing option [1]: > > sage: matrix(2,2,F) > [x*y + x 0] > [ 0 x*y + x] > > but the other ones would work too: > > sage: matrix(2,2,lambda i,j: F(i,j)) #sage doesn't actually check "callable" > but looks for specific types > [0 1] > [0 2] > > sage: matrix(list(F)) #we're not actually looking for iterables: they need > to be lists or tuples > [x x] > > sage: matrix(map(list,list(F))) > [0 1] > [0 1] > > so ... yeah ... with our current rules, taken with appropriate ducktyping > interpretation, we have input that could specify 4 (different!) matrices. Ouch. It is a good thing matrix currently tests for specific kinds of iterables rather than generally for iterability; but this is not a very good pattern to follow. Best regards, Darij -- 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 [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/sage-devel. For more options, visit https://groups.google.com/d/optout.
