## Feature #5310

### Integral objects

Status: | Assigned | ||
---|---|---|---|

Priority: | Normal | ||

Assignee: | Kenta Murata | ||

Category: | - | ||

Target version: | next minor |

**Description**

I believe it is ambiguous what object can behave as an integral number.

I don't think the current use of Object#to_int isn't appropriate for this purpose.

The most understandable example is Float#to_int.

It should raise error for all float values because they always have uncertainty,

but it doesn't and returns an integral part of it.

I propose to change the use of Object#to_int for the next release of Ruby.

I recommend the following specification changes:

(1) Remove to*int method from Float and BigDecimal.
(2) Rational#to*int returns an Integer only if its denominator is 1. Otherwise, it raises an appropriate error.

(3) Complex#to

*int returns the result of to*int of its real part only if its imaginary part is exactly zero (0.0 isn't exactly zero).

If anyone have another idea, please give me your comment.

**Related issues**

### History

#### #1 Updated by Kenta Murata over 2 years ago

**Target version**changed from*2.0.0*to*Next Major*

#### #2 Updated by Brian Shirai over 2 years ago

On Mon, Sep 12, 2011 at 6:15 PM, Kenta Murata muraken@gmail.com wrote:

Issue #5310 has been reported by Kenta Murata.

Feature #5310: Integral objects

http://redmine.ruby-lang.org/issues/5310Author: Kenta Murata

Status: Open

Priority: Normal

Assignee:

Category: core

Target version: 1.9.xI believe it is ambiguous what object can behave as an integral number.

I don't think the current use of Object#to_int isn't appropriate for this purpose.The most understandable example is Float#to_int.

It should raise error for all float values because they always have uncertainty,

but it doesn't and returns an integral part of it.I propose to change the use of Object#to_int for the next release of Ruby.

I recommend the following specification changes:(1) Remove to

int method from Float and BigDecimal.int returns an Integer only if its denominator is 1. Otherwise, it raises an appropriate error.

(2) Rational#to

(3) Complex#toint returns the result of toint of its real part only if its imaginary part is exactly zero (0.0 isn't exactly zero).If anyone have another idea, please give me your comment.

I strongly disagree with this proposal.

Any object should be allowed to participate in integral operations

based on the object's implementing #to*int. When object A requests
that object B represent itself as an integral value, it is up to
object B to do so, or not do so. The only thing that object A should
require is that the value returned from #to*int be an integral value.

The object A should have no say is how the object B represents itself.

To do so is to 1) severely break encapsulation; 2) impose ad hoc

type/class requirements that break ducktyping; 3) create more brittle,

non-OO code.

Should it not be clear, allow me to reiterate that I am adamantly

opposed to this change.

Cheers,

Brian

#### #3 Updated by Kenta Murata over 2 years ago

I believe you are misreading of the topic.

On Tuesday, September 13, 2011 at 11:03 , brian ford wrote:

Any object should be allowed to participate in integral operations

based on the object's implementing #to_int.

My proposal doesn't disturb that, and I don't want to interfere that.

I want to allow anyone to create original "integral" numbers which can behave alike Fixnum and Bignum.

Unfortunately, to_int is currently used for converting to an Integer from a non-integral, inexact number like a Float.

--

Kenta Murata

