## Feature #8232

### Rudiments of abstract algebra in Ruby

**Description**

I have recently been struggling with Matrix class to make it accept physical magnitudes for matrix multiplication, and at that opportunity (http://bugs.ruby-lang.org/issues/8223), I noticed that rings and fields in Ruby do not know their additive identity. Eg. there is no method Float#zero or Rational#zero... I therefore propose that:

- every ring has #additive_identity, alias #zero method defined.
- every ring has other methods defined, as required for rings in abstract algebra. An example (perhaps a stupid example) might be:

class << Integer

def additive_identity; 0 end

alias zero additive_identity

def add( other ); self + other end

def additive_inverse; -self end

def multiply( other ); self * other end

def multiplicative_identity; 1 end

end

- That every field in Ruby has, in addition to the above methods, a method #multiplicative_inverse defined, as in:

class << Float

def additive_identity; 0.0 end

alias zero additive_identity

def add( other ); self + other end

def additive_inverse; -self end

def multiply( other ); self * other end

def multiplicative_identity; 1.0 end

alias one multiplicative_identity

def multiplicative_inverse; 1.0 / self end

end

I am no pro mathematician, and abstract algebra first sounded to me like a kind of thing that should be treated in some specialized libraries for math nerds, but looking how Twitter pays people to write abstract algebra in Scala

https://github.com/scalaz/scalaz/blob/master/core/src/main/scala/scalaz/Monoid.scala

and reading posts like this one about it:

http://stackoverflow.com/questions/14790588/what-is-twitters-interest-in-abstract-algebra

, where especially noteworthy comment is that by Randall Schulz of box.com, fourth from the top.

If we actually require Ruby rings and fields to have the basic properties of rings and fields (just like Enumerable classes are required to have #each method), it would be possible to implement structured objects such as Matrices over them, and instead of intuitively using numeric literals such as 0 and 1, the matrix or another structured object would ask rings / fields, which their elements come from, what their #additive_identity (#zero), #multiplicative_identity (#one) is. And at the same time, I would like to express my wish that Matrix be made a standard part of Ruby, that does not need to be loaded by require.

#### Updated by steakknife (Barry Allard) over 7 years ago

MRI built-in numeric types are implemented in C, which means they are difficult to modify at runtime. Subclassing would be painfully messy to use.

https://gist.github.com/5332699

To potential implementer/s: consider tradeoffs for more modules dependencies (preferred) vs. DRY.

#### Updated by marcandre (Marc-Andre Lafortune) over 7 years ago

**Assignee**set to*matz (Yukihiro Matsumoto)*

boris_stitnicky (Boris Stitnicky) wrote:

... I noticed that rings and fields in Ruby do not know their additive identity. Eg. there is no method Float#zero or Rational#zero... I therefore propose that:

-1. I can't see how this would help most Rubyists.

The `add`

, `multiply`

and `additive_inverse`

are completely redundant with `+`

, `*`

and `@-`

methods. BTW, they are instance methods, not singleton methods.

Moreover, I anyone needs a generic `zero`

method, it takes a couple of lines to supplement the builtin classes. In any case, 0, even though it's a Fixnum, will act as a zero for all builtin Numeric classes, so will 1 for multiplication.

Finally, as I explained in #8223, I don't think that Matrix could use a generic `zero`

method.

And at the same time, I would like to express my wish that Matrix be made a standard part of Ruby, that does not need to be loaded by require.

You should open a different feature request if you like, but I'm -1 on this too, as I believe very very few Rubyists need Matrix. Compare that to `set`

... BTW, coding it in C would be a huge undertaking too.

steakknife (Barry Allard) wrote:

MRI built-in numeric types are implemented in C, which means they are difficult to modify at runtime.

I'm not sure exactly what you mean, but I'm pretty sure it's wrong. Numeric classes can be modified as easily as any other Ruby class.

#### Updated by Anonymous over 7 years ago

-1. I can't see how this would help most Rubyists.

I think that I have to come clean, that Hermes, not Apollo inspired me to raise this issue.

In some quarters, abstract algebra is considered cool. If we have #additive_idenity (alias

#zero) and #multiplicative_identity (alias #one) in all algebraic rings (such as Numerics),

nobody can point fingers (like Randall Schulz does in that SO comment, see the link in my

original post at the top) that Ruby people are "hobbyist proffesionals" who "reject formal

mathematical foundations" and "insist on a purely intuitive approach". Yes, Ruby is based

on abstract algebra, yes, we support as much as was pragmatic. The thing is, to sprinkle

just ever so little abstract algebra terminology (Rings, Fields, Monoids, #additive_inverse,

#multiplicative_inverse...) to give Ruby cute fake glasses :-)))

http://coderay.rubychan.de/images/ruby-chan-coderay-small.png?1302355251

A bit more seriously, it is already possible to ask Numeric#zero?, so why not have its

counterpart methods without question mark, such as Float.zero, Integer.zero

(and Float.one, Integer.one...)

Finally, as I explained in #8223, I don't think that Matrix could use a generic

`zero`

method.

I will try to subclass it into MatrixOverAlgebraicRing, that does use #zero and #one, I'll let you know.

... I would like ... that Matrix ... does not need to be loaded by require.

... I'm -1 on this too, as I believe very very few Rubyists need Matrix. Compare that to`set`

...

Very few Rubyists need Matrix? Really? So if I think that everyone needs matrices, and

that Ruby is my Octave++, I'm weird? I understand that in past, there was probably an

issue of whether Set should be enabled by default, and it was rejected. But Set is imitated

so well by Arrays! Am I weird again to think that matrices (and tensors) are more fundamental?

BTW, coding it in C would be a huge undertaking too.

And necessary. I'll start (re)learning C, I promise :-)

#### Updated by Anonymous over 7 years ago

steakknife (Barry Allard) wrote:

MRI built-in numeric types are implemented in C, which means they are difficult to modify at runtime. Subclassing would be painfully messy to use.

https://gist.github.com/5332699

To potential implementer/s: consider tradeoffs for more modules dependencies (preferred) vs. DRY.

Yes, that's it.