Re: Not-so-smart matching (was Re: How to make a new operator.)

2012-03-25 Thread Damian Conway
yary suggested:

> In a situation like this, I reach for a thesaurus

The standout from that list for me is: 'consonance'.
Second favorite is: 'gibe' or 'jibe'.

But the underlying operation is .ACCEPTS(),
so perhaps the operation should be referred to
as "acceptance" or "acceptibility".

Damian


Re: Not-so-smart matching (was Re: How to make a new operator.)

2012-03-25 Thread yary
I also like "agreement", "conformance"... In a situation like this, I
reach for a thesaurus- very useful when looking for just the right
name for a variable/method name/way to describe a concept. Here's a
grab bag to start with:

accord, agree, conformance, conformation, conformity, congruence,
congruity, consensus, consonance, correspondence, harmony, unison
agree, fit, correspond, compeer, meet, gibe, pair, mate, twin, cope with, touch

Fit, correspond, congruity, harmonize seem like other good
descriptions for the concept. Fit is especially good due to its
brevity, and congruence is good due to the use of ~~ as the smartmatch
aka congruence/fitness/agreement/harmonizing/correspondence/conformance
operator.

(Bikeshed?)

-y



On Sun, Mar 25, 2012 at 12:35 AM, David Green  wrote:
> On 2012-March-21, at 6:38 pm, Daniel Carrera wrote:
>> The idea of smart-matching a function just doesn't quite fit with my brain. 
>> I can memorize the fact that smart-matching 7 and &foo means evaluating 
>> foo(7) and seeing if the value is true, but I can't say I "understand" it.
>
> Maybe it just needs a better name.  "Match" implies that two (or more) things 
> are being compared against each other, and that's how smart-matching started 
> out, but it's been generalised beyond that.  The underlying .ACCEPTS method 
> suggests "acceptance"... but that's too broad (a function can "accept" args 
> without returning true).  "Agreement" fits, in the sense of "that [food] 
> agrees with me", but I think it suggests equality a bit too strongly.  
> "Accordance"?  "Conformance"?  "Validation"?  That seems a good match (ahem) 
> for the concept: ~~ checks whether some value is "valid" (or "desired"?) 
> according to certain criteria.  The obvious way to validate some value 
> against a simple string or number is to compare them; or against a pattern, 
> to see if the value matches; but given a function, you check the value by 
> passing it to the function and seeing whether it says yea or nay.
>
> I'm not sure "validation" or "validity" is the best name, but it conforms 
> better to what smart-"matching" does.  Or "conformance"  Hm.  But 
> terminology that sets up the appropriate expectations is a good thing.
>
>
> -David
>


Re: Floating-point equality (was Re: How to make a new operator.)

2012-03-25 Thread Moritz Lenz
On 03/25/2012 06:55 AM, Moritz Lenz wrote:
> I don't know if the majority of the perl6-language posters have realized
> it yet, but both Perl 6 and the its implementations are quite mature
> these days. Mature enough that such proposals should be prototyped as
> modules, and thoroughly tested on lots of existing code before taken
> into consideration for

... inclusion into the spec.

Sometimes I do finish my sentences with several hours delay, sorry for that.

Cheers,
Moritz


Re: How to make a new operator.

2012-03-24 Thread Damian Conway
> At least in #perl6 I've never seen anybody try to write an auto-deduced
> sequence, and fail because of floating-point errors.

Except for Martin's 1, sqrt(2), 2...8

But, yes, the widespread use of Rats rather than Nums
means only the edgiest of edge-cases fails. And as you get
an explicit Failure when it does happen, at least people will
know when the numerical computations don't work as hoped.

Damian


Re: Floating-point equality (was Re: How to make a new operator.)

2012-03-24 Thread Moritz Lenz


On 03/25/2012 05:59 AM, David Green wrote:
> On 2012-March-23, at 12:01 am, Damian Conway wrote:
>> [...] we ought to allow for the inevitable loss of significant digits within 
>> the two preliminary division ops, and therefore compare the results with an 
>> suitably larger epsilon.
>> That would not only be computational more justifiable, I suspect it might 
>> also produce more "least surprise". ;-)
> 
> I think that comparisons for floating-point values should take some kind of 
> 'significance' adverb and complain if it's missing.  Having to be explicit 
> makes for the least surprise of all.
> 
>π == 22/7   # error
>π == 22/7 :within(0.002)# true
>π == 22/7 :within(0.2)  # false

