Re: Operating on pairs, Was Re: Revised solution #2

2009-01-16 Thread Richard Hainsworth

Carl Mäsak wrote:

Andy (>):
  

map?

perl6 -e 'my $x = :a<5>; say $x.map( {  .value / 10} ).fmt("%s")'



Yes, sure. That'll print a tenth of the value of $x. The '.fmt("%s")'
is a no-op in this case.

// Carl
  

Not entirely a no-op. Thus
$perl6
> my $x=:a<5>; say $x.map({.value/10}).fmt("the value is %s%%")
the value is 0.5%

But we have lost the .key part of the pair

> my $x=:a<5>; say $x.map({.value/10}).fmt("key %s val %s")
Null PMC access in get_string()

Still, even if we could do something like (which we cant with rakudo, 
not sure if this is possible in perl6 in principle)
say $pair.map({.key => .value*100/$count}).fmt("Candidate %s has %s 
percent of vote");


would it be more elegant than
printf("Candidate %s has %s percent of 
vote\n",$pair.key,$pair.value*100/$count);


I dont think so.



Re: Operating on pairs, Was Re: Revised solution #2

2009-01-15 Thread Larry Wall
On Thu, Jan 15, 2009 at 12:46:09PM +0300, Richard Hainsworth wrote:
> Larry Wall wrote:
>> On Wed, Jan 14, 2009 at 09:55:38AM +0300, Richard Hainsworth wrote:
>>   
>>> However, I came across one thing in solution #3 that I posted 
>>> yesterday.  $pair.fmt("%s %s") is nice, but it doesnt allow for any 
>>> action on either  value or key before printing (I wanted to print the 
>>> value as a  percentage), and this had to be done in a printf 
>>> statement. In fact the  printf statement was the longest and ugliest 
>>> statement in the program.
>>> 
>>
>> Maybe I'm missing something, but you can always do:
>>
>> $pair.key.foo.fmt("%s"),
>> $pair.value.bar.fmt("%s")
>>
>> Larry
>>   
> This surely requires that foo and bar are defined as sub's.

It was a notional action, just as the %s is a notional format.
The main point was that you can deref $pair twice.

> Suppose I just need a single transformation of a value before outputting  
> it? Eg., expressing .value as a percentage of $count?
>
> Is there some way to include a one-off in the subroutine "chain"?  
> Something like
> $pair.value.{shift / 10}.fmt("%s");

Well, I'm sure there's some way to do that, but certainly not
with any existing subscript notation.

Maybe it's better to just use parens:

($pair.value/10).fmt("%s")

Admittedly that doesn't interpolate well, which is part of the point
.fmt in the first place, and the way interpolation is defined to
end on brackets of some kind:

say "My value = $foo.fmt('%d')."

So I guess there's some small need for mapping a scalar value.

$pair.value.map({$_/10}).fmt("%s")

which maybe can even be written

$pair.value.map(*/10).fmt("%s")

Larry


Operating on pairs, Was Re: Revised solution #2

2009-01-15 Thread Richard Hainsworth

Larry Wall wrote:

On Wed, Jan 14, 2009 at 09:55:38AM +0300, Richard Hainsworth wrote:
  
However, I came across one thing in solution #3 that I posted yesterday.  
$pair.fmt("%s %s") is nice, but it doesnt allow for any action on either  
value or key before printing (I wanted to print the value as a  
percentage), and this had to be done in a printf statement. In fact the  
printf statement was the longest and ugliest statement in the program.



Maybe I'm missing something, but you can always do:

$pair.key.foo.fmt("%s"),
$pair.value.bar.fmt("%s")

Larry
  

This surely requires that foo and bar are defined as sub's.

Suppose I just need a single transformation of a value before outputting 
it? Eg., expressing .value as a percentage of $count?


Is there some way to include a one-off in the subroutine "chain"? 
Something like

$pair.value.{shift / 10}.fmt("%s");




Re: Revised solution #2

2009-01-14 Thread Larry Wall
On Wed, Jan 14, 2009 at 09:55:38AM +0300, Richard Hainsworth wrote:
> However, I came across one thing in solution #3 that I posted yesterday.  
> $pair.fmt("%s %s") is nice, but it doesnt allow for any action on either  
> value or key before printing (I wanted to print the value as a  
> percentage), and this had to be done in a printf statement. In fact the  
> printf statement was the longest and ugliest statement in the program.

Maybe I'm missing something, but you can always do:

$pair.key.foo.fmt("%s"),
$pair.value.bar.fmt("%s")

Larry


Re: Revised solution #2

2009-01-13 Thread Carl Mäsak
Richard (>), Carl (>>), Andy (>>>):
>>> P6 treats the key/value as an anonymous 'pair' object so @ranking is an
>>> list of pairs. That's why:
>>>  say @ranking.pop.fmt("$m Medal: %s, %s")
>>>
>>> or, less succinctly:
>>>  say (pop @ranking).fmt("$m Medal: %s, %s");
>>>
>>> works - the pair object, popped off into the 'printf' like 'fmt' method
>>> (akin to:
>>> my $skater_pair = pop @ranking;
>>> printf("$m Medal: %s, %s\n", $skater_pair);
>>>
>>> or, longer:
>>> printf("$m Medal: %s, %s\n", $skater_pair.key, $skater_pair.value);
>>>
>>> ) devolves into a list (key, value) which fills the 2 '%s' fields.
>>>
>>> hashes, then, are lists of pairs, indexed by their 'key' attribute.
>>>
>>> I think, anyway.
>>>
>>
>> You are right about everything but the 'devolves into a list' part.
>> Look at S29:1599, and you'll note that one of the four flavours of
>> .fmt method lives in the Pair class. No devolving required.
>>
>> Because of this, the .fmt call is not equivalent to the version of
>> printf taking a pair:
>>
>>  printf("$m Medal: %s, %s\n", $skater_pair);
>>
>> In fact, this line throws a "Null PMC access in get_string()" in
>> Rakudo, which bug I just reported.
>
> Actually Andy had 'printf("...",$skater_pair.key, $skater_pair.value);'
> which works.

Yes, but I had the distinct impression from his message that he
considered the expanded version with C<$skater_pair.key,
$skater_pair.value> in the argument list equivalent to the form with
just C<$skater_pair> in the argument list. That is not the case in
Perl 6; arguments are not flattened so that they take up more
positions in the argument list than they appear.

> However, I came across one thing in solution #3 that I posted yesterday.
> $pair.fmt("%s %s") is nice, but it doesnt allow for any action on either
> value or key before printing (I wanted to print the value as a percentage),
> and this had to be done in a printf statement. In fact the printf statement
> was the longest and ugliest statement in the program.

Use .map?

// Carl


Re: Revised solution #2

2009-01-13 Thread Richard Hainsworth

Carl Mäsak wrote:

Andy (>):
  

P6 treats the key/value as an anonymous 'pair' object so @ranking is an
list of pairs. That's why:
  say @ranking.pop.fmt("$m Medal: %s, %s")

or, less succinctly:
 say (pop @ranking).fmt("$m Medal: %s, %s");

works - the pair object, popped off into the 'printf' like 'fmt' method
(akin to:
my $skater_pair = pop @ranking;
printf("$m Medal: %s, %s\n", $skater_pair);

or, longer:
printf("$m Medal: %s, %s\n", $skater_pair.key, $skater_pair.value);

) devolves into a list (key, value) which fills the 2 '%s' fields.

hashes, then, are lists of pairs, indexed by their 'key' attribute.

I think, anyway.



You are right about everything but the 'devolves into a list' part.
Look at S29:1599, and you'll note that one of the four flavours of
.fmt method lives in the Pair class. No devolving required.

Because of this, the .fmt call is not equivalent to the version of
printf taking a pair:

 printf("$m Medal: %s, %s\n", $skater_pair);

In fact, this line throws a "Null PMC access in get_string()" in
Rakudo, which bug I just reported.

Thanks,
// Carl
  
Actually Andy had 'printf("...",$skater_pair.key, $skater_pair.value);' 
which works.


However, I came across one thing in solution #3 that I posted yesterday. 
$pair.fmt("%s %s") is nice, but it doesnt allow for any action on either 
value or key before printing (I wanted to print the value as a 
percentage), and this had to be done in a printf statement. In fact the 
printf statement was the longest and ugliest statement in the program.


Richard