Array Sutraction

Ok, this has been discussed at length previously,
and it appears that the implementation has
changed.

Consider:

in 1.6.7

[1,1,2,2,3,3] - [3] => [1,2]

in 1.8.0

[1,1,2,2,3,3] - [3] => [1,1,2,2]

I think this last algorithm was chosen for
performance reasons. The problem is, the #- operation
is neither explainable by the Array being considered a bag
or a set. Plus, since this operation seems to change
with revisions, it is hard to rely upon.

The one explanation that is consistent between the two
is if #uniq is applied to both sides of the equation.
Tbat is,

([1,1,2,2,3,3].uniq - [3].uniq).uniq #=> [1,2].uniq => [1,2]
([1,1,2,2,3,3].uniq - [3].uniq).uniq #=> [1,1,2,2].uniq => [1,2]

So it would seem that Array#- is incomplete and the user
is required to apply #uniq to the result.

All I can say is, Why?

···


Jim Freeze

Mandrell: "You know what I think?"
Doctor: “Ah, ah that’s a catch question. With a brain your size you
don’t think, right?”
– Dr. Who

Hi,

···

In message “Array Sutraction” on 03/04/08, Jim Freeze jim@freeze.org writes:

So it would seem that Array#- is incomplete and the user
is required to apply #uniq to the result.

If you want uniq elements in the result. 1.8.0 Array#- removes
elements in the right operand from the receiver (right operand).

						matz.

Jim Freeze wrote:

Ok, this has been discussed at length previously,
and it appears that the implementation has
changed.

Consider:

in 1.6.7

[1,1,2,2,3,3] - [3] => [1,2]

in 1.8.0

[1,1,2,2,3,3] - [3] => [1,1,2,2]

I think this last algorithm was chosen for
performance reasons. The problem is, the #- operation
is neither explainable by the Array being considered a bag
or a set. Plus, since this operation seems to change
with revisions, it is hard to rely upon.

FWIW, 1.8 has a Set class if you want true set behavior:

require “set”
set_a = Set.new([1,1,2,2,3,3])
p set_a → #<Set: {1, 2, 3}>

set_b = set_a -[3]
p set_b → #<Set: {1, 2}>

Regards,

Dan

···


a = [74, 117, 115, 116, 32, 65, 110, 111, 116, 104, 101, 114, 32, 82]
a.push(117,98, 121, 32, 72, 97, 99, 107, 101, 114)
puts a.pack(“C*”)

I’m sorry Matz, I don’t understand.

I don’t have a horse in either the set or bag race.
It’s just the current implementation is very confusing.

If I have a = [1,1,2,2,2] and I subtract [2], then
I should get [1,1,2,2] if a is considered a bag.
If a is considered a set, then it must first be
temporarily converted to a set [1,2] and then
the subtraction is performed yielding [1].

However, 1.8.0 returns [1,1].

ruby -ve ‘p [1,1,2,2,2]-[2]’
ruby 1.8.0 (2003-03-10) [i386-freebsd4.6]
[1, 1]

···

On Tuesday, 8 April 2003 at 13:19:32 +0900, Yukihiro Matsumoto wrote:

Hi,

In message “Array Sutraction” > on 03/04/08, Jim Freeze jim@freeze.org writes:

So it would seem that Array#- is incomplete and the user
is required to apply #uniq to the result.

If you want uniq elements in the result. 1.8.0 Array#- removes
elements in the right operand from the receiver (right operand).

  					matz.


Jim Freeze

There’s no real need to do housework – after four years it doesn’t get
any worse.

Ahh, thanks Dan. I didn’t know this.

···

On Tuesday, 8 April 2003 at 22:54:25 +0900, Daniel Berger wrote:

Jim Freeze wrote:

FWIW, 1.8 has a Set class if you want true set behavior:

require “set”
set_a = Set.new([1,1,2,2,3,3])
p set_a → #<Set: {1, 2, 3}>

set_b = set_a -[3]
p set_b → #<Set: {1, 2}>

Regards,

Dan


Jim Freeze

