[RCR] Numeric#of

A

Ara.T.Howard

this got a generally favourable reception so:


RCR - Numeric#of - an accumlative version of Numeric#times

~ > cat of.rb
class Numeric
def of
ret = []
times{|i| ret << yield(i)}
ret
end
end

them = 3.of{ Array.new }
p them # => [[],[],[]]


-a
--
===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| URL :: http://www.ngdc.noaa.gov/stp/
| "640K ought to be enough for anybody." - Bill Gates, 1981
===============================================================================
 
Y

Yukihiro Matsumoto

Hi,

In message "[RCR] Numeric#of"

|this got a generally favourable reception so:
|
|RCR - Numeric#of - an accumlative version of Numeric#times

What if n is very large number?

Besides that Numeric#of is not very intuitive for me (non native
English speaker). It seems too vague for me. Is the name "of" really
OK for you guys?

matz.
 
A

Ara.T.Howard

Hi,

In message "[RCR] Numeric#of"

|this got a generally favourable reception so:
|
|RCR - Numeric#of - an accumlative version of Numeric#times

What if n is very large number?


same problem with using #map vs. #map! isn't it?
Besides that Numeric#of is not very intuitive for me (non native English
speaker). It seems too vague for me. Is the name "of" really OK for you
guys?

matz.

i'm not attached to 'of' - all i was suggesting was a collecting
Numeric#times. i actually considered this first:

~ > cat a.rb
class Numeric
def inject accum = []
times{|i| accum = yield(accum, i)}
accum
end
end

stacks = 3.inject{ [] }
p stacks # [[],[],[]]

hash = 16.inject({}){|h,i| h = i; h}
p hash[4] # => 4

but this is even less intuitive, whereas the 'of' why kindof reads like 'give
me n of these'. sorry i can't think of a better non-english-centric name ;-)

-a
--
===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| URL :: http://www.ngdc.noaa.gov/stp/
| "640K ought to be enough for anybody." - Bill Gates, 1981
===============================================================================
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: [RCR] Numeric#of"

|> What if n is very large number?
|
|same problem with using #map vs. #map! isn't it?

Yes, but they are for Enumerables, collecting items for number of
times can be abused more easily. Just my concern.

|i'm not attached to 'of' - all i was suggesting was a collecting
|Numeric#times. i actually considered this first:

...

|but this is even less intuitive, whereas the 'of' why kindof reads like 'give
|me n of these'. sorry i can't think of a better non-english-centric name ;-)

You don't have to care about being "non-english-centric", but I just
worry that the word "of" can mean virtually anything.

matz.
 
H

Hal Fulton

Yukihiro said:
Hi,

In message "Re: [RCR] Numeric#of"

|> What if n is very large number?
|
|same problem with using #map vs. #map! isn't it?

Yes, but they are for Enumerables, collecting items for number of
times can be abused more easily. Just my concern.

|i'm not attached to 'of' - all i was suggesting was a collecting
|Numeric#times. i actually considered this first:

...

|but this is even less intuitive, whereas the 'of' why kindof reads like 'give
|me n of these'. sorry i can't think of a better non-english-centric name ;-)

You don't have to care about being "non-english-centric", but I just
worry that the word "of" can mean virtually anything.

I understand the idiom, but I agree that it is a little vague.

What if we allow Integer#* to take a block?

a,b,c,d,e = 5 * { Array.new }


Hal
 
J

Joel VanderWerf

Hal said:
What if we allow Integer#* to take a block?

a,b,c,d,e = 5 * { Array.new }

Visually nice, but some would read that as "five times array dot new",
which is a lot like the reading of

5.times { Array.new }
 
M

Martin DeMello

Yukihiro Matsumoto said:
Besides that Numeric#of is not very intuitive for me (non native
English speaker). It seems too vague for me. Is the name "of" really
OK for you guys?

I don't like it in the case where the block actually uses the index -
i.e. 3.of { Array.new } seems fine, but 3.of {|i| i+1} doesn't. I can't
think of a better name either, though.

(And it seems worth reiterating my idea of a collecting block syntax -
3.times [|i| i+1] would be nicely orthogonal to the 'times' iterator)

martin
 