Note that neither 22/7 nor 0.002 are floating-point values.

I don't know if the majority of the perl6-language posters have realized
it yet, but both Perl 6 and the its implementations are quite mature
these days. Mature enough that such proposals should be prototyped as
modules, and thoroughly tested on lots of existing code before taken
into consideration for

Niecza supports operator adverbs, and supports them on user-defined
operators, so there's nothing to stop you from trying it.

Cheers,
Moritz


Re: How to make a new operator.

2012-03-24 Thread Moritz Lenz


On 03/23/2012 09:14 AM, Damian Conway wrote:
>> it means we cannot do the same fuzziness for the endpoint,
> 
> Except that we will be encouraging people to use: * >= $END
> as their standard endpoint pattern, which will provide
> most of the necessary fuzz.

and which will still surprise those people who are surprised
by floating point inaccuracies.

>> This discussion makes me think that maybe
>> deducing geometric sequences is too much magic as well.
> 
> Geometric sequence inference is fine on Ints and Rats.
> 
> But, if we can't perform inferences involving Nums in a sound numerical
> way (and it may well be that we can't, without taking a noticeable
> performance hit), then I think that we would be better off limiting the
> deduction of *both* arithmetic and geometric sequences to starting lists
> that contain only Ints and Rats.

Floating point numbers *can* represent a huge number of commonly used
values without errors, and you can do error-free arithmetic operations
on many of them. Excluding Nums from automatic deduction feels like an
unnecessary pessimization or stigmatization, especially if you consider
that writing a number like 0.001 in your program gives a Rat by default
not a Num.

Most of the time you only get a Num in Perl 6 if you consciously decide
to write one, in which case you should also be well aware of the
limitations of FP math.

At least in #perl6 I've never seen anybody try to write an auto-deduced
sequence, and fail because of floating-point errors.

Cheers,
Moritz


Not-so-smart matching (was Re: How to make a new operator.)

2012-03-24 Thread David Green
On 2012-March-21, at 6:38 pm, Daniel Carrera wrote:
> The idea of smart-matching a function just doesn't quite fit with my brain. I 
> can memorize the fact that smart-matching 7 and &foo means evaluating foo(7) 
> and seeing if the value is true, but I can't say I "understand" it.

Maybe it just needs a better name.  "Match" implies that two (or more) things 
are being compared against each other, and that's how smart-matching started 
out, but it's been generalised beyond that.  The underlying .ACCEPTS method 
suggests "acceptance"... but that's too broad (a function can "accept" args 
without returning true).  "Agreement" fits, in the sense of "that [food] agrees 
with me", but I think it suggests equality a bit too strongly.  "Accordance"?  
"Conformance"?  "Validation"?  That seems a good match (ahem) for the concept: 
~~ checks whether some value is "valid" (or "desired"?) according to certain 
criteria.  The obvious way to validate some value against a simple string or 
number is to compare them; or against a pattern, to see if the value matches; 
but given a function, you check the value by passing it to the function and 
seeing whether it says yea or nay.  

I'm not sure "validation" or "validity" is the best name, but it conforms 
better to what smart-"matching" does.  Or "conformance"  Hm.  But 
terminology that sets up the appropriate expectations is a good thing.


-David



Floating-point equality (was Re: How to make a new operator.)

2012-03-24 Thread David Green
On 2012-March-23, at 12:01 am, Damian Conway wrote:
> [...] we ought to allow for the inevitable loss of significant digits within 
> the two preliminary division ops, and therefore compare the results with an 
> suitably larger epsilon.
> That would not only be computational more justifiable, I suspect it might 
> also produce more "least surprise". ;-)

I think that comparisons for floating-point values should take some kind of 
'significance' adverb and complain if it's missing.  Having to be explicit 
makes for the least surprise of all.

   π == 22/7   # error
   π == 22/7 :within(0.002)# true
   π == 22/7 :within(0.2)  # false

Probably with something like 'use epsilon :within(0.0002)' as way to declare 
the fuzziness for a given scope if you have a lot of comparisons.  And of 
course you could use (the equivalent of) 'use epsilon :within(0)' to say, "I 
know what I'm doing, just give me straight what I ask for and I'll take the 
consequences."

Alternatively, maybe have float-comparisons give an error or warning, and 
introduce an "approximation operator": π == ~22/7 :within($epsilon).  (Except 
"~" is already taken!)


