[RCR] Numeric#of

Hi –

how about this?

Object#collect

them = collect(3){ Array.new }

I don’t think “collect” is suitable as all-purpose/top-level method.
It really means: collect results from filtering an enumerable object’s
elements. You could say the object here is 3, but that’s got an
awfully procedural and kind of backwards feel to it (assigning the
role of the receiver to an argument).

should’nt this be Kernel::collect?
Anyway, I’d prefer to see Object#* :slight_smile:
them = Array.new * 3 # actually dup/clone

I think * is already claimed by too many existing classes to be
reclaimed for this (for example, “abc” * 3, or 10 * 3).

David

···

On Mon, 31 May 2004, gabriele renzi wrote:

il Tue, 25 May 2004 15:37:04 -0600, “Ara.T.Howard” ahoward@noaa.gov > ha scritto::


David A. Black
dblack@wobblini.net

Hal Fulton wrote:

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 }

Lighthearted observation: Kernel.exit! (why does ‘ri’ say Kernel#exit!
when it’s not an instance method?) does modify the status of the
Kernel.

And it can certainly be called a “destructive” method, as methods-
ending-in-bang are often called.

Gavin

···

On Tuesday, May 25, 2004, 11:36:25 PM, ts wrote:

(Do any methods exist in the core/standard which are so named, but
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)

i must say that idea of a collecting block syntax is a nice one…

this conversation has basically went the same way my own thought process went
before submitting the RCR. ‘of’ might not be the greatest name, but then
again neither is ‘map’ (unless you have programmed perl). my point is this:
‘of’ is nice and short and mnemonic enough, at least as mnemonic as
Array#map isn’t it?

after you’d seen

a, b, c = 3.of { MyClass.new }

or even

first, second, third, fourth = 4.of {|which| MyClass.new which }

once, maybe thrice, in some sources - wouldn’t it be clear enough?

-a

···

On Tue, 25 May 2004, Hal Fulton wrote:

Gavin Kistner wrote:

On May 25, 2004, at 5:08 AM, David Alan Black wrote:

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?)

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

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
URL :: Solar-Terrestrial Physics Data | NCEI
“640K ought to be enough for anybody.” - Bill Gates, 1981
===============================================================================

The “root cause” of this RCR (and others), I think, is the desire to
create an Enumerable out of an Integer. Integers themselves are not
Enumerable (nor should they be), but it is often desirable to think of
them as such. Consider

a =
3.times { a << “foo” }

Integer#times is natural enough, but it is not an Enumeration – and
that is where #times does not match our needs. Thus we have

require ‘enumerator’
3.enum_for(:times).map { “foo” }

or, the proposed abbreviation,

3.of { “foo” }

It is clear there is a desire to convert from Integers to Enumerables
freely. I think it is time to bring this into canon – and I would
like to call it Integer#enum.

The proposed #of or #instances_of is thus a special case of
Integer#enum,

3.enum.map { “foo” }

which I happen to like the best. But the gem here is that it comes
with all the power of Enumerable

6.enum.sort_by { rand } # => [4, 2, 5, 3, 1, 0]

Now you may say, “well it’s effectively the same as (0…n), who needs
it?” First, I like 6.enum.foo better than (0…6).foo. Second, you
cannot chain with Ranges,

[1, 2, 3].inject(0) { |a, x| a+x }.enum.map { |x| x }

would become

(0…([1, 2, 3].inject(0) { |a, x| a+x })).map { |x| x }

which I feel is awkward, if not confusing.

···

— Harry Ohlsen harryo@qiqsolutions.com wrote:

gabriele renzi wrote:

not if you don’t want instances, say:

them 3.instances_of {‘foo’}

Good point!

I was thinking that the point of the method was to get unique objects, but of course it could be
used in this way.


Do you Yahoo!?
Friends. Fun. Try the all-new Yahoo! Messenger.
http://messenger.yahoo.com/

