I should probably spend more time with the fmt package before adding to this discussion, but oh well. Here’s what my reaction at the moment is to do.
// Format returns the matrix as a nicely formatted string
func Format(a Matrix, verb string) string{
}
Now, inside Format, we can parse the verb string. It will be “[number][.number]rune”. The numbers mean what they mean in fmt, i.e. specify the printing precision. The verbs also mean what they mean in fmt. Naively, this could be done with
var s string
r, c := a.Dims()
for i := 0; i < r; i++{
for j := 0; j < c ; j++{
s += fmt.Sprintf(verb, a.At(i,j))
}
}
Obviously it needs a lot of error checking and doing the actual pretty printing part.
If we wanted to support the “#” we parse it out ourself and then print the header if it’s there. As we are parsing the verb ourselves, we could define whatever language we wanted in the formatting string, so, for example, the space as you suggest in the PR. Therefore,
mat64.Format(a, “%# .5e)
would print all of the entries of a with five decimal places, and those that are known to mat64 to be by definition zero have a . instead of a value. This would be coded by parsing the flag, seeing there is a # and a ‘ ‘, thus printing the header, printing the dots, and passing “%.5e” to Sprintf on all of the elements.
This is somewhat covoluted, so another option is to have
func Format(a Matrix, matVerb string, elemVerb string)
Where elemVerb is what is passed to fmt.Sprintf on each of the values and matVerb are our special verb on printing matrices (dot, header, etc.). This more cleanly establishes what aligns with fmt and what is different.
Lastly, I know there are good reasons to not fully construt a string which is why the fmt.State.