G

Gavin Sinclair

Joel said:
Visually nice, but some would read that as "five times array dot new",
which is a lot like the reading of

5.times { Array.new }

I think that if we are to support this Numeric#of idea, then the above
example is (inadvertently) the best.

a, b, c, d, e = 5.times { Array.new }

is more intuitive to me than

a, b, c, d, e = 5.of { Array.new }

I know Integer#times is already implemented, but supporting the above
would now be incompatible. At the moment, 5.times { whatever } returns 5.
Surely nobody depends on that behaviour? #times is used for its
side-effects, not its return value.

Here is a simple untested implementation which supports the existing as
well as the proposed behaviour.

class Integer
def times(&block)
(0...self).map(&block)
end
end

5.times { puts "Hello" } # existing use of Integer#times
n = 1
6.times { |i| n = n * i } # existing use of Integer#times
a, b, c = 7.times { Array.new } # *new* use of Integer#times

I can see where #of comes from, but #times is much more natural to me.

Cheers,
Gavin
 
K

Kent Dahl

Ara.T.Howard said:
RCR - Numeric#of - an accumlative version of Numeric#times
[...]
them = 3.of{ Array.new }

It also looks awfully terse. How about:

them = 3.times_collect{ Array.new }

I think it reads better. "Three times, collect [result of] Array.new".

It is three characters longer than the (seemingly) equivalent:

Array.new(3){Array.new}

but far more readable, and could assume another top-level container.

Just my 0.02 NOK.
 
M

Mauricio Fernández

I think that if we are to support this Numeric#of idea, then the above
example is (inadvertently) the best.

a, b, c, d, e = 5.times { Array.new }

is more intuitive to me than

a, b, c, d, e = 5.of { Array.new }

I know Integer#times is already implemented, but supporting the above
would now be incompatible. At the moment, 5.times { whatever } returns 5.
Surely nobody depends on that behaviour? #times is used for its

I do make a number of assumptions regarding Integer#times; specifically,
I expect it not to collect the result of the expression: what if a large
temp. object is created there? Would I have to add ; nil so that it
can be GCed?
side-effects, not its return value.

IMHO this
100000.times{ ... }
would be way more common than
a, b, c = 3.times{ [] }

I certainly do *not* want an array to be created in the 1st case.
That extension would render Integer#times unsuitable for iteration,
performance-wise.

I'd rather keep Integer#times as it is, and use the
a, b, c = (1..3).map{[]}
idiom; I don't think the use case deserves polluting the language (in the
case of 'of', by being too generic) or a potentially big performance hit,
for a minimal gain.

Don't get me wrong, I love adapting the language to the problem space
(I (ab)use metaprogramming often) but IMHO in this case it just doesn't
pay off.

--
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

MSDOS didn't get as bad as it is overnight -- it took over ten years
of careful development.
-- (e-mail address removed)
 
M

Michael Neumann

On Tue, May 25, 2004 at 06:15:24PM +0900, Gavin Sinclair wrote:

[...]

I'd rather keep Integer#times as it is, and use the
a, b, c = (1..3).map{[]}

I agree completely with all you said. What about a method
Integer#iterations that returns a Range object? That would indeed be
much more useful, as it could be used with a lot of more methods.

a, b, c = 3.iterations.map{[]}

Or something like this:

a, b, c = Range.times(3).map{[]}

But I'm not sure if it's worth.

Regards,

Michael
 
G

Guillaume Marcais

Le 25 mai 04, à 05:15, Gavin Sinclair a écrit :
Here is a simple untested implementation which supports the existing as
well as the proposed behaviour.

class Integer
def times(&block)
(0...self).map(&block)
end
end

5.times { puts "Hello" } # existing use of Integer#times
n = 1
6.times { |i| n = n * i } # existing use of Integer#times
a, b, c = 7.times { Array.new } # *new* use of Integer#times

But in that case, an array is built and return even if I use times as a
loop. That could be pretty bad performance wise. Unless the interpretor
as a way to know that the return value is not used and does not build
the array in that case.

Guillaume.
 
D

David Alan Black

Hi --

Hi,

In message "[RCR] Numeric#of"

