Re: How to make a new operator.

2012-03-22 Thread Daniel Carrera
On 22 March 2012 04:59, Jonathan Lang datawea...@gmail.com wrote:
 My understanding is if you want to count by threes, starting at 2 and ending 
 at 14, you should be able to write:

   2, 5 ... 14

That certainly looks very intuitive, and it is similar to what I would
write in an email. The only annoyance is that I have to do a bit of
mental arithmetic. But I guess that's ok. Especially since most of the
time you'd probably want to write 2,5...* anyway.

 So:

    1, 3 ... 13 # same as 1,3,5,7,9,11,13
    1 ... 10 # same as 1,2,3,4,5,6,7,8,9,10
    1, 2, 4 ... 100 # same as 1,2,4,8,16,32,64


That last one doesn't work on Rakudo :-(

 Meanwhile, using Whatever for the test condition means keep the series going 
 indefinitely:

    1, 3 ... * # every positive odd number.
    1 ... * # all counting numbers.
    1, 2, 4 ... * # all powers of 2.


Yeah, and those are very convenient.


 And using '...^' instead of '...' changes the default final test condition 
 from ' $n' to '= $n':

    1, 3 ...^ 13 # same as 1,3,5,7,9,11
    1 ...^ 10 # same as 1,2,3,4,5,6,7,8,9
    1, 2, 4 ...^ 100 # same as 1,2,4,8,16,32,64


Ok. I hadn't thought of doing that.


 In short, what Damian is talking about is the more powerful and reliable use 
 of the syntax; but the above approach (assuming it has been properly 
 implemented) is a more intuitive use that covers the most common cases.  Make 
 common things easy, and make uncommon things possible.


Yeah.


 Likewise, using Whatever in conjunction with operators is there to provide an 
 intuitive way to calculate the next term from the previous one(s):

    1, *+2 ... 13 # start at 1, step by 2s, stop at 13.
    1, 1, *+* ... * # each new term is the sum of the previous two.

Oh! That second one is cool. a one line implementation of the
Fibonacci sequence.

Cheers,
Daniel.
-- 
I'm not overweight, I'm undertall.


Re: How to make a new operator.

2012-03-22 Thread Carl Mäsak
Jonathan Lang (), Daniel ():
 So:

    1, 3 ... 13 # same as 1,3,5,7,9,11,13
    1 ... 10 # same as 1,2,3,4,5,6,7,8,9,10
    1, 2, 4 ... 100 # same as 1,2,4,8,16,32,64

 That last one doesn't work on Rakudo :-(

And it never will. Note that 100 is not a power of 2, and that the
goal needs to match exactly. This is because smartmatching is used,
not some other comparison. The sequence will continue to generate
numbers until the number 100 is generated, which never happens. Rakudo
loops forever on this one, as per spec.

If you're wondering why things are factored in this way, it's because
previous versions of the spec that tried to special-case 100 to work
in cases like the above, ended up not working out. It turned out that
the unification of infix:... and smartmatching was what did work. It
has the slight drawback that we have to educate users to write * =
100 instead of 100 in the case of not-exactly-matching goal states.
But it's still a net win, because this unified semantics works better
than anything we had before.

// Carl


Re: How to make a new operator.

2012-03-22 Thread Daniel Carrera
On 22 March 2012 11:02, Carl Mäsak cma...@gmail.com wrote:
    1, 2, 4 ... 100 # same as 1,2,4,8,16,32,64

 That last one doesn't work on Rakudo :-(

 And it never will. Note that 100 is not a power of 2, and that the
 goal needs to match exactly. This is because smartmatching is used,
...
 If you're wondering why things are factored in this way, it's because
 previous versions of the spec that tried to special-case 100 to work
 in cases like the above, ended up not working out. It turned out that
 the unification of infix:... and smartmatching was what did work. It
 has the slight drawback that we have to educate users to write * =
 100 instead of 100 in the case of not-exactly-matching goal states.
 But it's still a net win, because this unified semantics works better
 than anything we had before.

But that's a bit of a problem if I *don't* want a value higher than 100.

 2,4,8... * = 100
2 4 8 16 32 64 128

There is no simple formula I can use at the end to get the sequence to
stop where I want. So I have to do something like:

my @a = 2,4,8... * = 100;
@a.pop
# Use @a