It is now 10 p.m. Do you know where Henry Kissinger is?
– Elizabeth Carpenter

Hi,

I don’t have a horse in either the set or bag race.
It’s just the current implementation is very confusing.

I defined array subtraction as

def -(other)
self.delete_if{|x| other.include?(x)}
end

which is very clear for me (note that real Array#- uses Hash inside,
so that its comparison is actually done by eql? not ==).

						matz.
···

In message “Re: Array Sutraction” on 03/04/08, Jim Freeze jim@freeze.org writes:

“Jim Freeze” jim@freeze.org schrieb im Newsbeitrag
news:20030408003523.A678@freeze.org

I’m sorry Matz, I don’t understand.

I don’t have a horse in either the set or bag race.
It’s just the current implementation is very confusing.

If I have a = [1,1,2,2,2] and I subtract [2], then
I should get [1,1,2,2] if a is considered a bag.
If a is considered a set, then it must first be
temporarily converted to a set [1,2] and then
the subtraction is performed yielding [1].

I don’t find this confusing. In fact I find the implicit application of
uniq (older version) more confusing because it is somewhat surprising - at
least to me. In that case substraction indeed combines two operations.

I’d view the substraction “a-b” as “remove all elements in b from a”,
which would reasonable lead to all 2’s removed from [1,1,2,2,2] yielding
[1,1].

However, 1.8.0 returns [1,1].

ruby -ve ‘p [1,1,2,2,2]-[2]’
ruby 1.8.0 (2003-03-10) [i386-freebsd4.6]
[1, 1]

That’s what I’d expect.

robert

I don’t find this confusing. In fact I find the implicit
application of
uniq (older version) more confusing because it is somewhat
surprising - at
least to me. In that case substraction indeed combines two
operations.

I’d view the substraction “a-b” as “remove all elements in b from
a”,
which would reasonable lead to all 2’s removed from [1,1,2,2,2]
yielding
[1,1].

So [1, 1, 2, 2] - [2] should yield the same as [1, 1, 2, 2] - [2, 2]?
That seems odd to me.

···

Do you Yahoo!?
Yahoo! Tax Center - File online, calculators, forms, and more

I agree. But the presence of a Set in 1.8
maes me feel better. After all, an Array
is not in itself a bag or a set, so we can
define its minus operator more or less
arbitrarily.

Hal

···

----- Original Message -----
From: “Michael Campbell” michael_s_campbell@yahoo.com
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Tuesday, April 08, 2003 8:59 AM
Subject: Re: Array Sutraction

I’d view the substraction “a-b” as “remove all elements in b from
a”,
which would reasonable lead to all 2’s removed from [1,1,2,2,2]
yielding
[1,1].

So [1, 1, 2, 2] - [2] should yield the same as [1, 1, 2, 2] - [2, 2]?
That seems odd to me.

Yes. It’s not really subtraction as implied by the ‘-’ minus operator.
Maybe it should be renamed to #remove_all_from. :slight_smile:

···

On Tuesday, 8 April 2003 at 22:59:50 +0900, Michael Campbell wrote:

I don’t find this confusing. In fact I find the implicit
application of
uniq (older version) more confusing because it is somewhat
surprising - at
least to me. In that case substraction indeed combines two
operations.

I’d view the substraction “a-b” as “remove all elements in b from
a”,
which would reasonable lead to all 2’s removed from [1,1,2,2,2]
yielding
[1,1].

So [1, 1, 2, 2] - [2] should yield the same as [1, 1, 2, 2] - [2, 2]?
That seems odd to me.


Jim Freeze

F: When into a room I plunge, I
Sometimes find some VIOLET FUNGI.
Then I linger, darkly brooding
On the poison they’re exuding.
– The Roguelet’s ABC

So [1, 1, 2, 2] - [2] should yield the same as [1, 1, 2, 2] - [2,
2]?
That seems odd to me.

I agree. But the presence of a Set in 1.8
maes me feel better. After all, an Array
is not in itself a bag or a set, so we can
define its minus operator more or less
arbitrarily.