i see your point, but my original idea was not only for constructing objects,
but for doing ‘something’ n times:

admittedly lame example:

results = 16.of{|n| db.execute(build_query(n)) }

-a

···

On Tue, 1 Jun 2004, Alan Chen wrote:

gabriele renzi surrender_it@remove.yahoo.it wrote in message news:1aulb0pj5pk1b5hup1otnt70plqn4dnifh@4ax.com

il Tue, 25 May 2004 15:37:04 -0600, “Ara.T.Howard” ahoward@noaa.gov >> ha scritto::

how about this?

Object#collect

them = collect(3){ Array.new }

should’nt this be Kernel::collect?
Anyway, I’d prefer to see Object#* :slight_smile:
them = Array.new * 3 # actually dup/clone

I had one suggestion which I think was lost in the recent gateway
debug process… I’ll repeat it again below - hopefully it wasn’t a
simply bad idea :slight_smile:

To me, creating multiple instances of initialized objects feels like
it belongs more with the new call, rather than Integer. Perhaps we
could add a “multiple instance” new? Here is one implementation.

def Object.newx( nx, *args)
instances =
if( block_given? )
nx.times { instances.push yield(self.new(*args)) }
else
nx.times { instances.push self.new(*args) }
end
instances
end

a,b,c = Array.newx(3)

I’m not sure what should be done when the new also expects a block.

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
A flower falls, even though we love it; and a weed grows, even though we do
not love it. --Dogen
===============================================================================

Hi,

To me, creating multiple instances of initialized objects feels like
it belongs more with the new call, rather than Integer.

Yes, in fact it already works with the new call :wink:

a,b,c = Array.newx(3)

a,b,c = Array.new(3) { Array.new }

Regards,
Kristof

···

On Tue, 01 Jun 2004 16:29:57 -0700, Alan Chen wrote:

Joel wrote:

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 }

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

Ara.T.Howardwrote:
[snip]

after you’d seen

a, b, c = 3.of { MyClass.new }

or even

first, second, third, fourth = 4.of {|which| MyClass.new which }

once, maybe thrice, in some sources - wouldn’t it be clear enough?

Your ‘of’ is a mix between times and map. Wouldn’t it be better to
name it ‘times_map’ ?

a, b, c = 3.times_map {|n| -n}

a=0, b=-1, c=-2

···


Simon Strandgaard

i must say that idea of a collecting block syntax is a nice one…

please, no more syntax :slight_smile:
I believe that in the case a collecting/non collecting dychotomy
should exist it should be something at the convention level, like !
for dangerous methods

this conversation has basically went the same way my own thought process went
before submitting the RCR. ‘of’ might not be the greatest name, but then
again neither is ‘map’ (unless you have programmed perl).

I believe map() was really common long time before Larry wrote his
first language, and it is very common in many languages.
not that this makes it obvious to anyone, anyway.

my point is this:
‘of’ is nice and short and mnemonic enough, at least as mnemonic as
Array#map isn’t it?

after you’d seen

a, b, c = 3.of { MyClass.new }

or even

first, second, third, fourth = 4.of {|which| MyClass.new which }

once, maybe thrice, in some sources - wouldn’t it be clear enough?

agreed

···

il Tue, 25 May 2004 12:22:53 -0600, “Ara.T.Howard” ahoward@noaa.gov ha scritto::

Although not as short (or memorable for the usage of a,b,c = 3.of {
… } ) this smells like the cleanest solution, to me.

···

On May 25, 2004, at 8:26 PM, Jeff Mitchell wrote:

The proposed #of or #instances_of is thus a special case of
Integer#enum,

3.enum.map { “foo” }