Cheers,
Daniel.
-- 
I'm not overweight, I'm undertall.


Re: How to make a new operator.

2012-03-22 Thread Moritz Lenz


On 03/22/2012 11:51 AM, Daniel Carrera wrote:
 On 22 March 2012 11:02, Carl Mäsak cma...@gmail.com wrote:
1, 2, 4 ... 100 # same as 1,2,4,8,16,32,64

 That last one doesn't work on Rakudo :-(

 And it never will. Note that 100 is not a power of 2, and that the
 goal needs to match exactly. This is because smartmatching is used,
 ...
 If you're wondering why things are factored in this way, it's because
 previous versions of the spec that tried to special-case 100 to work
 in cases like the above, ended up not working out. It turned out that
 the unification of infix:... and smartmatching was what did work. It
 has the slight drawback that we have to educate users to write * =
 100 instead of 100 in the case of not-exactly-matching goal states.
 But it's still a net win, because this unified semantics works better
 than anything we had before.
 
 But that's a bit of a problem if I *don't* want a value higher than 100.

Then exclude it: 2, 4, 8 ...^ *  100

Cheers,
Moritz


Re: How to make a new operator.

2012-03-22 Thread Daniel Carrera
On 22 March 2012 12:06, Moritz Lenz mor...@faui2k3.org wrote:

 But that's a bit of a problem if I *don't* want a value higher than 100.

 Then exclude it: 2, 4, 8 ...^ *  100

Ok...  I looked up what you did. I see how it works. Thanks.


Related questions:  What types of sequences can Perl 6 recognize?


-- 
I'm not overweight, I'm undertall.


Re: How to make a new operator.

2012-03-22 Thread Carl Mäsak
Daniel ():
 Related questions:  What types of sequences can Perl 6 recognize?

As covered by Jonathan Lang earlier in this thread (though it was
perhaps easy to miss), Perl 6 auto-detects arithmetic sequences (same
additive difference each time) and geometric sequences (same
multiplicative factor applied each time). Two terms are enough to seed
the first kind; three terms are necessary for the second kind.

If you supply three terms that follow neither an arithmetic or a
geometric sequence (and doesn't contain a Callable as its last term),
Perl 6 throws up its hands and doesn't try to guess.

If you ask me, auto-detecting arithmetic and geometric sequences, but
nothing else, is pretty much the sweet spot. We don't want to put more
in CORE. The one that comes up most often as a suggested addition is
the sequence of primes. Mostly just to mess with people who try it.
:-)

// Carl


Re: How to make a new operator.

2012-03-22 Thread Bruce Gray

On Mar 21, 2012, at 11:49 PM, Jonathan Lang wrote:

What I want to know is whether there's a way to define a step  
function that's based in part or in whole on the current term's  
index.  For example, how would I use infix:... to generate the  
perfect squares between 0 and 100?  Namely,  
'0,1,4,9,16,25,36,49,64,81,100'.  For example, is Perl 6 set up to  
try to pass the current element's index into the step function by  
means of a named parameter?


I would hope for something like:

  - :index { $index * $index } ... 100

or

  1, *+:index ... * # 1,3,6,10,15,21,28,36,45,...

(Note: I _don't_ expect the above to work as is; they're merely  
intended to convey a rough idea of what I _do_ want.)


If not, how _would_ I generate these lists?



In real life, you would just use this:
   my @squares = map { $_ * $_ }, 0..10;
or, for an infinite list, use a binding instead of an assignment:
   my @squares := map { $_ * $_ }, 0..*;
But you were asking about ... specifically :^)

I have run into the same need for something like :index, while
playing with RosettaCode tasks like Continued_fraction.
Your squares example will be clearer than the RC tasks.

At first, I tried to trick the compiler, by *binding* the list to an
array, then referring to that bound array from within the closure.
   my @squares := 0, { @squares.elems ** 2 } ... *;
This worked, but only as an artifact of the then-current Rakudo
implementation. It is not specced to work, and I was told in
freenode/#perl6 not to rely on that behavior.

On freenode/#perl6, I was pointed to part of the spec that I had  
overlooked.

The sequence operator is defined in S03:
   http://perlcabal.org/syn/S03.html#List_infix_precedence
