[RCR] Floating point division operator /. (or fdiv method)

  • Thread starter Michael Neumann
  • Start date
M

Michael Neumann

Hi,

I know that introducing new syntax into Ruby is probably far from being
accepted by matz....

Every now and then I accidentially pass an integer to a method and am
surprised than I get a wrong result. The reason is that the method
expected floats as arguments and not integers. These kind of bugs are
very hard to find, IMHO.

Imagine the following method:

def meth(a, b)
a / b
end

It works if a, b or both are floats, but not if both are integers.

Instead you have to write:

a.to_f / b

or

a / b.to_f

or

1.0 * a / b

...

My proposal is to add a /. operator, that treats both arguments as
floats, so that

1 /. 2 # => 0.5

Or alternatively:

class Float
alias fdiv /
end

class Integer
def fdiv(divisor)
self.to_f / divisor
end
end

a.fdiv(b)

Any comments?

IMHO, even better would be if / would always mean floating point
division and an extra // operator would mean integer division, but it's
to late to change now (even for Ruby 2.0) :)

Regards,

Michael
 
S

Simon Strandgaard

Michael Neumann said:
My proposal is to add a /. operator, that treats both arguments as
floats, so that

1 /. 2 # => 0.5

Hmm. that could be useful.. though I rarely uses floats.

Watchout slashdot not suis you for sealing their name :)
 
M

Michael Neumann

Hmm. that could be useful.. though I rarely uses floats.

Watchout slashdot not suis you for sealing their name :)

No the name actually comes from Ocaml's /. operator :)
 
P

Paul Brannan

Watchout slashdot not suis you for sealing their name :)

Perhaps the operator should occasionally (or often) return return bad
results or misinformation, in the spirit of slashdot editing practices.
:)

Paul
 
G

gabriele renzi

Hi,

I know that introducing new syntax into Ruby is probably far from being
accepted by matz....

Every now and then I accidentially pass an integer to a method and am
surprised than I get a wrong result. The reason is that the method
expected floats as arguments and not integers. These kind of bugs are
very hard to find, IMHO.

Maybe you could use the 'mathn' module?
irb(main):001:0> require 'mathn'
=> true
irb(main):002:0> 1/1
=> 1
irb(main):003:0> 1/2
=> 1/2
irb(main):004:0> 3/2
=> 3/2
irb(main):005:0> 1+ (1/2)
=> 3/2
irb(main):006:0> 1.0+ (1/2)
=> 1.5
 
D

David A. Black

Hi --

Hi,

I know that introducing new syntax into Ruby is probably far from being
accepted by matz....

Every now and then I accidentially pass an integer to a method and am
surprised than I get a wrong result. The reason is that the method
expected floats as arguments and not integers. These kind of bugs are
very hard to find, IMHO.

Imagine the following method:

def meth(a, b)
a / b
end

It works if a, b or both are floats, but not if both are integers.

Instead you have to write:

a.to_f / b

or

a / b.to_f

or

1.0 * a / b

...

My proposal is to add a /. operator, that treats both arguments as
floats, so that

1 /. 2 # => 0.5

But you've still got a "have to write" case -- meaning, when you write
#meth, above, you still can't just write "a / b". So if the problem
is that you forget to write "a.to_f" instead of "a", you're still in
danger of forgetting to write "/." instead of "/".
Or alternatively:

class Float
alias fdiv /
end

class Integer
def fdiv(divisor)
self.to_f / divisor
end
end

a.fdiv(b)

Any comments?

I like fdiv better than adding a ./ operator.


David
 
R

Robert Klemme

David has said it all - here are some additional remarks.

Michael Neumann said:
Hi,

I know that introducing new syntax into Ruby is probably far from being
accepted by matz....

Every now and then I accidentially pass an integer to a method and am
surprised than I get a wrong result. The reason is that the method
expected floats as arguments and not integers. These kind of bugs are
very hard to find, IMHO.

