Project

General

Profile

Actions

Bug #3434

closed

Specs for coercion?

Added by marcandre (Marc-Andre Lafortune) almost 14 years ago. Updated over 6 years ago.

Status:
Closed
Target version:
[ruby-core:30755]

Description

=begin
What are the official specs of coercion for mathematical classes?

I will take Matrix as an example, but my questions are meant to be for the general case.

My understanding is that for a obj.coerce(obj_2) should return [compatible_2, compatible] such that compatible2.send(some_operation, compatible) returns (if possible) a meaningful result.

Can we assume anything more about coercion? I'm asking because I find in test_matrix (@m1 being a Matrix):

def test_scalar_mul
s1 = @m1.coerce(1).first
assert_equal(Matrix[[1]], (s1 * 1) * Matrix[[1]])
assert_equal(Vector[2], s1 * Vector[2])
assert_equal(Matrix[[2]], s1 * Matrix[[2]])
o = Object.new
def o.coerce(x)
[1, 1]
end
assert_equal(1, s1 * o)
end

  1. Should the first and last assert work? Are implementers of other mathematical classes mandated/encouraged to provide that level of compatibility? Are users of coerce encouraged (or guaranteed success) when doing any other operation than compatible2 * compatible or similar?

My feeling is that the only thing one should do with the results of coerce is to call an operation on the first element and pass the second element. Doing operations using only one of the two returned elements with another new object should yield undetermined results.

If this is the case, I feel the Matrix library would be best to assume that Scalar#* is called with a Matrix or Vector (remember that the Scalar is not meant to be used directly by anybody else than the Matrix lib), and these two assert would not work.

  1. The second assert is clearly implementation dependant. In the current implementation, both Vector and Matrix use Matrix::Scalar as a temporary class, but that could change.

  2. I am assuming that compatible doesn't have to be equal?, eql? or == to obj nor of the same class, and the same is true for compatible_2 vs obj_2, right? Thus the third assert isn't a spec guaranteed for all implementations.

  3. Finally, a somewhat trivial question: should obj.coerce(obj_2) succeed if obj and obj_2 are of the same class (and presumably return [obj_2, obj])? Clearly this is not very useful, but the specs should be made precise.

This is the case for Numeric and is explicit in the documentation but fails for Matrix:

 Matrix.I(2).coerce(Matrix.I(2))  # => TypeError: Matrix can't be coerced into Matrix

Coercion should always work for the trivial case of two objects of the same class, right?

Thanks.

Marc-André
=end

Actions #1

Updated by yugui (Yuki Sonoda) over 13 years ago

  • Target version changed from 1.9.2 to 2.0.0

=begin

=end

Actions #2

Updated by shyouhei (Shyouhei Urabe) over 13 years ago

  • Status changed from Open to Assigned

=begin

=end

Updated by trans (Thomas Sawyer) about 11 years ago

=begin
Regarding the coercion spec, I had need of coercion for Array the other day while implementing a set logic system. So I wondered if coercion can't be more general and not just isolated to Numerics. Is there a necessary reason coercion can't work in general for ((operators)) across ((all classes))?
=end

Updated by ko1 (Koichi Sasada) about 11 years ago

  • Description updated (diff)

I'm not sure about this ticket.
Who can discuss about it?

Updated by ko1 (Koichi Sasada) about 11 years ago

  • Category set to core
  • Target version changed from 2.0.0 to 2.6
Actions #6

Updated by naruse (Yui NARUSE) almost 11 years ago

  • Tracker changed from Misc to Bug

Updated by mame (Yusuke Endoh) over 6 years ago

  • Status changed from Assigned to Feedback

All of this are just my opinion, but obviously, coercion is a "best effort" feature. I believe there is no conclusive spec for coercion even in matz's heart. Until we encounter a concrete case that doesn't work well, we can't think what is a desirable behavior.

My feeling is that the only thing one should do with the results of coerce is to call an operation on the first element and pass the second element.

I agree with this. IMO, all but this (or sometimes, all including this) are not guaranteed.

If you have any concrete case that does not work well, it would be good to disclose it. (Marc-Andre, if your case is related to matrix.rb, you are now the maintainer, so you may fix it yourself :-)

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

  • Status changed from Feedback to Closed

Thanks for your reply.
I agree that we need to base on concrete examples, so I'll close this.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0