[I was going to suggest that as a way to handle stopping points in a sequence: 
1, 3, 5 ... ~10, but that still wouldn't work without treating the Num::Approx 
values as a special case, which defeats the purpose.  Though with a postfix "up 
from" operator, you could say: 1, 3, 5 ... 10^.]


-David



Re: How to make a new operator.

2012-03-24 Thread Jonathan Lang
On Mar 24, 2012, at 6:36 PM, Stefan O'Rear  wrote:
> On Sat, Mar 24, 2012 at 06:16:58PM -0700, Jonathan Lang wrote:
>> IMHO: if we're going to take loss of precision into account, we should do so 
>> explicitly.  I'm a bit rusty, so forgive me if I misuse the terminology: if 
>> a number has an epsilon, the epsilon should be attached to it as a trait so 
>> that it can be accessed by the program.  This allows all sorts of things, 
>> like "close enough" smart-matching and error propagation.  The main question 
>> is if Perl should assign a minimum epsilon to all floats by default, or if 
>> this should be an "all's fair if you predeclare" type of thing.  
> 
> Speaking as an implementor, I think this is quite unlikely.  Some of my
> reasons:
> 
> 1. Interval arithmetic (this is the correct technical term) is very
>   inefficient on some popular architectures.
> 
> 2. After a long computation which is numerically stable *but which Perl
>   cannot _prove_ the stability of*, error bounds will be very large, and
>   if smart-matching automatically takes them into account, it will tend
>   to result in extremely suprising false positives

I'll concede that these two (especially the second one) are sufficient 
arguments against the "default epsilon" idea, rendering my disagreement on the 
third point largely moot.  That said:

> 3. Adding hidden state to numbers that is not visible by default will make
>   debugging harder.  Not hiding the state will make output much noisier.

That's why I was suggesting making epsilon available as a trait (e.g., 
something like "5 but error(.01)"): if you need it, it would be easy to look it 
up; if you don't need it, it would be easy to ignore it.  

> Larry is free to override this of course.  Also, interval arithmetic ought
> to be possible as a module.

Absolutely, it would be possible as a module.  And with your second point 
above, it ought to be a module, to be explicitly applied when the programmer 
wants to use interval arithmetic.

Re: How to make a new operator.

2012-03-24 Thread Stefan O'Rear
On Sat, Mar 24, 2012 at 06:16:58PM -0700, Jonathan Lang wrote:
> IMHO: if we're going to take loss of precision into account, we should do so 
> explicitly.  I'm a bit rusty, so forgive me if I misuse the terminology: if a 
> number has an epsilon, the epsilon should be attached to it as a trait so 
> that it can be accessed by the program.  This allows all sorts of things, 
> like "close enough" smart-matching and error propagation.  The main question 
> is if Perl should assign a minimum epsilon to all floats by default, or if 
> this should be an "all's fair if you predeclare" type of thing.  

Speaking as an implementor, I think this is quite unlikely.  Some of my
reasons:

1. Interval arithmetic (this is the correct technical term) is very
   inefficient on some popular architectures.

2. After a long computation which is numerically stable *but which Perl
   cannot _prove_ the stability of*, error bounds will be very large, and
   if smart-matching automatically takes them into account, it will tend
   to result in extremely suprising false positives.

3. Adding hidden state to numbers that is not visible by default will make
   debugging harder.  Not hiding the state will make output much noisier.

Larry is free to override this of course.  Also, interval arithmetic ought
to be possible as a module.

-Stefan


signature.asc
Description: Digital signature


Re: How to make a new operator.

2012-03-24 Thread Jonathan Lang
On Mar 24, 2012, at 5:26 PM, Damian Conway  wrote:

>> Actually, that one works fine in both niecza and rakudo, since those are 
>> Rats.
> 
> Oh, that's good to hear.
> 
> It doesn't change my underlying argument however. Any operations
> performed on genuine floats are going to lose precision, and if we're
> using such operations to infer relationships (such as equality or
> sequence) then we ought to take the loss of precision we're causing
> into account when deciding outcomes.
> 
> Which seems to mean either (a) making it a compiletime error to request
> sequence inferences on floats , or (b) comparing the differences and
> quotients within the sequence inference with a larger epsilon (or using
> interval arithmetic).
> 
> Damian

IMHO: if we're going to take loss of precision into account, we should do so 
explicitly.  I'm a bit rusty, so forgive me if I misuse the terminology: if a 
number has an epsilon, the epsilon should be attached to it as a trait so that 
it can be accessed by the program.  This allows all sorts of things, like 
"close enough" smart-matching and error propagation.  The main question is if 
Perl should assign a minimum epsilon to all floats by default, or if this 
should be an "all's fair if you predeclare" type of thing.  

Re: How to make a new operator.

2012-03-24 Thread Damian Conway
> Actually, that one works fine in both niecza and rakudo, since those are Rats.

Oh, that's good to hear.

It doesn't change my underlying argument however. Any operations
performed on genuine floats are going to lose precision, and if we're
using such operations to infer relationships (such as equality or
sequence) then we ought to take the loss of precision we're causing
into account when deciding outcomes.

Which seems to mean either (a) making it a compiletime error to request
sequence inferences on floats , or (b) comparing the differences and
quotients within the sequence inference with a larger epsilon (or using
interval arithmetic).

Damian


Re: How to make a new operator.

2012-03-24 Thread Larry Wall
On Fri, Mar 23, 2012 at 07:14:51PM +1100, Damian Conway wrote:
: For example:
: 
: 1, 1.0001, 1.0002 ... *
: 
: won't deduce a correct arithmetic sequence either (on most hardware).

Actually, that one works fine in both niecza and rakudo, since those are Rats.

Larry


Re: How to make a new operator.

2012-03-23 Thread Patrick R. Michaud
On Thu, Mar 22, 2012 at 11:07:08AM -0500, Bruce Gray wrote:
> Well, it works in Niecza. It does not (yet) work in Rakudo:
>   15:25  perl6: my @squares := 0, (-> *@a { @a.elems ** 2 })
> ... *; say ~@squares[^11];
>   15:25  ..niecza v15-4-g1f35f89: OUTPUT<<0 1 4 9 16 25 36 49
> 64 81 100NL>>
>   15:25  ..rakudo 1a468d: OUTPUT<<0 0 0 0 0 0 0 0 0 0 0NL>>

It now works in Rakudo, as of 2012.03-5-g69920db:

   > my @squares = 0, (-> *@a { @a.elems ** 2 }) ... *; say @squares[^11];
   0 1 4 9 16 25 36 49 64 81 100

Also @_ now DTRT again:

> my @squares = { @_ ** 2 } ... *;  say @squares[^11];
0 1 4 9 16 25 36 49 64 81 100

> my @triangle = 1, { @_[*-1] + @_ + 1 } ... *;  say @triangle[^11]
1 3 6 10 15 21 28 36 45 55 66

Note that Rakudo also doesn't require a binding operation for the array... 
assignment of detectably infinite lists (indicated here by the final 
Whatever term) is supported.

Pm


Re: How to make a new operator.

2012-03-23 Thread Damian Conway
> But unless we twist smartmatching semantics for that purpose,

No!

Please, no.

;-)


> it means we cannot do the same fuzziness for the endpoint,

Except that we will be encouraging people to use: * >= $END
as their standard endpoint pattern, which will provide
most of the necessary fuzz.


> So I'm firmly against such magic.

But that's the point: it's not magic. It's correct numerical computation
under the limitations of floating-point arithmetic. As discussed in
every numerical computing textbook for the last half a century.

Note that this problem occurs for *arithmetic* deductions as well.
If either number is floating point, some loss of precision in the
difference between them is almost inevitable, especially if the two
numbers are very close.

For example:

1, 1.0001, 1.0002 ... *

won't deduce a correct arithmetic sequence either (on most hardware).

In fact that example would be slightly more likely to imply a geometric
sequence, since a division operation loses fewer significant digits than
a subtraction when the arguments are both so close to 1.0)


> This discussion makes me think that maybe
> deducing geometric sequences is too much magic as well.

Geometric sequence inference is fine on Ints and Rats.

But, if we can't perform inferences involving Nums in a sound numerical
way (and it may well be that we can't, without taking a noticeable
performance hit), then I think that we would be better off limiting the
deduction of *both* arithmetic and geometric sequences to starting lists
that contain only Ints and Rats.

Damian


Re: How to make a new operator.

