Re: Gather, take, newbie questions

2013-12-11 Thread Richard Hainsworth

Hello Jacinta,

Perl6 code should be much simpler than what you are trying. There is no 
need to use a state variable or a binding.


I'm not sure how to use a maximum in the sequence, so I didn't.

The Fibonacci sequence can be generated in a single line as

1, 1, &[+] ... *

or as
1, 1, *+* ... *
in your code.

So the question is how to apply your constraints, viz. a certain number 
of terms or a maximum.


The best thing when trying to experiment with perl6 is to use REPL, 
which you get by just typing perl6 in to a terminal.

Below is my output; my terminal gives me ">" to say its waiting for input

So
$ perl6
> say (1, 1, &[+] ... *)[0 .. 20]
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946

The Fibonacci sequence is in the () and the [0..20] gives me the first 
21 values


By the way I tried just
say 1, 1, &[+] ... *
and the terminal hung. Got to put a stop on the sequence.

Now we need to get terms to a maximum, and you wanted to use gather/take, so

> say gather for 1, 1, &[+] ... * { last if $_ > 2; take $_ }
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 
17711


The sequence is after the 'for' and the test is inside the {}, with 
'take' snapping up all values of the sequence that pass the filter


> say (gather for 1, 1, &[+] ... * { last if $_ > 2; take $_ })[0 
.. 19]

1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765

This puts the two idioms together, implementing a maximum value of 2 
and a maximum number of terms.


You could avoid the magic $_ with a pointy block, eg.
gather for 1, 1, &[+] ... * -> $s { last if $s > 2; take $s }

but I'm an old perl fan and I like the default variable $_ .

You want it in a subroutine?

> sub Fib ( :$max-value, :$max-no-terms ) {( gather for  1, 1, &[+] ... 
* -> $s { last if $s > $max-value; take $s } )[0 .. $max-no-terms] }

sub Fib(:max-value(:$max-value), :max-no-terms(:$max-no-terms)) { ... }

> say Fib(:max-no-terms(35),:max-value(2) )
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 
17711


Note that Fib uses named parameters, not positional parameters. See the 
: in the definition line.


Also notice how the named parameters were passed as pairs :xxx(yyy) when 
calling Fib. The = sign was not used.


Also no need to use an explicit return, because the value of a block is 
the value of the last line in the block, which in the Fib sub is 
truncated gather.


There is probably a shorter way. But the fundamental thing is the way to 
code the Fibonacci sequence.


Hope this helps.


Richard

On 12/12/2013 11:05 AM, Jacinta Richardson wrote:

G'day folk,

I'm slowing working through some basic exercises to get a feel for 
Perl 6.  I'm currently trying to create a fibonacci sequence stopping 
at a maximum value, or a set number of terms...


I've written this:

use v6;

sub MAIN($terms = 35, $maximum = 4_000_000) {
my @sequence = gather for fibonacci($maximum) -> $number {
state $count = 0;
take $number if $number < $maximum && $count++ < $terms;
};

say @sequence;
}

sub fibonacci($maximum) {
   my @numbers := 0, 1, *+* ... * < $maximum;
   return @numbers;
}

with the sequence generator kindly inspired by 
http://justrakudoit.wordpress.com/2010/12/29/perl-6-fibonacci-versus-haskell/ 
but I can't get this to compile.  The syntax highlighter is telling me 
something's wrong because say @sequence is all blue, instead of say 
appearing as a keyword, and the compiler says


===SORRY!===
Confused at line 19, near "}\n\nsub fib"

It's obvious I've done something wrong, but I just can't work out what 
it is.  Can someone show me that which will be more obvious to me when 
I know more Perl 6?


Thanks,

Jacinta





Re: Gather, take, newbie questions

2013-12-11 Thread Larry Wall
On Thu, Dec 12, 2013 at 02:05:35PM +1100, Jacinta Richardson wrote:
:sub MAIN($terms = 35, $maximum = 4_000_000) {
: my @sequence = gather for fibonacci($maximum) -> $number {
: state $count = 0;
: take $number if $number < $maximum && $count++ < $terms;
: };
: 
: say @sequence;
:}
: 
:sub fibonacci($maximum) {
:my @numbers := 0, 1, *+* ... * < $maximum;
:return @numbers;
:}

Your main problem here is that your series is terminated backwards.
The ... runs until the right side matches, and and 0 < $maximum,
so it terminates on 0.  So you want * > $maximum.  You can also use a ^
to exclude the last value whwere it becomes true, so you can just say

0, 1, *+* ...^ * > $maximum

and then you don't have to put in the extra check in your loop.

But you don't really need the loop either.  A more succinct way to
pick the first N terms is to use slice subscripting to pick out the 0th
to the $term'th - 1 element (again, using ^ to exclude the final value):

say (0, 1, *+* ...^ * > $maximum)[0 ..^ $terms];

We also often like to abbreviate 0 ..^ $terms down to ^$terms like this

say (0, 1, *+* ...^ * > $maximum)[^$terms];

But usually we just limit it by number of terms, and don't care about the
maximum:

say (0, 1, *+* ... *)[^$terms];

Hope this helps...

Larry


Re: Gather, take, newbie questions

2013-12-11 Thread David Warring
Hi Jacinta,
I get a bit further with my build of Perl 6, which at least runs:

% perl6 fib.pl
0

Are you maybe using an old Perl6? Try:

% perl6 -e'say $*PERL'

("name" => "rakudo", "compiler" => {"name" => "rakudo", "ver" =>
"2013.11-22-g262e600", "release-number" => "", "build-date" =>
"2013-12-05T22:52:45Z", "codename" => ""}).hash


> ===SORRY!===
> Confused at line 19, near "}\n\nsub fib"
>

- David


Gather, take, newbie questions

2013-12-11 Thread Jacinta Richardson

G'day folk,

I'm slowing working through some basic exercises to get a feel for Perl 
6.  I'm currently trying to create a fibonacci sequence stopping at a 
maximum value, or a set number of terms...


I've written this:

   use v6;

   sub MAIN($terms = 35, $maximum = 4_000_000) {
my @sequence = gather for fibonacci($maximum) -> $number {
state $count = 0;
take $number if $number < $maximum && $count++ < $terms;
};

say @sequence;
   }

   sub fibonacci($maximum) {
   my @numbers := 0, 1, *+* ... * < $maximum;
   return @numbers;
   }

with the sequence generator kindly inspired by 
http://justrakudoit.wordpress.com/2010/12/29/perl-6-fibonacci-versus-haskell/ 
but I can't get this to compile.  The syntax highlighter is telling me 
something's wrong because say @sequence is all blue, instead of say 
appearing as a keyword, and the compiler says


===SORRY!===
Confused at line 19, near "}\n\nsub fib"

It's obvious I've done something wrong, but I just can't work out what 
it is.  Can someone show me that which will be more obvious to me when I 
know more Perl 6?


Thanks,

Jacinta