|this got a generally favourable reception so:
|
|RCR - Numeric#of - an accumlative version of Numeric#times

What if n is very large number?

Besides that Numeric#of is not very intuitive for me (non native
English speaker). It seems too vague for me. Is the name "of" really
OK for you guys?

My problem with it (the word, rather than the idea) is that it doesn't
make sense to me as a message being sent to an integer. It reads more
like a keyword construct.

A couple of ideas:

1. Integer#collect # maybe too vague
2. Integer#times! # ! as a warning that results are accumulating


David
 
K

Kristof Bastiaensen

Hi,

Besides that Numeric#of is not very intuitive for me (non native
English speaker). It seems too vague for me. Is the name "of" really
OK for you guys?
matz.

Isn't "3.of { Array.new }" the same as
"Array.new(3) { Array.new }"?
IMHO the last one is more clear because it describes
better what you are doing
(creating an Array with three arrays as elements)

Regards,
Kristof
 
K

Kristof Bastiaensen

I agree completely with all you said. What about a method
Integer#iterations that returns a Range object? That would indeed be
much more useful, as it could be used with a lot of more methods.

a, b, c = 3.iterations.map{[]}

you could always do:

require "enumerator"
a, b, c = 3.to_enum:)times).map{[]}

but then again typing
a, b, c = [], [], []
is much less work ;-)

Regards,
Kristof
 
G

Gavin Kistner

A couple of ideas:
1. Integer#collect # maybe too vague
2. Integer#times! # ! as a warning that results are accumulating

Don't method names ending in ! imply that the receiver is being
modified.
(Do any methods exist in the core/standard which are so named, but
which do not modify the receiver?)

It would be foolish to think that
3.times! { ... }
could modify the integer 3, but that's what the second suggestion says
to me (despite being a nice attempt at an end-run around the
performance problem of accumulating while only wanting to iterate).
 
T

ts

G> (Do any methods exist in the core/standard which are so named, but
G> which do not modify the receiver?)

svg% ri Kernel#exit!
----------------------------------------------------------- Kernel#exit!
Process.exit!(fixnum=-1)
------------------------------------------------------------------------
Exits the process immediately. No exit handlers are run. _fixnum_
is returned to the underlying system as the exit status.

Process.exit!(0)

svg%



Guy Decoux
 
G

Gavin Sinclair

I'd rather keep Integer#times as it is, and use the
a, b, c = (1..3).map{[]}
idiom; I don't think the use case deserves polluting the language (in the
case of 'of', by being too generic) or a potentially big performance hit,
for a minimal gain.

I certainly agree that that idiom is clear enough and we don't need to
address the "problem" at hand. And your notes about performance are
well made.

I guess something like this would qualify for 'extensions' if there
was enough interest and a really good name. Perhaps n.map { ... } as
a shortcut for (0...n).map { ... } is suitable, but I've realised by
now that my intuition is not often widely shared :)

Gavin
 
H

Hal Fulton

Gavin said:
Don't method names ending in ! imply that the receiver is being modified.
(Do any methods exist in the core/standard which are so named, but which
do not modify the receiver?)

There is at least exit! and I think one or two others.

Matz has said that the ! signifies danger in general.
It would be foolish to think that
3.times! { ... }
could modify the integer 3, but that's what the second suggestion says
to me (despite being a nice attempt at an end-run around the performance
problem of accumulating while only wanting to iterate).

It's starting to become unreadable IMO.


Hal
 
D

David Alan Black

Hi --

Gavin Kistner said:
Don't method names ending in ! imply that the receiver is being
modified.

I put the little note over on the right in the hope of pre-answering
this :)

! in a method names alerts you to danger (which often, but not always,
involves a modification to the receiver). I thought maybe the
accumulation of results would be alert-worthy, since you'd want to
avoid it, for performance reasons, unless you were sure that's what
you wanted.


David
 

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

Similar Threads

Numeric#of 2
stable snapshot 4
Object#copy [rcr?] 4
[RCR] Kernel#hostname 0
parent of TrueClass, FalseClass 9
RMagick jp2 problem 8
RCR - 'struct flock*' wrapper for rb_io_fcntl 7
narray on windows? 1

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top