(-, /\ / / //

Kristof Bastiaensen kristof@vleeuwen.org wrote in message news:pan.2004.06.02.00.04.02.673681@vleeuwen.org

Hi,

To me, creating multiple instances of initialized objects feels like
it belongs more with the new call, rather than Integer.

Yes, in fact it already works with the new call :wink:

a,b,c = Array.newx(3)

a,b,c = Array.new(3) { Array.new }

Regards,
Kristof

Yes, but can you do it for any object?

class Dbrec
attr_accessor :city, :state
def initialize
@name = ‘’
@state = ‘’
end
end

losangeles,sandiego = Dbrec.newx(2)

or

losangeles,sandiego = Dbrec.newx(2) { |rec| rec.state = ‘CA’; rec }

If anyone was actually serious about a newx method, you might want to
eliminate the need for the last “; rec” in the block above. Now, Ara
was looking for a general “do it x times and collect the results”
method and this is a “instantiate multiple mostly, similar objects”
method. My hunch is that neither one is necessary, and would mostly
trade a minor convience for a minor obfuscation of code.

···

On Tue, 01 Jun 2004 16:29:57 -0700, Alan Chen wrote:

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.

···

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


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.
– dmeggins@aix1.uottawa.ca

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.

···

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

[snip]

Your ‘of’ is a mix between times and map. Wouldn’t it be better to
name it ‘times_map’ ?

Even simpler… it would make sense to me if it were just named ‘maps’

a, b, c = 3.maps {|n| -n}

a=0, b=-1, c=-2

···

Simon Strandgaard neoneye@adslhome.dk wrote:


Simon Strandgaard

i must say that idea of a collecting block syntax is a nice one…

please, no more syntax :slight_smile:

What do you have against syntax? (:

I believe that in the case a collecting/non collecting dychotomy
should exist it should be something at the convention level, like !
for dangerous methods

Add % to the list of acceptable method name suffixes? (I’d say we’ve
pretty thoroughly colonised the keyboard by now - good free symbols are
hard to find.)

martin

···

gabriele renzi surrender_it@remove.yahoo.it wrote:

il Tue, 25 May 2004 12:22:53 -0600, “Ara.T.Howard” ahoward@noaa.gov > ha scritto::

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

···

On Tue, May 25, 2004 at 07:20:00PM +0900, Mauricio Fern?ndez wrote:

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 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 :slight_smile:

Gavin

···

On Tuesday, May 25, 2004, 8:20:00 PM, Mauricio wrote:

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.

Or even just map (there’s no Numeric#map) - I don’t like that either
[ruby-talk:62177] but I can’t think of anything I like better.

martin

···

Simon Strandgaard neoneye@adslhome.dk wrote:

Simon Strandgaard neoneye@adslhome.dk wrote:
[snip]

Your ‘of’ is a mix between times and map. Wouldn’t it be better to
name it ‘times_map’ ?

Even simpler… it would make sense to me if it were just named ‘maps’

a, b, c = 3.maps {|n| -n}

a=0, b=-1, c=-2

i must say that idea of a collecting block syntax is a nice one…

please, no more syntax :slight_smile:

Well, I’d love ruby to stay simple. I have this ugly feeling of ruby
becoming perlish in the bad way, i.e. adding new syntax, new
mistetyous operators and so on. Just think of how many new things
we’ll see in Ruby2… Key:val literals, val:default arguments,
@_variables

And, in the end, everybody is going to hate syntax (sooner or later),
that’s why people gets happy with LISP (sooner or later :wink:

What do you have against syntax? (:

I believe that in the case a collecting/non collecting dychotomy
should exist it should be something at the convention level, like !
for dangerous methods

Add % to the list of acceptable method name suffixes? (I’d say we’ve
pretty thoroughly colonised the keyboard by now - good free symbols are
hard to find.)

not necessarily a new symbol (I’m against stuff that is not obvious).
But something like: collecting_times/times colllecting_each/each and
so on, would be nice.
Surely not ‘collecting’ but something on the line. Now I just need to
find a good name, I’m sure I can get it in the next few decades…

···

il Thu, 27 May 2004 05:23:12 GMT, Martin DeMello martindemello@yahoo.com ha scritto::