35

Perl6::Math::Matrix (Part 3: When to Use MMD)

 5 years ago
source link: https://www.tuicool.com/articles/hit/vMJbmyq
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

In this guide about what to consider when writing a Perl 6 module, we (afterPart 1 andPart 2) will reach Perl 6's great power of signatures . They enable a feature that is very often used in Perl 6 (internally and externally). Here are I look at when the usage of MMD makes the most sense.

In short: M ulti M ethod D ispatch allows you to have multiple methods or subs with the same name but different signatures. When you call the method, the compiler decides according to the type and number of arguments, which actual method is allowed to run (and if no signature fits the call, an error will be thrown — same as with any malformed call). But this is just the technical side. There is also the software engineering/API side. When is it useful to combine different functionalities under the same name and when does it just muddy the waters? To clear up that question, I want to look at three (+1) examples from the module at hand.

Constructors

Unsurprisingly, we have a method called new . During the original design, which was the work of Pierre Vigiernew just accepted an Array of Arrays of Numbers as in: [[1,2],[3,4]] . It also informed the user how to understand a matrix. Very recently, I added the possibility to provide a list of lists of numbers or a Str ing that is a direct tabular representation of a matrix. Of course, it makes sense to call all of these methods new . The input of each contains the same data, just in different formats, and the result is also in any case the same — no confusion there.

But we have additional constructors for special matrices, as any system like Mathematica or Octave has (also for the reasons mentioned last time). I named them new-zero, new-identity, and so on. Not using these with MMD in this case was easy because there are three reasons to do so:

  • They do functionally something different. The former constructor methods take the data as is and only transformed them into a new format, a Math::Matrix object. These special constructors take only information about the size or the content of some cells and fill up the rest.
  • There is a clear relation between the name of a special matrix and the signature needed to construct such matrix. The name sets the stage, the signature is subordinated. If we overload new both of them get crammed into the signature as for instance in: Matrix.new('zero', 2, 3) , which really doesn't sit well with my intuition either. It's much clearer to pull the decisive name into the method name to make what will follow clearer. For example: Matrix.new-zero(2, 3) .
  • Last but not least it would be impossible or way too complicated. We would have 7 multi-methods (more planned) with overlapping signatures. To even be able to separate them, we have to insert the name of the special matrix and then we get into the problem of bullet two and that the first param.

norm

A norm is a singular number that reflect the abstract concept of size. You can invent any number of different norms, but the (strongly simplified) rule is: the greater the numbers in the matrix, the greater the value of its norm. There are many norms that have a dedicated name. The most famous is the Euclidean, but also the p-q-norm is very widespread. In fact, if you set p = 2 and q= 2, you get the Euclidean. But as you can easily see in this situation, we should full employ MMD. First, it's conceptually always the same thing you do: you want to calculate the norm (one value) based on the matrix cell values. And no matter if you write $matrix.norm('column-sum') or $matrix.norm(p:<4>,q:<3>) or $matrix.norm(1) (p-norm with p = q = 1 aka L1 aka sum of all absolute cell values), it never gets complicated (speaking about the complexity of the signatures).

submatrix

It's a little more tricky is our third case, where we have three multi-methods listening to the name submatrix. Associated with that term is a clear mathematical definition, so surely we have to provide that. So when you call $matrix.submatrix(1,2) the second row and third column will be removed and you get a matrix with the content that is left. To combine that with something that has less academic credibility is the first question mark you may put on my design here. But it felt right to me and I can back it up with reason.

The second method takes a more visual approach. If you write down a matrix as a table on a sheet of paper and draw in it an rectangle you get a submatrix of that second kind. The third variant is a Swiss army knife method to get any selection, combination, and ordering of rows and columns you imagine.

You can separate all three signatures easily, since the first takes two Int, the second two Ranges of Int, and the third two lists of Int. So at least the criteria of simplicity is still upheld. And in any case you get a subset of the original matrix, so also the functionality is similar enough to fit a common umbrella term. The third multi-method might be better called rehash or something of that nature. But force of expectation works in more than one way. Surely the trained mind wants to see under the name just what it already knows. But when searching for the latter functionality, it might at first look close something that it knows to be similar. Also, the fully unfamiliar name of a method rehash might trigger unwanted confusion. We are here in Perl country, where the word hash calls for strong associations into an entirely different direction.

map

For instance, map is another very important keyword in Perl that provokes a clear set of expectations. Math Matrix provides something of a map that maps over all cells and on every call of the provided block, the only argument of that anonymous block will be the cell value. The module also has an iterator that additional provides the indexes of the current cell. Here MMD would be fully misleading. Quite to contrary the name of the second method need flashing warning lights, so I called it map-with-index .


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK