[S29] pick on other things than junctions

1 view
Skip to first unread message

Ingo Blechschmidt

unread,
Apr 4, 2005, 2:34:50 PM4/4/05
to perl6-l...@perl.org
Hi,


I remembered Damian saying that pick does not only work on junctions,
but on arrays and hashes, too (and I even found his posting :):
http://groups.google.com/groups?selm=420DB295.3000902%40conway.org).

Are the following assumptions correct?
my $junc = 1|2|3;
print $junc.pick; # "1", "2", or "3"
print pick $junc; # same

my @array = <a b c>;
print @array.pick; # "a", "b", or "c"
print pick @array; # same

What does pick return on hashes? Does it return a random value or a
random pair? (I suppose returning a pair is more useful.)


--Ingo

--
Linux, the choice of a GNU | The next statement is not true. The
generation on a dual AMD | prevoius statement is true.
Athlon! |

Rod Adams

unread,
Apr 4, 2005, 3:13:15 PM4/4/05
to perl6-l...@perl.org
Ingo Blechschmidt wrote:

>I remembered Damian saying that pick does not only work on junctions,
>but on arrays and hashes, too (and I even found his posting :):
>http://groups.google.com/groups?selm=420DB295.3000902%40conway.org).
>
>Are the following assumptions correct?
> my $junc = 1|2|3;
> print $junc.pick; # "1", "2", or "3"
> print pick $junc; # same
>
> my @array = <a b c>;
> print @array.pick; # "a", "b", or "c"
> print pick @array; # same
>
>What does pick return on hashes? Does it return a random value or a
>random pair? (I suppose returning a pair is more useful.)
>
>

Most likely a pair.

Now if I could only find some more time to work on S29. I've been making
progress (slowly) on getting the string functions written up, but life
seems to be conspiring against rapid progress.


-- Rod Adams

Trey Harris

unread,
Apr 4, 2005, 3:29:34 PM4/4/05
to Ingo Blechschmidt, perl6-l...@perl.org
In a message dated Mon, 4 Apr 2005, Ingo Blechschmidt writes:
> What does pick return on hashes? Does it return a random value or a
> random pair? (I suppose returning a pair is more useful.)

I'd assume in all cases that pick returns an *alias*, and in the case of
hashes, an alias to the pair:

# Add entropy to your hash
for 1..$entropy_thresshold {
%hash.pick.value *= rand $scribble_factor;
}

Trey

Trey Harris

unread,
Apr 4, 2005, 5:44:12 PM4/4/05
to Ingo Blechschmidt, perl6-l...@perl.org
Yikes. Sorry about the ressends... my email client kept dying and I
thought the mail was lost. Guess not. :-)

Trey

--

Trey Harris

unread,
Apr 4, 2005, 5:12:37 PM4/4/05
to Ingo Blechschmidt, perl6-l...@perl.org
In a message dated Mon, 4 Apr 2005, Ingo Blechschmidt writes:
> What does pick return on hashes? Does it return a random value or a
> random pair? (I suppose returning a pair is more useful.)

I'd assume in all cases that pick returns an *alias*, and in the case of

Trey Harris

unread,
Apr 4, 2005, 3:10:37 PM4/4/05
to Ingo Blechschmidt, perl6-l...@perl.org
I'd assume you'd get an *alias* to a random pair:

# Test error-correction
for 1..$entropy_threshhold {
%hash.pick.value = rand $scribble_factor;
}

Trey

In a message dated Mon, 4 Apr 2005, Ingo Blechschmidt writes:

Ingo Blechschmidt

unread,
Apr 5, 2005, 8:38:05 AM4/5/05
to perl6-l...@perl.org
Hi,

I like that, too. So:
my @array = <a b c d>;
my $elem = @array.pick;
$elem = "z"; # $elem now "z", @array unchanged

my @array = <a b c d>;
my $elem := @array.pick;
$elem = "z"; # $elem now "z", @array changed
# (any(@array) eq "z" now true)

Same for hashes:
my %hash = (a => 1, b => 2);
my $pair = %hash.pick;
$pair = ...; # %hash unchanged

my %hash = (a => 1, b => 2),
my $pair := %hash.pick;
$pair = ...; # %hash changed


--Ingo

--
Linux, the choice of a GNU | Black holes result when God divides the
generation on a dual AMD | universe by zero.
Athlon! |

Larry Wall

unread,
Apr 5, 2005, 12:05:37 PM4/5/05
to perl6-l...@perl.org
On Tue, Apr 05, 2005 at 02:38:05PM +0200, Ingo Blechschmidt wrote:
: Hi,

:
: Trey Harris wrote:
: > In a message dated Mon, 4 Apr 2005, Ingo Blechschmidt writes:
: >> What does pick return on hashes? Does it return a random value or a
: >> random pair? (I suppose returning a pair is more useful.)
: >
: > I'd assume in all cases that pick returns an *alias*, and in the case
: > of hashes, an alias to the pair:
: >
: > # Add entropy to your hash
: > for 1..$entropy_thresshold {
: > %hash.pick.value *= rand $scribble_factor;
: > }
:
: I like that, too. So:
: my @array = <a b c d>;
: my $elem = @array.pick;
: $elem = "z"; # $elem now "z", @array unchanged
:
: my @array = <a b c d>;
: my $elem := @array.pick;
: $elem = "z"; # $elem now "z", @array changed
: # (any(@array) eq "z" now true)

