Re: How to make a new operator.
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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
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.
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