2012-03-22 Thread Moritz Lenz
On 03/23/2012 05:30 AM, Patrick R. Michaud wrote:
> On Fri, Mar 23, 2012 at 03:03:09PM +1300, Martin D Kealey wrote:
>> 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 problem was that infix: hung with Complex numbers, because it
was defined for each numeric type, but the Complex candidate was
missing. Thus the most general candidate called .Numeric on its
arguments, re-dispatched, and looped infinitely.

Fixed in 2012.03-3-g4a247b1, and tested in S32-num/complex.t.
This also fixes the sequence 1, 2i, -4 ... 256.

Cheers,
Moritz


Re: How to make a new operator.

2012-03-22 Thread Moritz Lenz
On 03/23/2012 07:01 AM, Damian Conway wrote:
> Patrick correctly observed:
> 
>> 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".
> 
> Although, arguably, that might be considered a bug.
> 
> Not that sqrt(2) / 1 should == 2 / sqrt(2) of course, but that, when
> deducing a sequence we know we're comparing quotients, so we ought to
> allow for the inevitable loss of significant digits within the two
> preliminary division ops, and therefore compare the results with an
> suitably larger epsilon.
> 
> That would not only be computational more justifiable,
> I suspect it might also produce more "least surprise". ;-)

But unless we twist smartmatching semantics for that purpose, it means
we cannot do the same fuzziness for the endpoint, condemning people to
write infinite loops instead of failing fast.

So I'm firmly against such magic. All the previous iterations of the
sequence operator had some additional degrees of magic, and we've come
to regret all of them. This discussion makes me think that maybe
deducing geometric sequences is too much magic as well.

Cheers,
Moritz


Re: How to make a new operator.

2012-03-22 Thread Damian Conway
Patrick correctly observed:

> 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".

Although, arguably, that might be considered a bug.

Not that sqrt(2) / 1 should == 2 / sqrt(2) of course, but that, when
deducing a sequence we know we're comparing quotients, so we ought to
allow for the inevitable loss of significant digits within the two
preliminary division ops, and therefore compare the results with an
suitably larger epsilon.

That would not only be computational more justifiable,
I suspect it might also produce more "least surprise". ;-)

Damian


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


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: 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  perl6: my @squares := 0, (-> *@a { @a.elems ** 2 }) ... *;
say ~@squares[^11];
15:25  ..niecza v15-4-g1f35f89: OUTPUT<<0 1 4 9 16 25 36 49 64
81 100NL>>
15:25  ..rakudo 1a468d: OUTPUT<<0 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 ).
The future is already here, it's just unevenly distributed.


Cheers,
Moritz


Re: How to make a new operator.

2012-03-22 Thread Jon Lang
On Thu, Mar 22, 2012 at 9:07 AM, Bruce Gray  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_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").
>

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 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  perl6: my @squares := 0, (-> *@a { @a.elems ** 2 }) ...  
*; say ~@squares[^11];
	15:25  ..niecza v15-4-g1f35f89: OUTPUT<<0 1 4 9 16 25 36 49  
64 81 100NL>>

15:25  ..rakudo 1a468d: OUTPUT<<0 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 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 Daniel Carrera
On 22 March 2012 12:06, Moritz Lenz  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 Moritz Lenz


On 03/22/2012 11:51 AM, Daniel Carrera wrote:
> On 22 March 2012 11:02, Carl Mäsak  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 11:02, Carl Mäsak  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 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 04:59, Jonathan Lang  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-21 Thread Jonathan Lang
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?

Re: How to make a new operator.

2012-03-21 Thread Jonathan Lang
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 is, the list-building operator looks at the previous two or three terms 
preceding it to determine where to start and what "step function" to use, and 
then looks at the first term following it to determine where to stop.  The use 
of lambda functions in the immediately preceding and following terms provides a 
means to explicitly define the step function and the test condition, 
respectively; but Perl 6 is supposed to be smart enough to intuit linear step 
functions from two strictly numeric prior terms, geometric step functions from 
three such terms, and a test condition that stops the series at '> $n' from a 
numeric right term.  

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

and

2, 5 ... 14 # same as 2,5,8,11,14

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.

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

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. 

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.
1, 1, &infix:<+> ... * # same as last one.

Re: How to make a new operator.

2012-03-21 Thread Daniel Carrera
On 22 March 2012 01:13, Solomon Foster  wrote:
> It actually smartmatches whatever is on the right hand side against
> the sequence, and stops when the smartmatch returns True.  It just
> "happens" that you smartmatch an anonymous function, it executes the
> function and returns its result.