But what should we call "pick without replacment"? .peck?

Unfortunately @array.=pick isn't what you want. It would reduce the
array to one element. On the other hand, if .pick takes an argument
saying how many to pick, then maybe

@array.=pick(+@array)

gives you a random shuffle. Unfortunately,

@array.=pick(@array - 1)

won't tell you which one it left out.

: Same for hashes:


: my %hash = (a => 1, b => 2);
: my $pair = %hash.pick;
: $pair = ...; # %hash unchanged
:
: my %hash = (a => 1, b => 2),
: my $pair := %hash.pick;
: $pair = ...; # %hash changed

I'm not sure that works. We don't quite have pairs as first class
containers. Binding would try to use a pair as a named argument, and
would fail unless the key happened to be 'pair', which it isn't in this
case. However, if you were to say,

my Pair $pair := %hash.pick;

then it has a better chance of working, presuming someone has the gumption
to write .pick on hashes, which doesn't look entirely trivial to do right.

Larry

Ingo Blechschmidt

unread,
Apr 5, 2005, 1:01:03 PM4/5/05
to perl6-l...@perl.org
Hi,

Larry Wall wrote:
> : Same for hashes:
[...]


> : my %hash = (a => 1, b => 2),
> : my $pair := %hash.pick;
> : $pair = ...; # %hash changed
>
> I'm not sure that works. We don't quite have pairs as first class
> containers. Binding would try to use a pair as a named argument, and
> would fail unless the key happened to be 'pair', which it isn't in
> this case.

Oh yes, of course. Others may be interested in
http://groups.google.com/groups?threadm=x7wtsvo0fs.fsf%40mail.sysarch.com.

> then it has a better chance of working, presuming someone has the
> gumption to write .pick on hashes, which doesn't look entirely trivial
> to do right.

<thinking out loud>I'm sure I overlooked something, but the following
seems to be correct and is not *that* difficult :):
class Hash;
...;
method pick() is rw {
# First pick a random key.
my $key = .keys.pick;
# Then return an appropriate Proxy object:
return new Proxy:
FETCH => {

Ok. While typing the C<{> here, I realized you were correct :)
It'd be reasonable simple if there was a .get_pair_by_key method
(which'd do appropriate binding and'd be C<is rw>):

method pick() is rw {
my $key = .keys.pick;
my $pair := .get_pair_by_key($key);
return $pair;
}


--Ingo

--
Linux, the choice of a GNU | Mathematicians practice absolute freedom.
generation on a dual AMD | -- Henry Adams
Athlon! |

Ingo Blechschmidt

unread,
Apr 28, 2005, 8:49:12 AM4/28/05
to perl6-l...@perl.org
Ingo Blechschmidt <iblech <at> web.de> writes:
> > then it has a better chance of working, presuming someone has the
> > gumption to write .pick on hashes, which doesn't look entirely trivial
> > to do right.
>
> <thinking out loud>I'm sure I overlooked something, but the following
> seems to be correct and is not *that* difficult :):
> class Hash;
> ...;
> method pick() is rw {
> # First pick a random key.
> my $key = .keys.pick;
> # Then return an appropriate Proxy object:
> return new Proxy:
> FETCH => {
>
> Ok. While typing the C<{> here, I realized you were correct :)
> It'd be reasonable simple if there was a .get_pair_by_key method
> (which'd do appropriate binding and'd be C<is rw>):
>
> method pick() is rw {
> my $key = .keys.pick;
> my $pair := .get_pair_by_key($key);
> return $pair;
> }

well :)

# Ignoring multi-dimensionality
method pairbykey($key is copy) is rw {
return new Proxy:
FETCH => -> $pair { $self{$key} },
STORE => -> $pair {
my ($newkey, $newval) = $pair.kv;
$self.delete($key); # Delete old entry
$self{$key = $newkey} = $newval; # Add new entry
};
}
# Correct?

BTW, this would make the following work, too:
for %hash.pairs -> $pair is rw { $pair = ... }
# Implementation of Hash::pairs:
method pairs (Any|Junction *@keytests) {
my @keys = @keytests ?? .keys.grep:{ $_ ~~ any @keytests } :: .keys;
return .pairbykey».(@keys);
}
# Correct?

The next logical step to full rw-ness would be a rw .pairs (@keytests
removed for simplicity):
method pairs ($self:) is rw {
return new Proxy:
FETCH => { .pairbykey».(.keys) },
STORE => -> *@new {
.delete($_) for .keys;
# [Is there a .clear? The obvious way, %hash = ()/
# $self = {} won't work of course.]
$self{$_.key} = $_.value for @new;
};
}
# Correct?

</thinking out loud>

--Ingo

--
Linux, the choice of a GNU | Mr. Cole's Axiom: The sum of the
generation on a dual AMD | intelligence on the planet is a constant;
Athlon! | the population is growing.

Reply all
Reply to author
Forward
0 new messages