Sent with Sparrow (http://www.sparrowmailapp.com)

#### #4 Updated by Brian Shirai over 2 years ago

Hi,

On Mon, Sep 12, 2011 at 7:30 PM, Kenta Murata muraken@gmail.com wrote:

Â I believe you are misreading of the topic.

There is some inconsistency between your proposal and what has been implemented:

# integral.rb

class Numberish

def initialize(value)

@value

#### #5 Updated by Kenta Murata over 2 years ago

Hi,

On Wednesday, September 14, 2011 at 06:23 , brian ford wrote:

There is some inconsistency between your proposal and what has been implemented:

We can change the implementation according to the proposal if accepted.

A Float value is a machine approximation of a mathematical real

number. A BigDecimal is an exact representation of a real number. The

mathematical real numbers embed the integers.

You are not right.

A BigDecimal is a floating-point number same as a Float except for internal representation.

So, A BigDecimal is also approximation of a real number,

in other words, a BigDecimal has error as well as a Float does.

It is right understanding because I am the master of bigdecimal.

It is untrue that Float numbers cannot be consistently represented as

integral values. It is merely up to the language to define them as

such. Ruby already takes liberties with defining mathematical

operations (see http://redmine.ruby-lang.org/issues/3289).

I know. I suggest to change for number system.

To remove #to_int from Float and BigDecimal and partially from

Rational and Complex introduces typing concepts where none are needed,

breaks consistent polymorphism, and breaks compatibility with 1.8 and

prior 1.9.

Yes, my proposal introduces incompatibility, so I propose this for 2.0.

--

Kenta Murata

Sent with Sparrow (http://www.sparrowmailapp.com)

#### #6 Updated by Brian Shirai over 2 years ago

On Tue, Sep 13, 2011 at 5:18 PM, Kenta Murata muraken@gmail.com wrote:

Hi,

On Wednesday, September 14, 2011 at 06:23 , brian ford wrote:

There is some inconsistency between your proposal and what has been implemented:

We can change the implementation according to the proposal if accepted.

But you have already changed the implementation and your change is

inconsistent with what you are claiming in your response. If you are

not intending to exclude other objects implementing #to_int, then why

did you implement it that way? That's confusing.

A Float value is a machine approximation of a mathematical real

number. A BigDecimal is an exact representation of a real number. The

mathematical real numbers embed the integers.You are not right.

A BigDecimal is a floating-point number same as a Float except for internal representation.

So, A BigDecimal is also approximation of a real number,

in other words, a BigDecimal has error as well as a Float does.

It is right understanding because I am the master of bigdecimal.

BigDecimal is an arbitrary precision floating-point library. There are

other arbitrary precision floating-point libraries. The

characteristics of BigDecimal really have nothing to do with this

discussion anyway.

A real-number approximation can be easily represented as an integral

value any number of ways. It can be consistently represented using any

one of those any number of ways. A real-number approximation is no

less and no more an integral value than the Numberish object in my

example. There is no reason to introduce this arbitrary distinction in

Ruby. I could just as easily define Numberish as:

class Numberish

def initialize(value)

@value = value

end

def to*int
@value.to*i # or

*anything*else, even just 1

end

end

n = Numberish 4.2

Why is this change needed? Please don't reiterate this argument about

imprecise floating-point values. What problems does this change fix?

Thanks,

Brian

It is untrue that Float numbers cannot be consistently represented as

integral values. It is merely up to the language to define them as

such. Ruby already takes liberties with defining mathematical

operations (see http://redmine.ruby-lang.org/issues/3289).I know. I suggest to change for number system.

To remove #to_int from Float and BigDecimal and partially from

Rational and Complex introduces typing concepts where none are needed,

breaks consistent polymorphism, and breaks compatibility with 1.8 and

prior 1.9.Yes, my proposal introduces incompatibility, so I propose this for 2.0.

Kenta Murata

Sent with Sparrow (http://www.sparrowmailapp.com)

#### #7 Updated by Yukihiro Matsumoto over 2 years ago

Hi,

I strongly disagree to use to_int (currently working for integer

conversion) as integral conversion. Note that I don't disagree (yet)

to introduce concept of integrals to Ruby in the future. But

recycling name is not ideal.

matz.

#### #8 Updated by Brian Shirai over 2 years ago

Hi Matz,

On Wed, Sep 14, 2011 at 1:31 AM, Yukihiro Matsumoto matz@ruby-lang.org wrote:

Hi,

I strongly disagree to use to_int (currently working for integer

conversion) as integral conversion. Â Note that I don't disagree (yet)

to introduce concept of integrals to Ruby in the future. Â But

recycling name is not ideal.

Could you explain what you mean by integer conversion versus integral

conversion?

I'm still completely lost on what problem this proposal is intending to fix.

Thanks,

Brian

#### #9 Updated by Alexey Muranov over 2 years ago

Hello, i also do not understand very well the issue.

Am i right that it has to do with the difference between #to*int and #to*i methods, similar to the difference between #to*ary and #to*a methods?

Do i understand correctly that #to*a is a conversion to an Array of anything that can be converted, and #to*ary is an "easy conversion to Array" reserved for objects that are essentially arrays, and similarly #to*int is reserved for objects that are essentially integers?
In this case i agree with the proposal: to convert a Float to Integer, only #to*i should be allowed, because Floats store approximate values, and Integers store exact values, so Floats are not "essentially" Integers.

I think it would be nice if the rule for using #to*ary and #to*int was the following: conversion back and forth (if a corresponding inverse conversion exists) should always return the same value.

Also the conversion should whenever possible commute with some operations: sum, concatenation, etc.

Currently i get: (10000000000000000.to*f+1.to*f).to*int #=> 10000000000000000
(but of course #to*f is not an "easy conversion", so this in not wrong).

Probably this is impossible to observe exactly, but maybe to some extent?

This is just an idea.

Alexey.

#### #10 Updated by Alexey Muranov over 2 years ago

@Brian, if i understood correctly, the proposal is intending to fix the problem that Float and BigDecimal should not respond to #to*int, and in some other cases #to*int should raise an Error on some inputs.

Sorry, this sounds like a tautology :).

Alexey.

#### #11 Updated by Yui NARUSE over 2 years ago

**Project**changed from*ruby-trunk*to*CommonRuby***Category**deleted ()*core***Target version**deleted ()*Next Major*

#### #12 Updated by Yui NARUSE over 2 years ago

**Project**changed from*CommonRuby*to*ruby-trunk*

#### #13 Updated by Yusuke Endoh about 2 years ago

**Status**changed from*Open*to*Assigned***Assignee**set to*Kenta Murata*

#### #14 Updated by Yusuke Endoh over 1 year ago

**Target version**set to*next minor*