Imagine the following method:

def meth(a, b)
a / b
end

It works if a, b or both are floats, but not if both are integers.

Instead you have to write:

a.to_f / b

or

a / b.to_f

or

1.0 * a / b

..

You might better use Kernel#Float because of this:
TypeError: cannot convert nil into Float
from (irb):8:in `Float'
from (irb):8=> 0.0
My proposal is to add a /. operator, that treats both arguments as
floats, so that

1 /. 2 # => 0.5

Or alternatively:

class Float
alias fdiv /
end

class Integer
def fdiv(divisor)
self.to_f / divisor
end
end

a.fdiv(b)

Any comments?

IMHO, even better would be if / would always mean floating point
division and an extra // operator would mean integer division, but it's
to late to change now (even for Ruby 2.0) :)

I strongly oppose that one: Operators are overloaded and if I have two
int's I want integer division, if I have to floats I want float division.
And I don't want that changed, because often code is written with integer
divisions in mind. All sorts of indexing calculations depend on int math.

Kind regards

robert
 
M

Martin DeMello

Paul Brannan said:
Perhaps the operator should occasionally (or often) return return bad
results or misinformation, in the spirit of slashdot editing practices.
:)

And the complementary mod operator would only go to 5 :)

martin
 
M

Michael Neumann

Hi --



But you've still got a "have to write" case -- meaning, when you write
#meth, above, you still can't just write "a / b". So if the problem
is that you forget to write "a.to_f" instead of "a", you're still in
danger of forgetting to write "/." instead of "/".

Sure, but when at the time of writing #meth, you think parameters a and
b will always be floats (and of course you don't document it, because
it's a quick hack :), you'll get in trouble later (e.g. meth(1,2) vs.
meth(1.0, 2.0)). So you want use fdiv, as you expect the division to be
a floating point division (and for me that's the usual case).

Regards,

Michael
 
D

David A. Black

Hi --

Sure, but when at the time of writing #meth, you think parameters a and
b will always be floats (and of course you don't document it, because
it's a quick hack :), you'll get in trouble later (e.g. meth(1,2) vs.
meth(1.0, 2.0)). So you want use fdiv, as you expect the division to be
a floating point division (and for me that's the usual case).

OK, but what I mean is: given the same problem, you can also solve it
with to_f, and it should be no more or less difficult to remember than
remembering to use fdiv. (Assuming I'm following your argument
correctly.) I'm just making the conservative argument with regard to
change.


David
 
B

Bret Jolly

Michael Neumann said:
IMHO, even better would be if / would always mean floating point
division and an extra // operator would mean integer division, but it's
to late to change now (even for Ruby 2.0) :)

We already have .div for integer division. (13.div(7) == 2)
/ has an established meaning in the mathn library: 13/7 is the
rational number 13/7. Since the standard libraries give wrong
answers when mathn is not required (and no one seems to have the
slightest interest in fixing them), the mathn meaning must be
the standard meaning. NEVER use / for integer division:
use .div instead.

I don't like the Ocamlish /. . It's fine for Ocaml, a strongly
and statically typed language, but it strikes me as alien to the
spirit of Ruby. I'd rather just use .to_f (as in 13/(7.to_f)) to
force floating point.

Regards, Bret
 
J

Jim Weirich

Robert said:
David has said it all - here are some additional remarks.



I strongly oppose that one: Operators are overloaded and if I have two
int's I want integer division, if I have to floats I want float division.
And I don't want that changed, because often code is written with integer
divisions in mind. All sorts of indexing calculations depend on int math.

Then your code will break whenever it is used in a program that requires
"mathn". You should always use div if you want integer division.

The truth is that Ruby's / operator is broken. Any time a programmer
uses a / operation, they intend the operation to be either a float
divide or an int divide, not something that polymorphically switches its
semantics based on the operands. Anytime you use / to mean int
division, it will break if given floats (or someone required mathn).
Anytime you use / to mean float division, it will break if given 2 ints.

In a perfect world where backward compatibility wasn't an issue, I would
make / always mean float division and // always mean int division.

If I were to worry about backward compatibility, leave / as is (and
never use it!). And then provide specific operators for int and float
division. /. and // aren't too bad. div and fdiv (as methods, not
operators) are not bad either.

I recall in earlier threads on this topic that Matz was uncomfortable
defining division of integers (exact values) so that it returns an
inexact result. I think he was implying that a future ruby might return
rationals for integer division. I think that makes sense.
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: [RCR] Floating point division operator /. (or fdiv method)"

|If I were to worry about backward compatibility, leave / as is (and
|never use it!). And then provide specific operators for int and float
|division. /. and // aren't too bad. div and fdiv (as methods, not
|operators) are not bad either.

Numeric#div does integer division and Numeric#quo does float (or
rational if available) division _now_.

matz.
 
P

Paul Brannan

Then your code will break whenever it is used in a program that requires
"mathn". You should always use div if you want integer division.
The truth is that Ruby's / operator is broken.

I strongly disagree. It is mathn that is broken, not the / operator.

I use / all the time to indicate integer division (provided I'm working
with integers). My code will not work with mathn and I have no
intention of going out of my way to uglify my code just to make it
compatible with a broken library.

I've said it before and I will say it again. Code that changes builtin
classes without a really good reason (YAML is one such example) is
broken. See [ruby-talk:81923] for what I've written in the past on this
subject.

If we get selector namespaces in ruby 2.0, then mathn can be rewritten
such that users can get floating-point division with / in their
namespace only. Until then I recommend not using mathn.

Paul
 
R

Robert Klemme

Paul Brannan said:
math.

Then your code will break whenever it is used in a program that requires
"mathn". You should always use div if you want integer division.
The truth is that Ruby's / operator is broken.

I strongly disagree. It is mathn that is broken, not the / operator.

I use / all the time to indicate integer division (provided I'm working
with integers). My code will not work with mathn and I have no
intention of going out of my way to uglify my code just to make it
compatible with a broken library.

I've said it before and I will say it again. Code that changes builtin
classes without a really good reason (YAML is one such example) is
broken. See [ruby-talk:81923] for what I've written in the past on this
subject.

That's especially true if an existing method's or standard operator's
behavior is changed.
If we get selector namespaces in ruby 2.0, then mathn can be rewritten
such that users can get floating-point division with / in their
namespace only. Until then I recommend not using mathn.

Thanks for expressing my feelings about this so well!

Regards

robert
 
S

Sam Roberts

I strongly disagree. It is mathn that is broken, not the / operator.

I agree, mathn's / operator is broken, not Ruby's!
I've said it before and I will say it again. Code that changes builtin
classes without a really good reason (YAML is one such example) is
broken. See [ruby-talk:81923] for what I've written in the past on this
subject.

If we get selector namespaces in ruby 2.0, then mathn can be rewritten
such that users can get floating-point division with / in their
namespace only. Until then I recommend not using mathn.

I think that the ability to extend the builtins is amazingly useful, but
I avoid using it in libraries because I can't do scope control.

Can somebody point me to a description, or ruby-talk thread, of how this
"selector" mechanism is going to work? Is it decided? I think its a
very, very interesting idea.

Cheers,
Sam
 
M

Martin DeMello

Yukihiro Matsumoto said:
Numeric#div does integer division and Numeric#quo does float (or
rational if available) division _now_.

Not a good choice of names, IMO, since it's not obvious which is which.
fdiv is clearer than quo.

martin
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: [RCR] Floating point division operator /. (or fdiv method)"

|> Numeric#div does integer division and Numeric#quo does float (or
|> rational if available) division _now_.
|
|Not a good choice of names, IMO, since it's not obvious which is which.
|fdiv is clearer than quo.

fdiv is not good either, since it may return rational.

matz.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top