Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Useless hack of the saturday morning

1 view
Skip to first unread message

gabriele renzi

unread,
May 28, 2005, 7:11:18 AM5/28/05
to
Hi gurus and nubys,

this morning I stumbled across the Autrijus Tang journal[1],
which was showing this nifty piece of code:


say [~] (-> @c is copy {gather {
while @c[0] { for @c ->
{take(.shift)} } }
}(['Joec','utrk','shle','te6r',' r .','a h.','nPa.'].map:{[split "",$_]}));

in perl6 the [<something>] is the reduce metaoperator, and -> is the
equivalent of "proc".
The hard thing was understanding what gather/take are supposed to do.
A little investigation yielded explanation[2], they seem to be some kind
of accumulating construct a-la inject. In the tradition of the
perl6->ruby port such as junctions, .= operator and so on I tried
implement it.


Oh, and here is the translated JAPRH

proc{|c|p gather{c.each{|x|take x.shift}while
c[0][0]}.join}.call ['Joedh','utr a','shlRc',
'te6uk',' r be','a ayr.','nPn .' ].map{|x|x.split ''}

And down is the implementation[3]
[1] http://use.perl.org/~autrijus/journal/24919

[2] http://search.cpan.org/~dconway/Perl6-Gather-0.04/Gather.pm

[3]
class Gatherer
attr :gathered
def take(arg)
@gathered||=[]
@gathered<< arg
end
end

def gather &blk
c=Gatherer.new
c.instance_eval &blk
c.gathered
end

if __FILE__ == $0
require 'test/unit'

class TestGatherer < Test::Unit::TestCase
def ok(x, y)
assert_equal x.to_a,y
end
def test_take
l= gather { for i in 1..10: take i end}
ok 1..10, l
end
def test_take2
l= gather { for i in 1..10: take i end; take 99}
assert_equal (1..10).to_a+[99],l
end

def test_gathered
l= gather {for i in 1..10: take i end; take 99 unless gathered}
ok 1..10,l
end

def test_gathered_empty
l= gather {take 99 unless gathered}
ok 99,l
end

def test_gathered_pop
l= gather {for i in 1..10: take i end; gathered.pop }
ok 1..9,l
end
end
end

Christian Neukirchen

unread,
May 29, 2005, 5:50:48 AM5/29/05
to
gabriele renzi <surren...@remove-yahoo.it> writes:

> Hi gurus and nubys,
>
> this morning I stumbled across the Autrijus Tang journal[1],
> which was showing this nifty piece of code:
>
>
> say [~] (-> @c is copy {gather {
> while @c[0] { for @c ->
> {take(.shift)} } }
> }(['Joec','utrk','shle','te6r',' r .','a h.','nPa.'].map:{[split "",$_]}));
>
> in perl6 the [<something>] is the reduce metaoperator, and -> is the
> equivalent of "proc".
> The hard thing was understanding what gather/take are supposed to do.
> A little investigation yielded explanation[2], they seem to be some
> kind of accumulating construct a-la inject. In the tradition of the
> perl6->ruby port such as junctions, .= operator and so on I tried
> implement it.

That's very nice and useful (I often wished for it), but goo already
had it for a long time. :-) It is called "packing" there, see
http://people.csail.mit.edu/jrb/goo/manual.46/goomanual_29.html

I think the implementation with instance_eval can be a bit surprising,
maybe [Dynamic Variables][1] could do that better.

[1]: http://chneukirchen.org/blog/archive/2005/04/dynamic-variables-in-ruby.html

--
Christian Neukirchen <chneuk...@gmail.com> http://chneukirchen.org


gabriele renzi

unread,
May 29, 2005, 6:52:59 AM5/29/05
to
Christian Neukirchen ha scritto:
<snip>

>
> That's very nice and useful (I often wished for it), but goo already
> had it for a long time. :-) It is called "packing" there, see
> http://people.csail.mit.edu/jrb/goo/manual.46/goomanual_29.html

wow, I always thought GOO was cool, it seem I need to investigate it
more deeply :)

> I think the implementation with instance_eval can be a bit surprising,
> maybe [Dynamic Variables][1] could do that better.

yup, instance_eval is an hack, but I liked the idea of just allowing
#take inside #gather, which I don't have Idea how to reproduce withouth
it. Using DynaVars seem definitely a cool hack, anyway :)

Christian Neukirchen

unread,
May 29, 2005, 10:15:34 AM5/29/05
to
gabriele renzi <surren...@remove-yahoo.it> writes:

> Christian Neukirchen ha scritto:
> <snip>
>> That's very nice and useful (I often wished for it), but goo already
>> had it for a long time. :-) It is called "packing" there, see
>> http://people.csail.mit.edu/jrb/goo/manual.46/goomanual_29.html
>
> wow, I always thought GOO was cool, it seem I need to investigate it
> more deeply :)

If it was alive, it would be even nicer... so many good ideas but
noone pushing them.

>> I think the implementation with instance_eval can be a bit surprising,
>> maybe [Dynamic Variables][1] could do that better.
>
> yup, instance_eval is an hack, but I liked the idea of just allowing
> #take inside #gather, which I don't have Idea how to reproduce
> withouth it. Using DynaVars seem definitely a cool hack, anyway :)

I'd just make it raise a RuntimeError if you're not inside a
gathering. Esp. in method definitions, how would you reach for "the
outer self"?

murphy

unread,
May 31, 2005, 8:02:50 AM5/31/05
to
what about a more Ruby-like extension:

class Array
def add
yield self
self
end
end

# simple
a = [].add do |a|
a << 1
a << 2
a << 3
end
p a

# Fibonacci
b = [1,1].add do |a|
15.times { a << a[-1] + a[-2] }
end
p b

Array#inject may do as well.

Christian Neukirchen

unread,
May 31, 2005, 10:28:36 AM5/31/05
to
"murphy" <mur...@cYcnus.de> writes:

I think the nice thing about packings is that they don't need to
reference the array variable... your code is no improvement to just
appending to the array directly, IMHO.

James Edward Gray II

unread,
May 31, 2005, 10:57:17 AM5/31/05
to
On May 31, 2005, at 9:28 AM, Christian Neukirchen wrote:

> I think the nice thing about packings is that they don't need to
> reference the array variable... your code is no improvement to just
> appending to the array directly, IMHO.

In that case, how are gather/packing an improvement? They require
more typing than just appending to an Array.

I guess I just don't "get it". <shrugs>

James Edward Gray II


Christian Neukirchen

unread,
May 31, 2005, 2:33:50 PM5/31/05
to

For example, you could write methods that can add to any object
responding to "<<", just whatever it is.

It's mostly convenience, I'd say. It can make the code more elegant,
e.g. if you would have used #map, but sometimes need to map to several
values...

> James Edward Gray II

0 new messages