I see... I still find this a little confusing. The idea of
smart-matching a function just doesn't quite fit with my brain. I can
memorize the fact that smart-matching 7 and &foo means evaluating
foo(7) and seeing if the value is true, but I can't say I "understand"
it.


> Examples:
>
> 2, 5 ... 11 # smartmatch is true when you hit 11
> 2, 5 ... True # stop right away
> 2, 5 ... False # never stop
> 2, 5 ... * # shorter way of saying never stop
> 2, 1, 1/2 ... Num # stop when the number switches from a Rat to a Num
> 'a' ... /f/ # stop when the regular expression matches

Interesting.


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


Re: How to make a new operator.

2012-03-21 Thread Solomon Foster
On Wed, Mar 21, 2012 at 7:52 PM, Daniel Carrera  wrote:
>> * >= $b --- this determines where the sequence ends:  when the current value
>> is greater or equal to $b.
>
> So...  after the "..." you have an anonymous function that has to
> return 'True' for the sequence to end? Seems strange, but it works:
>
> # A "function" that always returns True => List of one item.
>> 2,5...True
> 2

It actually smartmatches whatever is on the right hand side against
the sequence, and stops when the smartmatch returns True.  It just
"happens" that you smartmatch an anonymous function, it executes the
function and returns its result.

In particular, note that True there is not an anonymous function, it's
just the value True.  You'd need to say { True } to get an anonymous
function which returns True.

Examples:

2, 5 ... 11 # smartmatch is true when you hit 11
2, 5 ... True # stop right away
2, 5 ... False # never stop
2, 5 ... * # shorter way of saying never stop
2, 1, 1/2 ... Num # stop when the number switches from a Rat to a Num
'a' ... /f/ # stop when the regular expression matches

-- 
Solomon Foster: colo...@gmail.com
HarmonyWare, Inc: http://www.harmonyware.com


Re: How to make a new operator.

2012-03-21 Thread Daniel Carrera
On 22 March 2012 00:08, Brandon Allbery  wrote:

> * + $c --- the next value is the current value plus $c.  ("*" means
> "Whatever", and generally refers to the current value of something.  In this
> case, we're specifying how to make a new value given a current value.  You
> can think of it as a way to make an anonymous function.  In Haskell this
> would be "(+ c)" or "\x -> x + c"; in Python, "lambda x: x + c"; in Perl 5,
> "sub {$_[0] + $c}".  The meaning of * is context dependent, though; when
> accessing array elements, for example, * refers to the end of the array, so
> @arr[* - 1] means the second last element of @arr.)


Interesting... a lambda expression...

> my &add3 = * + 3
WhateverCode.new()
>
> add3(2)
5


Cool... this actually works... But I notice that to use 'add3' in the
list construction I need to put an ampersand:

> 2, &add3 ... 14
2 5 8 11 14


Still... the fact that this works is neat.



> * >= $b --- this determines where the sequence ends:  when the current value
> is greater or equal to $b.


So...  after the "..." you have an anonymous function that has to
return 'True' for the sequence to end? Seems strange, but it works:

# A "function" that always returns True => List of one item.
> 2,5...True
2


So if I want to go from $a to $b by steps of $c, the correct recipe would be:

$a, *+$c ... * >= $b - $c

With this information, I can write something like this:

sub infix:<|>( Range $r, Int $c ) {
my ($a, $b) = $r.bounds;
return $a, *+$c ... * >= $b - $c
}

(2..10)|3   == 2, 5, 8

This would look better if I removed the parenthesis, but I'm having
trouble telling Rakudo that this infix operator is looser than the ..
operator:

sub infix:<|>( Range $r, Int $c ) is looser( &infix:<..> ) {
...
}
No applicable candidates found to dispatch to for 'trait_mod:'.



> haral:6704 Z$ ./perl6 -e 'say (2, 4 ... 10).^methods'

Thanks. That's very useful.

> The .^ operator runs a method on the object's "metaobject", which determines
> how it associates with its class and roles.  The metaobject is available via
> the HOW method, but is not something you can print or etc.; working with it
> directly is somewhat painful, which is why .^ exists.

Ok.


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


Re: How to make a new operator.

2012-03-21 Thread Damian Conway
> Ok, so infix:<...> isn't what I wish for either... Can you help me
> understand Damian's example?