Buried in its definition is this gem:
   http://perlcabal.org/syn/S03.html#line_1884
   The function may also be slurpy (n-ary), in which case all
   the preceding values are passed in (which means they must
   all be cached by the operator, so performance may suffer,
   and you may find yourself with a space leak).

That means that this will work:
   sub sq_gen (*@a) { @a.elems ** 2 };
   my @squares = 0, sq_gen ... {$_ = 100};
   say ~@squares;
(Note that the asterisk in *@a is mandatory)
or, infinitely:
   sub sq_gen (*@a) { @a.elems ** 2 };
   my @squares := 0, sq_gen ... *;
   say ~@squares[^11];

Great! However, I wanted to do it inline, without a separately-defined  
sub.
If it wasn't for that required asterisk, then I could use a  
placeholder variable to do this:

   my @squares = 0, { @^a.elems ** 2 } ... {$_ = 100};
FAIL! (Niecza)
   Unhandled exception: Nominal type check failed in binding '@a' in  
'ANON'; got Int, needed Positional


The last piece of the puzzle is the arrow sub syntax, more commonly
seen in for loops:
   my @squares = 0, (- *@a { @a.elems ** 2 }) ... {$_ = 100};
Or, more concisely:
   my @squares = 0, - *@a { +@a ** 2 } ... * = 100;

This works!

Well, it works in Niecza. It does not (yet) work in Rakudo:
	15:25 Util perl6: my @squares := 0, (- *@a { @a.elems ** 2 }) ...  
*; say ~@squares[^11];
	15:25 p6eval ..niecza v15-4-g1f35f89: OUTPUT0 1 4 9 16 25 36 49  
64 81 100NL

15:25 p6eval ..rakudo 1a468d: OUTPUT0 0 0 0 0 0 0 0 0 0 0NL

For your second example (1,3,6,10,15,21,28,36,45,...), it would look  
like this:

my @triangle = 1, (- *@a { @a[*-1] + @a.elems + 1 }) ... {$_ = 45};
Note that this particular sequence is just the triangle numbers, which
has a shorter form via triangular reduce:
   my @triangle = [\+] 1..9;

After writing all the above, it occurred to me that the use of @_ should
implicitly define a closure as slurpy/n-ary. That would remove the need
for the arrow, and make the code much less ugly.
Also, the first value (0) might be unnecessary. The spec says that it
should not be required when the closure is 0-ary, but I think that
should also be true for slurpy/n-ary closures.
These work in Niecza:

my @squares := { @_ ** 2 } ... *;

my @triangle := 1, { @_[*-1] + @_ + 1 } ... *;

--
Hope this helps,
Bruce Gray
(Util of PerlMonks)



Re: How to make a new operator.

2012-03-22 Thread Jon Lang
On Thu, Mar 22, 2012 at 9:07 AM, Bruce Gray bruce.g...@acm.org wrote:

 On Mar 21, 2012, at 11:49 PM, Jonathan Lang wrote:

  What I want to know is whether there's a way to define a step function
 that's based in part or in whole on the current term's index.  For example,
 how would I use infix:... to generate the perfect squares between 0 and
 100?  Namely, '0,1,4,9,16,25,36,49,64,81,**100'.  For example, is Perl 6
 set up to try to pass the current element's index into the step function by
 means of a named parameter?

 I would hope for something like:

  - :index { $index * $index } ... 100

 or

  1, *+:index ... * # 1,3,6,10,15,21,28,36,45,...

 (Note: I _don't_ expect the above to work as is; they're merely intended
 to convey a rough idea of what I _do_ want.)

 If not, how _would_ I generate these lists?



 In real life, you would just use this:
   my @squares = map { $_ * $_ }, 0..10;
 or, for an infinite list, use a binding instead of an assignment:
   my @squares := map { $_ * $_ }, 0..*;


True enough.


 But you were asking about ... specifically :^)


Yes, I was.


 On freenode/#perl6, I was pointed to part of the spec that I had
 overlooked.
 The sequence operator is defined in S03:
   
 http://perlcabal.org/syn/S03.**html#List_infix_precedencehttp://perlcabal.org/syn/S03.html#List_infix_precedence
 Buried in its definition is this gem:
   
 http://perlcabal.org/syn/S03.**html#line_1884http://perlcabal.org/syn/S03.html#line_1884
   The function may also be slurpy (n-ary), in which case all
   the preceding values are passed in (which means they must
   all be cached by the operator, so performance may suffer,
   and you may find yourself with a space leak).


