On Wednesday, June 17, 2015 at 5:52:20 AM UTC-7, Darij Grinberg wrote: > > I have a feeling that at least one reply to this message will try to > justify the status quo by claiming that users cannot be expected to go > search the doc for the right constructor, that the current syntax is the > simplest / most intuitive and is what people are used to; etc. >
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. - 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 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>) 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. -- 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.