Breaking down that example:

$a,  # Start at $a
*+$c # Generate next number via: sub($prev_num} { $prev_num + $c }
...  # Repeat until...
* >=$b   # ...this sub matches: sub($prev_num) { $prev_num >= $b }

* used as an argument to an operator is a shorthand for constructing
subroutines,
where the * represents the subroutine's argument.


Damian


Re: How to make a new operator.

2012-03-21 Thread Daniel Carrera
On 21 March 2012 22:50, Carl Mäsak  wrote:
> It would also produce an infinite list, because by the rules you need
> the RHS of infix:<...> to match exactly, and 10 is not in the infinite
> list 2, 5, 8, 11, 14... Which is why you'd need to write something
> like * >= 10.

Ok, so infix:<...> isn't what I wish for either... Can you help me
understand Damian's example?

$a,*+$c...* >=$b


I see a lot of Perl magic here and I have no idea what any of it does.
What does the first star do? And the plus sign?

I tried to guess what the >= does by experimentation, but I can't make
heads or tails of it:

> 2..100 >= 5
True
>
> 2...100 >= 5
2

Also, I'm only now learning what ... does. I thought it was just the
"yada yada yada" operator, but now I see that it makes an object
called List(), which clearly is different from both Range() and
Array()...

Btw, I just found the section in S09 covering multi-dimensional arrays
and the semicolon operator. I'll go read it now...

One unrelated question: Is there a way to ask an object what methods
it supports? That would make it easier for me to experiment. For
example, just now I have been looking for the methods supported by the
Range object (to see how I'd obtain the beginning and end points of a
range) and haven't found anything.

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


Re: How to make a new operator.

2012-03-21 Thread Damian Conway
> Interesting... but it doesn't seem to work in Rakudo Star (2012.02):
>
>> @(2,5..10)

You need three dots, not two.

Damian


Re: How to make a new operator.

