Rakudo Hacking: Pairs and Refinement Types

JonathanWorthington on 2008-03-28T00:16:23

First off, sorry it's been a while since I last posted. It's mostly been that I've just not done a lot between the Ukrainian and Dutch Perl Workshops and now, which was thanks to being busy with $REAL_LIFE and lacking either time or brain cycles for hacking Rakudo. Thankfully, I'm back into the swing of things now, and it's time to catch up on the blogging.

I'd like to give a belated thanks to everyone at the UPW and DPW for such a good time. I greatly enjoyed attending, meeting people and speaking at both workshops, and Kiev was a more beautiful city than I had imagined it being. The cathedrals and churches there are incredible - I'll surely be coming back to Ukraine to explore some more!

At UPW, some deficiencies in smart matching of arrays was discovered in Rakudo and I promised a fix. I also said I'd write a note about it here "soon", which I failed to do - sorry. I thought I had fixed array comparison with smart match, but that appears not to be working right now. :-( Also, the Perl 5 and Perl 6 way of checking if a list contains an element are different, and the Perl 6 way was dependent on something else that wasn't implemented (though I've started work on it now, so hopefully we have that soon too). Anyway, it's on the horizon.

I'm hazy on exactly what I got done at DPW and around there, but I know I started on pairs. Thanks to some extra contributions from cognominal++, quite a lot of this is now implemented. As specifying named parameters in a sub was already done, happily it means you can now do things like:

sub sayit (:$what) { say $what; }
sayit(what => "Oo minya pivo!");
Oo minya pivo!

It also works with object instantiation too.

class Foo { has $.a }
my $x = Foo.new(a => 42); say $x.a;
42

As well as the fat arrow syntax, there's also the colon pair syntax, in various forms (we ain't got 'em all yet, but the most useful ones are there).

sayit(:what);
1
sayit(:!what);
0
sayit(:what('privyet'));
privyet
my $what = 'nyam'; sayit(:$what);
nyam

Another thing I've hacked in some basic support for is the subset keyword, which allows you to write refinement types. You can smart-match against the type name to test if the variable meets that type.

subset Guess where { $_ >= 1 && $_ <= 100 };
if 42 ~~ Guess { say "yes" } else { say "no" }
yes
if 142 ~~ Guess { say "yes" } else { say "no" }
no
if 97 ~~ Guess { say "yes" } else { say "no" }
yes
subset LowGuess of Guess where { $_ <= 50; };
if 42 ~~ LowGuess { say "yes" } else { say "no" }
yes
if 97 ~~ LowGuess { say "yes" } else { say "no" }
no
if 0 ~~ LowGuess { say "yes" } else { say "no" }
no

Hopefully more types related stuff coming soon, amongst various other things. I'll be at the Oslo QA Hackathon, and hope to get plenty of free time there, as well as generally while traveling over the coming weekends.


typo?

fireartist on 2008-03-28T11:56:53

subset Guess where { $_ >= 1 && $_ if 42 ~~ Guess { say "yes" } else { say "no" }
yes
if 142 ~~ Guess { say "yes" } else { say "no" }
no
if 97 ~~ Guess { say "yes" } else { say "no" }
yes
subset LowGuess of Guess where { $_ if 42 ~~ LowGuess { say "yes" } else { say "no" }
yes
if 97 ~~ LowGuess { say "yes" } else { say "no" }
no
if 0 ~~ LowGuess { say "yes" } else { say "no" }
no

Are there some curlies/newlines missing here? I'm having difficulty parsing it. (particularly as I've never come across the subset keyword before :)

Other than that, though - it's nice to see what's happening - thanks!

Re:typo?

tron on 2008-03-28T13:50:53

AFAIK the parentheses around the condition are optional in Perl6. So the lines starting with "if" should be ok.
On the other hand me also thinks that the lines starting with "subset" got mixed up...

Re:typo?

JonathanWorthington on 2008-03-28T19:31:58

I'd not written some angle brackets as HTML entities, which resulted in mangled output. Sorry, and fixed now - thanks for pointing it out!

too much TIMTOWTDI

mpeters on 2008-03-28T15:40:49

I'm generally excited about Perl 6 and what it will be able to do, but I do have one concern. I understand and appreciate TIMTOWTDI because it means I can attack the same problem from different directions which is good. But why so many different ways to pass named parameters to subroutines? Maybe I'm missing something and should go back and read the synopsis (I admit it has been some time) but why so many different syntaxes for the same thing? You're not solving the problem in a different way, you're just using different syntax.

Re:too much TIMTOWTDI

JonathanWorthington on 2008-03-28T19:36:59

There's only really two syntxes: the fat arrow and the colon pair. I think that everyone is familiar with fat arrow so it's good to keep that, but it's not so easily extensible as colon pair to do some of the common special cases. Like, if you have a variable with the same name as the named parameter you want to pass it as, or if you just want to pass a true or false value. For example, when opening a file you can write :r to mean "read access" and it's as if you'd done r => 1, but neater. It would appear that Perl 6 will make quite heavy use of named parameters, so it's just the "common case should have a convenient short representation" thingy, I guess.