Interesting; it never occurred to me to try to retrieve the current index
by slurping in all of the previous elements and counting them.


 After writing all the above, it occurred to me that the use of @_ should
 implicitly define a closure as slurpy/n-ary. That would remove the need
 for the arrow, and make the code much less ugly.
 Also, the first value (0) might be unnecessary. The spec says that it
 should not be required when the closure is 0-ary, but I think that
 should also be true for slurpy/n-ary closures.


Agreed: starting values should only be mandatory when dealing with a step
function that definitely requires them.


 These work in Niecza:

my @squares := { @_ ** 2 } ... *;


And this is rather elegant, syntactically (though not so much in the
performance department).

-- 
Jonathan Dataweaver Lang


Re: How to make a new operator.

2012-03-22 Thread Moritz Lenz

Am 22.03.2012 17:07, schrieb Bruce Gray:

I have run into the same need for something like :index, while
playing with RosettaCode tasks like Continued_fraction.


If you want the index, don't use series. It's easy enough to access the 
array elements yourself. You can do something like


my @a := (1..*).map: - $i {
$i ** 2 + @a[$i - 1] // 0;
};

to access previous elements.  You can even use 'last' inside the map 
block to get out of the loop.




Well, it works in Niecza. It does not (yet) work in Rakudo:
15:25 Util perl6: my @squares := 0, (- *@a { @a.elems ** 2 }) ... *;
say ~@squares[^11];
15:25 p6eval ..niecza v15-4-g1f35f89: OUTPUT0 1 4 9 16 25 36 49 64
81 100NL
15:25 p6eval ..rakudo 1a468d: OUTPUT0 0 0 0 0 0 0 0 0 0 0NL


higher-arity sequences are a known regression in rakudo, 
S03-sequence/limit-arity-2-or-more.t currently isn't run.




After writing all the above, it occurred to me that the use of @_ should
implicitly define a closure as slurpy/n-ary.


It shouldn't only, it does already (in all rakudo pugs niecza).
The future is already here, it's just unevenly distributed.


Cheers,
Moritz


N-dimensional arrays and compiler support

2012-03-22 Thread Daniel Carrera
Hey,

I have a few slightly related questions:

1. The semicolon operator would allow Perl 6 to support N-dimensional
arrays... How would one iterate over that type of array?

my num @matrix[ 10 ; 10 ; 10 ];

I ask because a natural extension is to add arithmetic operators and
you have the beginnings of a Matlab-like array language.

2. Do you think Rakudo is likely to get support for N-dimensional
arrays in... say... the next year or so?