I’ll defer to others on the behavior (though I might still disagree),
but I’d at least like to not have it change quite so drastically in a
dot release. (Is 1.6 → 1.8 considered a dot release?)

···

Do you Yahoo!?
Yahoo! Tax Center - File online, calculators, forms, and more

From: “Michael Campbell” michael_s_campbell@yahoo.com
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Tuesday, April 08, 2003 8:59 AM
Subject: Re: Array Sutraction

I’d view the substraction “a-b” as “remove all elements in b from
a”,
which would reasonable lead to all 2’s removed from [1,1,2,2,2]
yielding
[1,1].

So [1, 1, 2, 2] - [2] should yield the same as [1, 1, 2, 2] - [2, 2]?
That seems odd to me.

I agree. But the presence of a Set in 1.8
maes me feel better. After all, an Array
is not in itself a bag or a set, so we can

Hmm, I was not aware that an Array was not a bag.
Can you give an example Hal.

define its minus operator more or less
arbitrarily.
–^^^^^^^^^^^
You found the confusion. :slight_smile:

···

On Tuesday, 8 April 2003 at 23:14:43 +0900, Hal E. Fulton wrote:

----- Original Message -----


Jim Freeze

Corrupt, adj.:
In politics, holding an office of trust or profit.

I think it’s more confusing when dealing with numbers than with
Objects.

i = Object.new # => #Object:0x277c230
j = Object.new # => #Object:0x276fdf8
k = Object.new # => #Object:0x2768898
a = [i, j, k, i, i]

a - [i] # => [j, k]
[i].each { |e| a.delete(e) }
# => [j, k]

You’re removing a specific Object from an array. At least, IMO.

-austin
– Austin Ziegler, austin@halostatue.ca on 2003.04.08 at 11:48

···

On Tue, 8 Apr 2003 23:33:17 +0900, Jim Freeze wrote:

On Tuesday, 8 April 2003 at 22:59:50 +0900, Michael Campbell wrote:

I don’t find this confusing. In fact I find the implicit
application of uniq (older version) more confusing because it is
somewhat surprising - at least to me. In that case substraction
indeed combines two operations.

I’d view the substraction “a-b” as “remove all elements in b
from a”, which would reasonable lead to all 2’s removed from
[1,1,2,2,2] yielding [1,1].
So [1, 1, 2, 2] - [2] should yield the same as
[1, 1, 2, 2] - [2, 2]?
That seems odd to me.
Yes. It’s not really subtraction as implied by the ‘-’ minus
operator. Maybe it should be renamed to #remove_all_from. :slight_smile:

I don’t find this confusing. In fact I find the implicit
application of
uniq (older version) more confusing because it is somewhat
surprising - at
least to me. In that case substraction indeed combines two
operations.

I’d view the substraction “a-b” as “remove all elements in b from
a”,
which would reasonable lead to all 2’s removed from [1,1,2,2,2]
yielding
[1,1].

So [1, 1, 2, 2] - [2] should yield the same as [1, 1, 2, 2] - [2, 2]?
That seems odd to me.

Yes. It’s not really subtraction as implied by the ‘-’ minus operator.
Maybe it should be renamed to #remove_all_from. :slight_smile:

Hmm… there might still be some confusion there. I might expect that to
remove all elements from the array. Perhaps it should be called
#remove_all_elements_equivalent_to **
:slight_smile:

Marty

** This was funny when I thought of it, but Austin, Texas has more than its
share of allergens in the air right now, so my head feels rather like a
recently kicked (US)football.

···

----- Original Message -----
From: “Jim Freeze” jim@freeze.org

On Tuesday, 8 April 2003 at 22:59:50 +0900, Michael Campbell wrote:


Jim Freeze

F: When into a room I plunge, I
Sometimes find some VIOLET FUNGI.
Then I linger, darkly brooding
On the poison they’re exuding.
– The Roguelet’s ABC

That’s the most disturbing part to me.

Is there at least a warning or something?

Of course, anyone who encounters a bug can
add his own Array#- which does a uniq after
(or before) calling the “real” one.