2012-03-21 Thread Carl Mäsak
Damian (>>), Daniel (>):
>> Perl 6 already has:  0,$c...*
>>
>> e.g. 0,3...* > 0, 3, 6, 9, 12
>
> Interesting... but it doesn't seem to work in Rakudo Star (2012.02):
>
>> @(2,5..10)
> 2 5 6 7 8 9 10
>
> :-(

Keep in mind that infix:<..> will listify to the kind of
one-step-at-a-time range that was produced above, whereas infix:<...>
is its more DWIMmy cousin and would take the above as counting three
steps at a time.

It would also produce an infinite list, because by the rules you need
the RHS of infix:<...> to match exactly, and 10 is not in the infinite
list 2, 5, 8, 11, 14... Which is why you'd need to write something
like * >= 10.

// Carl


Re: How to make a new operator.

2012-03-21 Thread Daniel Carrera
On 21 March 2012 22:09, Damian Conway  wrote:
>> Is it possible to create a new range operator ':' such that:
>
> Do you need to?

Hmm... maybe not...

>> a:b:c is a range from 'a' to 'b' by steps of 'c'.
>
> Perl 6 already has: $a,*+$c...* >=$b
>
> E.g. 2, 5 ...^ *>=15  > 2,5,8,11,14


That looks really scary.  I'll try to figure out what it means later.


> Perl 6 already has ^$b
> Perl 6 already has $a..* or $a...*
> Perl 6 already has: ^Inf > 0,1,2,3,4,5,

Ok... I think can use that.

I want to write a simple class for numerical computation. Mostly
because I don't like NumPy, PDL or Octave/Matlab. When I wrote my
email I was thinking of slices:

@matrix[2..5][3..7]
@matrix[2..5][*]
@matrix[5..*][^3]

I guess that's alright. It doesn't seem to be worth the effort in
adding new syntax.

I'm having trouble getting this to work with Rakudo Star (2012.02) though...


> my @a = \[1,2,3,4,5], \[6,7,8,9,0]
1 2 3 4 5 6 7 8 9 0
>
> @a[0]
1 2 3 4 5
>
> @a[0].WHAT
Capture()
>
> @a[0][2]
Any()


:-(

> Perl 6 already has:  0,$c...*
>
> e.g. 0,3...* > 0, 3, 6, 9, 12

Interesting... but it doesn't seem to work in Rakudo Star (2012.02):

> @(2,5..10)
2 5 6 7 8 9 10

:-(


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


Re: How to make a new operator.

2012-03-21 Thread Carl Mäsak
Daniel (>>), Damian (>):
>> : is the same as 0..Inf
>
> Perl 6 already has: ^Inf > 0,1,2,3,4,5,

Hah, Damian made an off-by-one error! Oh wait...

// Carl


Re: How to make a new operator.

2012-03-21 Thread Damian Conway
> Is it possible to create a new range operator ':' such that:

Do you need to?


> a:b:c is a range from 'a' to 'b' by steps of 'c'.

Perl 6 already has: $a,*+$c...* >=$b

E.g. 2, 5 ...^ *>=15  > 2,5,8,11,14


> :b is the same as 0..b

Perl 6 already has ^$b

e,g, ^100 > 0..99


> a: is the same as a..Inf

Perl 6 already has $a..* or $a...*

e.g. 3..* > 3,4,5,6,


> ::c is the same as 0:Inf:c

Perl 6 already has:  0,$c...*

e.g. 0,3...* > 0, 3, 6, 9, 12


> : is the same as 0..Inf

Perl 6 already has: ^Inf > 0,1,2,3,4,5,


Damian


Re: How to make a new operator.

2012-03-21 Thread Daniel Carrera
Hi Moritz

>> a:b is the same as a..b  (this is the easy part)
>>
>> a:b:c is a range from 'a' to 'b' by steps of 'c'. For example, 2:15:3
>> == 2,5,8,11,14
>
> That can be done by giving the new infix:<:> operator list associativity
> (niecza already supports this)

Can you explain or give me a link that explains how to do that? I can
figure out a little bit on my own:

multi sub infix:<:>( Int $a, Int $b ) {
 #  This is the case 'a:b'
}

multi sub infix:<:>( Range $a, Int $b ) {
 #  Is this correct?
 #  I'm thinking that a:b:c could be interpreted as (a:b):c so it
is "Range" : "Int".
 # Am I on the right track?
}


>> :b is the same as 0..b
>
> create a new prefix operator... except that that prefix : is already
> taken for constructing pairs

Ok. I hadn't realized that you could define the same symbol as prefix,
infix and postfix... So.. ignoring the fact that : conflicts with
existing syntax, I could do this:

multi sub infix:<:>( Int $a, Int $b )  { ... }
multi sub infix:<:>( Range $a, Int $b ) { ... }
multi sub prefix:<:>( Int $a ) { ... }
multi sub postfix:<:>( Int $b ) { ... }

Right?

>> : is the same as 0..Inf
>
> create a term:<:>.

Ok.


> There are hooks for all of that, but it requires you to come up with a
> new syntax that doesn't collide heads-on with lots of existing grammar
> rules.

Thanks. I'll see if I think of something that feels natural but
doesn't collide with anything. One option is to just use the existing
.. operator:

multi sub prefix:<..>( Int $b ) { 0..$b }
multi sub postfix:<..>( Int $a ) { $a..Inf }

Only problem is that something like "2..10..3" might be confusing.

Hmm... I must have made a mistake here somewhere... After defining
these functions, the traditional range '2..10' doesn't work anymore. I
suppose that my new functions have a higher precedence than the
traditional .. operator. I tried to fix this, but I failed:

multi sub prefix:<..>( Int $b ) is looser(&infix:) { 0..$b }

So, I'm not doing this right.

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


Re: How to make a new operator.

2012-03-21 Thread Moritz Lenz


On 03/21/2012 09:07 PM, Daniel Carrera wrote:
> Hello,
> 
> Is it possible to create a new range operator ':' such that:
> 
> a:b is the same as a..b  (this is the easy part)
> 
> a:b:c is a range from 'a' to 'b' by steps of 'c'. For example, 2:15:3
> == 2,5,8,11,14

That can be done by giving the new infix:<:> operator list associativity
(niecza already supports this)

> :b is the same as 0..b

create a new prefix operator... except that that prefix : is already
taken for constructing pairs

> a: is the same as a..Inf

create a postfix:<:> operator... except that postfix : is already taken
as invocant marker

> ::c is the same as 0:Inf:c

create a prefix:<::> operator. Except that this collides with existing
syntax...

> : is the same as 0..Inf

create a term:<:>.


There are hooks for all of that, but it requires you to come up with a
new syntax that doesn't collide heads-on with lots of existing grammar
rules.

Cheers,
Moritz