3. Does anyone here know much about Niecza? Can you compare it with
Rakudo? I am already familiar with the feature support page
(http://perl6.org/compilers/features) so I am leaving the question
intentionally vague. I'd be interested in anything that you think is
interesting (e.g. speed, development style, progress, whatever).

Cheers,
Daniel.
-- 
I'm not overweight, I'm undertall.


Re: How to make a new operator.

2012-03-22 Thread Martin D Kealey
On Thu, 22 Mar 2012, Carl Mäsak wrote:
 Jonathan Lang (), Daniel ():
     1, 2, 4 ... 100 # same as 1,2,4,8,16,32,64
 
  That last one doesn't work on Rakudo :-(

 And it never will. Note that 100 is not a power of 2, and that the goal
 needs to match exactly. This is because smartmatching is used, not some
 other comparison. The sequence will continue to generate numbers until the
 number 100 is generated, which never happens. Rakudo loops forever on this
 one, as per spec.

Hmmm, so it's likely that most times you get a Num rather than an Int or
Rat, those won't stop either?

1, 7 / 6.0 ... 2
1, sqrt(2), 2 ... 8

Question: do we support

1, 2i, -4 ... 256

 If you're wondering why things are factored in this way, it's because
 previous versions of the spec that tried to special-case 100 to work in
 cases like the above, ended up not working out. It turned out that the
 unification of infix:... and smartmatching was what did work. It has the
 slight drawback that we have to educate users to write * = 100 instead of
 100 in the case of not-exactly-matching goal states. But it's still a net
 win, because this unified semantics works better than anything we had
 before.

Sounds to me like AscendingArithmeticIteratorInclusiveTerminalSmartMatch
could do the same thing as normal SmartMatch except when the LHS is an
IteratorOf{X} and the RHS is an {X}, for X in {Int, Rat, Num} and possibly
other comparable (orderable) types, when  would be implied.

Likewise for AscendingArithmeticIteratorExclusiveTerminalSmartMatch (=)
DescendingArithmeticIteratorInclusiveTerminalSmartMatch () and
DescendingArithmeticIteratorExclusiveTerminalSmartMatch (=).

-Martin


Re: N-dimensional arrays and compiler support

2012-03-22 Thread Stefan O'Rear
On Thu, Mar 22, 2012 at 11:14:54PM +0100, Daniel Carrera wrote:
 Hey,

 I have a few slightly related questions:

 1. The semicolon operator would allow Perl 6 to support N-dimensional
 arrays... How would one iterate over that type of array?
 
 my num @matrix[ 10 ; 10 ; 10 ];

 I ask because a natural extension is to add arithmetic operators and
 you have the beginnings of a Matlab-like array language.

I've started trying to implement S09 things this month, and this is
actually one of the big questions that came up for me.  I raised it
on IRC earlier (which is much more active than p6l, fwiw) and I don't
think we actually arrived at a definite answer.

There are three obvious choices for what 'for @matrix { }' means:

* Iterate over slices that fix the leftmost index

* Iterate over all elements in lexicographic order

* Die

I'm currently thinking of the first, because it allows
(map {$_}, @matrix)[0] to mean the same thing as @matrix[0].  But it's
likely there are other nice considerations.

 2. Do you think Rakudo is likely to get support for N-dimensional
 arrays in... say... the next year or so?

No comment.  If pmichaud stays alive and well, anything is possible.

 3. Does anyone here know much about Niecza? Can you compare it with
 Rakudo? I am already familiar with the feature support page
 (http://perl6.org/compilers/features) so I am leaving the question
 intentionally vague. I'd be interested in anything that you think is
 interesting (e.g. speed, development style, progress, whatever).

For some reason it's much less suprising; I almost never have to guess
what niecza will do with a given piece of code.

Seriously, relative to Rakudo:

Performance: Uses less memory, compiles comparably fast, used to
be much faster at runtime but the gap has narrowed considerably.

Platform: Rakudo/Parrot requires a system with a C89 compiler and a
sufficiently 386-like processor (in particular, it wants a flat address
space and equal size code and data pointers).  Niecza requires a CLR
implementation (developed on Mono, tested on Microsoft .NET).

Rakudo can use C libraries, Niecza can use CLR libraries.

Features: Idiosyncratic variance.  Niecza is still generally ahead on
regex support and a few other odds and ends.  Rakudo currently has the
edge on macros, list behavior, native types, the MOP, and working
libraries.

 Cheers,
 Daniel.

-Stefan



signature.asc
Description: Digital signature


Re: How to make a new operator.

2012-03-22 Thread Patrick R. Michaud
On Fri, Mar 23, 2012 at 03:03:09PM +1300, Martin D Kealey wrote:
 On Thu, 22 Mar 2012, Carl Mäsak wrote:
  Jonathan Lang (), Daniel ():
      1, 2, 4 ... 100 # same as 1,2,4,8,16,32,64
  
   That last one doesn't work on Rakudo :-(
 
  And it never will. Note that 100 is not a power of 2, and that the goal
  needs to match exactly. 
 
 Hmmm, so it's likely that most times you get a Num rather than an Int or
 Rat, those won't stop either?
 
   1, 7 / 6.0 ... 2
   1, sqrt(2), 2 ... 8

The expression 7/6.0 produces a Rat, so the first sequence properly 
stops at 2.

On Rakudo on my system, sqrt(2) indeed produces a Num,
but since floating point arithmetic doesn't result in
sqrt(2) / 1 == 2 / sqrt(2), no geometric sequence is deduced 
and the sequence fails with unable to deduce sequence.

 Question: do we support
 
   1, 2i, -4 ... 256

I think this ought to work, but for some reason Rakudo on my system
hangs whenever I try it.  The following does work in Rakudo:

 say 1, { $^x * 2i } ... 256
1 0+2i -4+0i -0-8i 16+-0i 0+32i -64+0i -0-128i 256+-0i

The fact that the auto-deduced sequence hangs probably needs to be
filed as a bug report for Rakudo.

Pm