Hi,

On Tuesday, 16 June 2015 20:10:05 UTC+2, Nils Bruin wrote:
>
> Tiebreaker needed:
>
> We have a whole bunch of ways in which a matrix can be constructed. Some 
> of the possible signatures we support according to the documentation:
>
> A)
>
> matrix(n,m, <callable f>)
>
> which constructs the n x m matrix with entries f(i,j), where i,j run throw 
> the row and column indices.
>
> B)
>
> matrix(n,n, c)
>
> which produces c times the n x n identity matrix.
>

Does "kill the whole thing with fire" count as a tiebreaker?

I remember fighting against the matrix constructor and init (a matrix 
apparently has to go through several circles of ducktyping hell before 
being instantiated: first the matrix(...) constructor, then 
MatrixSpace(...).matrix(), then the MatrixSpace(...).__matrix_class 
constructor) half a year ago ( http://trac.sagemath.org/ticket/17124 ), and 
the reason was rather similar: What was meant as an entry was misunderstood 
to be a vector due to it belonging to a free module (the ground ring was a 
free module). I fixed it by adding yet another special case to the 
Frankensteinian mess of a code, not unlike what Jeroen suggested yesterday. 
The good ideas in Jeroen's pseudocode notwithstanding (I 100% agree on 
deprecating matrix(n, n, c), by the way), I am wondering whether the fixes 
of today won't become the bugs of tomorrow. This is not to belittle the 
work done by those who have been improving these constructors for years -- 
they have been bravely cutting heads off a hydra...

What, at least to me, seems to be the underlying problem is our pattern of 
ducktyping input "because we can". Polymorphism is certainly a good idea, 
but this goes far beyond any reasonable notion of polymorphism; it seems to 
be an attempt to save the user some typing time by implementing various 
different constructors all in the __init__ (or classcall, depending on the 
object). Needless to say, checking that these different constructors have 
disjoint domains of definitions is not a viable option: Whoever does this 
would have to have a bird's eye view of the whole Sage landscape (present 
and future). I am not blaming the authors of the matrix classes for not 
expecting that a matrix could be defined over a ring which itself is a free 
module; nor do I expect them to have tested it on the symbolic ring (I 
don't test things on the symbolic ring either) or on a ring R whose zero is 
not R(0) (brace yourself, these bugreports will be coming). Ducktyping has 
its limits when the pond is bottomless and has frogs, chameleons, kraken, 
dead things and horrors unknown. It appears that whoever wrote the doc of 
the matrix constructor ("Calling matrix() with a Sage object may return 
something that makes sense.") was aware of its ability to produce 
deterministic chaos, but several places in the Sage code are using the 
matrix constructor either assuming that it is a reliable piece of code with 
predictable output, or writing their own hacky workarounds to avoid its 
pitfalls. I don't know which is worse.

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. I think we 
are at the point where the downsides outweigh all of these arguments. Not 
having to look up how to build an identity matrix doesn't help if what 
comes out is a TypeError instead of an identity matrix; those aren't very 
user-friendly either. And the "matrix(n, n, c)" syntax makes no sense: 
Being a special syntax for scalar matrices, why does it require the user 
entering the size of the matrix twice? (It throws an error when you try to 
feed it different dimensions.) More importantly, why should one *expect* 
such a syntax? Why shouldn't it instead return the rank-1 matrix filled 
with c's? Or having a single c in cell (1,1) and 0's everywhere else? Sure, 
it's said in the doc, but the doc could just as well refer to 
Matrix.scalar(n, c, ring=R) for a scalar matrix (no, we don't have this 
method, and yes, we should have it). It appears that we are assuming that 
people learn Sage by trial and error, experimenting with various syntaxes 
until they find one that works. Apart from this being a great way to pick 
up bad habits, is this any faster than reading the doc?

  Best regards and sorry for more than the usual snark,
  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.

Reply via email to