Hal

···

----- Original Message -----
From: “Michael Campbell” michael_s_campbell@yahoo.com
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Tuesday, April 08, 2003 9:17 AM
Subject: Re: Array Sutraction

So [1, 1, 2, 2] - [2] should yield the same as [1, 1, 2, 2] - [2,
2]?
That seems odd to me.

I agree. But the presence of a Set in 1.8
maes me feel better. After all, an Array
is not in itself a bag or a set, so we can
define its minus operator more or less
arbitrarily.

I’ll defer to others on the behavior (though I might still disagree),
but I’d at least like to not have it change quite so drastically in a
dot release. (Is 1.6 → 1.8 considered a dot release?)

Hmmmmmmm.

x = [“one”, “one”, “two”, “two”, “two”]
y = [“two”]

What do you want x-y to be here?

Hal

···

----- Original Message -----
From: “Austin Ziegler” austin@halostatue.ca
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Tuesday, April 08, 2003 10:52 AM
Subject: Re: Array Sutraction

That seems odd to me.
Yes. It’s not really subtraction as implied by the ‘-’ minus
operator. Maybe it should be renamed to #remove_all_from. :slight_smile:

I think it’s more confusing when dealing with numbers than with
Objects.

i = Object.new # => #Object:0x277c230
j = Object.new # => #Object:0x276fdf8
k = Object.new # => #Object:0x2768898
a = [i, j, k, i, i]

a - [i] # => [j, k]
[i].each { |e| a.delete(e) }
# => [j, k]

You’re removing a specific Object from an array. At least, IMO.

Jim Freeze wrote:

Hmm, I was not aware that an Array was not a bag.

[1, 2] != [2, 1]

But if they were bags (or sets), wouldn’t they be == ?

I believe he means that
[1,1,2,2] - [2] => [1,1] instead of [1,1,2]

···

On Tue, Apr 08, 2003 at 11:35:02PM +0900, Jim Freeze wrote:

I’d view the substraction “a-b” as “remove all elements in b from
a”,
which would reasonable lead to all 2’s removed from [1,1,2,2,2]
yielding
[1,1].

So [1, 1, 2, 2] - [2] should yield the same as [1, 1, 2, 2] - [2, 2]?
That seems odd to me.

I agree. But the presence of a Set in 1.8
maes me feel better. After all, an Array
is not in itself a bag or a set, so we can

Hmm, I was not aware that an Array was not a bag.
Can you give an example Hal.


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Remember: While root can do most everything, there are certain
privileges that only a partner can grant.
– Telsa Gwynne

I want [“one”, “one”, “two”, “two”, “two”], because they’re not the
same objects.

But maybe that’s me. I’d use #delete_if if I wanted something other
than #delete-like behaviour. At least IMO.

-austin
– Austin Ziegler, austin@halostatue.ca on 2003.04.08 at 12:26:54

···

On Wed, 9 Apr 2003 01:03:24 +0900, Hal E. Fulton wrote:

That seems odd to me.
Yes. It’s not really subtraction as implied by the ‘-’ minus
operator. Maybe it should be renamed to #remove_all_from. :slight_smile:
I think it’s more confusing when dealing with numbers than with
Objects.

i = Object.new # => #Object:0x277c230
j = Object.new # => #Object:0x276fdf8
k = Object.new # => #Object:0x2768898
a = [i, j, k, i, i]

a - [i] # => [j, k]
[i].each { |e| a.delete(e) }
# => [j, k]

You’re removing a specific Object from an array. At least, IMO.

Hmmmmmmm.

x = [“one”, “one”, “two”, “two”, “two”]
y = [“two”]

What do you want x-y to be here?

“Hal E. Fulton” hal9000@hypermetrics.com schrieb im Newsbeitrag
news:08cf01c2fde8$fde0bfc0$0300a8c0@austin.rr.com

Hmmmmmmm.

x = [“one”, “one”, “two”, “two”, “two”]
y = [“two”]

What do you want x-y to be here?

I’d expect [“one”, “one”] as a result.

robert