Categories
Posts in this category
- A shiny perl6.org site
- Creating an entry point for newcomers
- Sprixel, a 6 compiler powered by JavaScript
- Another perl6.org iteration
- Blackjack and Perl 6
- Why I commit Crud to the Perl 6 Test Suite
- This Week's Contribution to Perl 6 Week 5: Implement Str.trans
- This Week's Contribution to Perl 6
- This Week's Contribution to Perl 6 Week 8: Implement $*ARGFILES for Rakudo
- This Week's Contribution to Perl 6 Week 6: Improve Book markup
- This Week's Contribution to Perl 6 Week 2: Fix up a test
- This Week's Contribution to Perl 6 Week 9: Implement Hash.pick for Rakudo
- This Week's Contribution to Perl 6 - Lottery Intermission
- This Week's Contribution to Perl 6 Week 3: Write supporting code for the MAIN sub
- This Week's Contribution to Perl 6 Week 1: A website for proto
- This Week's Contribution to Perl 6 Week 4: Implement :samecase for .subst
- This Week's Contribution to Perl 6 Week 7: Implement try.rakudo.org
- Report from the Perl 6 Hackathon in Copenhagen
- Custom operators in Rakudo
- A Perl 6 Date Module
- Defined Behaviour with Undefined Values
- Dissecting the "Starry obfu"
- The case for distributed version control systems
- Perl 6: Failing Softly with Unthrown Exceptions
- The first Perl 6 module on CPAN
- Gabor: Keep going
- Google Summer of Code Mentor Recap
- Building a Huffman Tree With Rakudo
- Immutable Sigils and Context
- Is Perl 6 really Perl?
- List.classify
- Perl 6: Lost in Wonderland
- Lots of momentum in the Perl 6 community
- Monetize Perl 6?
- Musing and the future of feather and the Pugs repository
- Musings on Rakudo's spectest chart
- My first executable from Perl 6
- Trying to implement new operators - failed
- Let's build an object
- Perl 6 is optimized for fun
- How to get a parse tree for a Perl 6 Program
- Perl 6 in 2009
- Perl 6 ticket life cycle
- The Perl Survey and Perl 6
- The Perl 6 Advent Calendar
- Physical modeling with Math::Model and Perl 6
- How to Plot a Segment of a Circle with SVG
- Publicity for Perl 6
- Rakudo architectural overview
- Rakudo Rocks
- Rakudo "star" announced
- My personal "I want a PONIE" wish list for Rakudo Star
- Rakudo's rough edges
- Rats and other pets
- Releasing Rakudo made easy
- Set Phasers to Stun!
- Starry Perl 6 obfu
- Recent Perl 6 Developments August 2008
- Strings and Buffers
- Subroutines vs. Methods - Differences and Commonalities
- A SVG plotting adventure
- A Syntax Highlighter for Perl 6
- Test Suite Reorganization: How to move tests
- The Happiness of Design Convergence
- Perl 6 Tidings from September and October 2008
- Perl 6 Tidings for November 2008
- Perl 6 Tidings from December 2008
- Perl 6 Tidings from January 2009
- Perl 6 Tidings from February 2009
- Perl 6 Tidings from March 2009
- Perl 6 Tidings from April 2009
- Perl 6 Tidings from May 2009
- Perl 6 Tidings from May 2009 (second iteration)
- Perl 6 Tidings from June 2009
- Perl 6 Tidings from August 2009
- Perl 6 Tidings from October 2009
- Timeline for a syntax change in Perl 6
- Visualizing match trees
- Want to write shiny SVG graphics with Perl 6? Port Scruffy!
- We write a Perl 6 book for you
- When we reach 100% we did something wrong
- Where Rakudo Lives Now
- Why was the Perl 6 Advent Calendar such a Success?
- What you can write in Perl 6 today
- Why you don't need the Y combinator in Perl 6
- You are good enough!
Mon, 19 Jul 2010
Gabor: Keep going
Permanent link
After reading this blog post, I just want to say: keep going.
Gabor does really awesome things for Perl (and especially for Perl 6, which I tend to notice more): beginner's tutorials, screencasts, training courses, writes an IDE and so on. If his primary interest was his own success, his priorities would be quite different.
I hope that Gabor doesn't pay too much attention to the hostilities from parts of the Perl community, and I wish him and us all the best for his current project.
Tue, 13 Jul 2010
This Week's Contribution to Perl 6 Week 9: Implement Hash.pick for Rakudo
Permanent link
For this week's contribution to Perl 6 we ask you to implement the
Hash.pick method (which does a weighted random selection) for
Rakudo.
(Introduction to this series of challenges)
Background
In Perl 6 the List class has a method called pick,
which randomly selects one item from a list. It has a few more options
too:
<a b c>.pick; # pick one random element <a b c>.pick(2); # pick two distinct, random elements <a b c>.pick(2, :replace); # pick two random elements, it's ok # if they are the same <a b c>.pick(*); # return a random permutation of the elements <a b c>.pick(*, :replace); # infinite, random stream of elements
This is already implemented through several multi methods in Rakudo.
Now the specification describes such a method for hashes too (actually it talks about Bags, but Rakudo doesn't have Bags yet. Pretend it says "Hash" instead). It assumes that each value in the hash is numeric, and that the value is a weight that determines the probability of picking one value. For example
{a => 1, b => 2}.pick; # returns 'a' with probability 1/3
# and 'b' with probability 2/3
{a => 1, b => 2}.pick(*); # <a b b> with probability 1/3
# <b a b> with probability 1/3
# <b b a> with probability 1/3
{a => 1, b => 0.5}.pick(*) # dies, because the weights aren't all integers
{a => 1, b => 0.5}.pick(*, :replace) # ok
What you can do
Implement Hash.pick. It's ok if your patch doesn't cover all cases. It would be nice if it supported non-integer weights.
Hint: this could be done by storing a list of accumulated weights, and a list of keys.
{a => 1, b => 2.5, c => 1}
# could translate to
my @keys = ('a', 'b', 'c');
my @accumulated_weights = (1, 3.5, 4.5);
# now pick a random number between 0 and 4.5,
# find the next-highest index in @accumulated_weights
# with a binary search, and then use that to obtain the key.
Of course other schemes are fine too.
Second hint: because it takes quite some time to recompile Rakudo, it is probably easier to implement the actual logic in a function in a normal source file first, and only later move it into src/core/Hash.pm.
Submission
Please submit your source code to the perl6-compiler@perl.org mailing list (and put moritz@faui2k3.org on CC, because the mailing list sometimes lack quite a bit).
Update: there's one submission on the perl6-compiler mailing list already, which looks pretty good.
Mon, 12 Jul 2010
Want to write shiny SVG graphics with Perl 6? Port Scruffy!
Permanent link
First let my apologize for waiting so long to come up with a new "weekly" Perl 6 challenge - I'm running out of ideas, and the one I have left needs more time to prepare.
Instead I want to motivate you to help porting the ruby scruffy charting library to Perl 6. It can generate shiny SVG graphics (they are currently broken on their main website, hence the waybackmachine link).
There's already an initial version Perl 6 port called "tufte", but it's not running yet. It needs your help. If you know a little ruby, and want to learn some more Perl 6, join #perl6, ask for a commit bit, and translate some ruby code into Perl 6. And in the end you'll be rewarded with nice SVG charts :-).
Tue, 29 Jun 2010
This Week's Contribution to Perl 6 Week 8: Implement $*ARGFILES for Rakudo
Permanent link
For this week's contribution to Perl 6 we ask you to implement the
$*ARGFILES special variable (and underlying object) for
Rakudo.
(Introduction to this series of challenges)
Background
In Perl 5, there is a "magic" way to iterate over input: while (my
$line = <>) { ... }. This reads from standard input if no command
line arguments were provided. If there are command line arguments, they are
taken as file names, and <> iterates over the contents of
these files.
In Perl 6 this magic is performed with the $*ARGFILES special
variable. Please implement it!
To do that, you have to understand how file reading works in Perl 6. Once
you have a file handle, there are two ways to read lines: either by calling
$handle.get, which returns just one line, or by calling
$handle.lines, which returns a (lazy) list of all the remaining
lines.
You can obtain the command line arguments from @*ARGS, open a
file with my $handle = open $filename; for reading; And finally
you can use lines('filename') to read all lines from a file.
What you can do
Implement a backend class for $*ARGFILES. You can do that in
normal Perl 6 code, no need to change the actual compiler. Once that's done,
we will plug it into Rakudo. Your code might look like this:
class IO::ArgFiles { has @!filenames; method get() { ... } method lines() { ... } method filename() { # return the current filename, or '-' if standard input ... } } my $*ARGFILES = IO::ArgFiles.new(filenames => @*ARGS); .say for $*ARGFILES.lines();
(Of course this is only a rough skeleton, you might need to change some details, or add some things).
Submission
Please submit your source code to the perl6-compiler@perl.org mailing list (and put moritz@faui2k3.org on CC, because the mailing list sometimes lack quite a bit).
Update:: there have been two submissions, and a mixture of both has been applied.
Mon, 28 Jun 2010
This Week's Contribution to Perl 6 - Lottery Intermission
Permanent link
In the original "Contribute now" announcement I've promised that there would be some t-shirts to win.
Since then there have seven challenges (mostly weekly), and I've decided on the rules of the lottery:
- Every contributor can win at most one t-shirt, even if he had submissions for multiple weeks
- The lottery will be done on a per-week base
Of course the lottery was conducted by a Perl 6 script. Here it is:
use v6; my @contribs = [ "patrickas", "shawjef3@<omitted>", "Dagur Valberg Johannsson", "Juan José 'Peco' San Martín"], [ "bubaflub" ], [ "patrickas", "David Green" ], [ "Hongwn Qiu"], [ "David Green", "Chris Fields", "rgrau"], [ "sahadev" , "Dean Serenevy"], [ "cygx" ], ; my %winners; for @contribs.pairs.pick(*) -> $p { my $week = $p.key + 1; my @people = $p.value.flat.grep({ !%winners{$_} }); say "Candidates for Week $week: @people.join(', ')";; my $winner = @people.pick; say "And the winner is... $winner!"; %winners{$winner} = $week; } say %winners.perl;
And then, in the moment of truth, it produced this output:
Candidates for Week 7: cygx
And the winner is... cygx!
Candidates for Week 2: bubaflub
And the winner is... bubaflub!
Candidates for Week 5: David Green, Chris Fields, rgrau
And the winner is... David Green!
Candidates for Week 1: patrickas, shawjef3@<omitted>, Dagur Valberg Johannsson, Juan José 'Peco' San Martín
And the winner is... shawjef3@<omitted>!
Candidates for Week 4: Hongwn Qiu
And the winner is... Hongwn Qiu!
Candidates for Week 3: patrickas
And the winner is... patrickas!
Candidates for Week 6: sahadev, Dean Serenevy
And the winner is... sahadev!
{"Hongwn Qiu" => 4, "patrickas" => 3, "bubaflub" => 2, "David Green" => 5,
"cygx" => 7, "sahadev" => 6, "shawjef3\@<omitted>" => 1}
If you are one of the winners, and haven't told me your address yet, please do so. Also tell me your t-shirt size, and whether you want a Rakudo or a Perl 6 t-shirt.
I'd like to thank again everybody who contributed, and The Perl Foundation for sponsoring some of the t-shirts!
Mon, 21 Jun 2010
This Week's Contribution to Perl 6 Week 7: Implement try.rakudo.org
Permanent link
For this week's contribution to Perl 6 we ask you to write a web shell for Rakudo, just like tryruby.org (or this js course) but for Perl 6 + Rakudo.
(Introduction to this series of challenges)
Background
We want a website like tryruby, but for Perl 6: A combination of web shell and built-in tutorial.
The idea is that for each session a supervisor/controller process runs on the server, which talks to a Rakudo process, and listens at a local socket. A CGI script receives the program lines to be executed, looks up the port number in a session file or database, and connects via a local socket to the controller process.
What you can do
You can help to make try.rakudo.org come real. This week I ask you to work on the front end, ie. a HTML page with some javascript that works like a shell; it sends the command entered by the user to a CGI script, and displays its response.
It should also be able to show instructions, and advance to the next instruction when the user has entered what he should.
Submission
A stub of the source code can be found on github. Please join our IRC channel and ask for commit access to that repository.
Then fill in any parts you want, primarily concerning the front-end. If you have any questions, don't hesitate to ask either on the IRC channel, or on the perl6-compiler@perl.org mailing list (and put moritz@faui2k3.org on CC, because the mailing list sometimes lack quite a bit).
Update: We now have a frontend and parts of the backend, by courtesy of cygx++. If you want to join the project, please improve what we have now instead of submitting a new solution.
Sun, 20 Jun 2010
Physical modeling with Math::Model and Perl 6
Permanent link
Let's talk about physics. I'm a physicist by education and profession, so it might be not be too surprising. But I also want to talk about programming, so please bear with me.
When physicists try to understand a system, typically they first come up with a lot of equations, and then try to solve them. Unfortunately some of those equations are quite hard to solve. I've written a module that solves them numerically, and allows you to express the equations in very simple Perl 6 code.
Getting started
Let's start with a very simple model. As a prerequisite you need the Rakudo Perl 6 compiler (latest release or
current development version), and then use proto to proto install Math-Model
(which also installs its dependencies).
A first model: throwing a stone horizontally into the air
Let's start with an example (to be found in examples/vertical-throw.pl in the Math-Model repository, with small modifications to unconfuse the syntax hilighter used for this page).
It describes the path of stone thrown vertically into the air.
use v6; use Math::Model; my $m = Math::Model.new( derivatives => { y_velocity => 'y', y_acceleration => 'y_velocity', }, variables => { y_acceleration => { $:force / $:mass }, mass => { 1 }, # kg force => { -9.81 }, # N = kg m / s**2 }, initials => { y => 0, # m y_velocity => 20, # m/s }, captures => ('y', 'y_velocity'), ); $m.integrate(:from(0), :to(4.2), :min-resolution(0.2)); $m.render-svg('throw-vertically.svg', :title('vertical throwing'));
First we declare that we use Perl 6 (use v6;), and then we
load the module that does all the hard work, Math::Model.
Then comes the interesting part: the actual model. It starts by declaring
that the derivative of y (which is the name we use for the
current height of the stone) is called y_velocity. Likewise the
derivative of y_velocity is called
y_acceleration.
A derivative describes the rate of change of some other variables. Here is a short list of useful physical quantities and their derivatives:
| Quantity | Derivative |
|---|---|
| position | velocity |
| velocity | acceleration |
| acceleration | jerk |
| momentum | force |
| energy | power |
| charge | current |
Next in the model are formulas for some variables. We don't need to give
formulas for those values on the right-hand side of the derivatives
declarations (y and y_velocity), which we will call
integration variables. We just need formulas for the derivatives that
are not also integration variables, and for other variables we use in the
formulas.
You might remember from physics class that F = m * a, force is mass times acceleration. We use this formula for calculating the acceleration
y_acceleration => { $:force / $:mass },
The other variables are actually constants (but Math::Model doesn't distinguish those); mass is set to 1 kg, and the force to the -9.81 N that a mass of 1 kg experiences at the latitude where I live (Germany).
The programmer in you might ask what the heck the : in $:force
means. It's a variable that is automatically a named parameter to the current
block. Math::Model uses Signature
introspection to find out which variables such a block depends on, and
topologically sorts all variables into an order of execution that satisfies
all the dependencies.
Back to the physical model; all integration variables need an initial value, which are provided on the next few lines. The line
captures => ('y', 'y_velocity'),
tells Math::Model which variables to record while the simulation is running.
$m.integrate(:from(0), :to(4.2), :min-resolution(0.2)); $m.render-svg('throw-vertically.svg', :title('vertical throwing'));
Finally these two lines are responsible for running the actual simulation
(for the time t = 0s to t = 4.2s), and then write the resulting curves into
the file throw-vertically.svg. And here it is, without further
ado:
The blue line is the height (in meter), and the yellow line the velocity (in meter/second). Positive velocities mean that the stone is moving upwards, negative that it's moving downwards. After about 4 seconds the stone has the height with which it started, at a velocity of about -20m/s. You don't see any effect of the stone hitting the ground, because the model knows nothing about a ground located at a height of 0m. Just imagine the stone fell into a well or down a cliff, and thus can have negative height too.
Iterating: throwing a stone at an arbitrary angle
It gets a bit more involved when you consider not only the y direction, but also the x direction, and throw the stone at an arbitrary angle. Still the x and y axis are rather independent:
use v6; use Math::Model; for 30, 45, 60 -> $angle { my $m = Math::Model.new( derivatives => { y_velocity => 'y', y_acceleration => 'y_velocity', x_velocity => 'x', }, variables => { y_acceleration => { $:force / $:mass }, mass => { 1 }, # kg force => { -9.81 }, # N = kg m / s**2 x_velocity => { 20 * cos($angle, Degrees) } # m / s }, initials => { y => 0, # m y_velocity => 20 * sin($angle, Degrees), # m/s x => 0, # m }, captures => <y x>, ); $m.integrate(:from(0), :to(2 * 20 * sin($angle, Degrees) / 9.81), :min-resolution(0.2)); $m.render-svg("throw-angle-$angle.svg", :x-axis<x>, :width(300), :height(200), :title("Throwing at $angle degreees")); }
The x velocity stays approximately constant (we disregard air drag), and it's value is the cosine of the throwing angle times the initial, total velocity. The velocity in y direction is the sine of the throwing angle times the initial, total velocity.
As a trick to get nicer graphs in the end, I calculated the expected time
until it hits the ground (which I know to be 2 * v_y / a; this is
cheating, but it doesn't change the physics behind it).
Finally this time we don't want to have the elapsed time on the x axis, but
the actual position in x direction. That can be done with the
:x-axis<x> option.
(Note that I cheated to produces these charts; normally SVG::Plot, the module that produces these graphs, automatically scales the axis; I've manually suppressed that; if you try to out the example you'll see that the three charts look much the same, except for different axis scaling).
The maximum reach in x direction before hitting the ground is achieved at 45 degrees. For smaller angles it's not long enough in the air, and for larger angles too much of the velocity is "wasted" in the vertical direction, so the stone doesn't get very far.
A third model: oscillating spring
Finally I want to present a third, simple model: a mass hanging down from a spring, this time including air drag. It doesn't show off any new features of Math::Model, but the result is a nice, oscillating curve.
use v6; use Math::Model; my $m = Math::Model.new( derivatives => { velocity => 'height', acceleration => 'velocity', }, variables => { acceleration => { $:force / $:mass }, mass => { 1 }, force => { - $:height - 0.2 * $:velocity * abs($:velocity)}, }, initials => { height => 1, velocity => 0, }, captures => <height>, ); $m.integrate(:from(0), :to(20), :min-resolution(1)); $m.render-svg('spring.svg', :title('Spring with damping'));
The air drag/damping is built into the formula for the force. It is proportional to the square of the velocity (making analytical solutions a nuisance), and always points in the opposite direction as the velocity.
Moving on
If you want to have some fun with Math::Model, here's a nice idea: You can simulate a mass attached to a spring, which can move freely in the xy plane. If you chose random initial values for the velocities in both directions, you can get non-periodic (chaotic?) trajectories in the xy plane.
(If you do, please send me the model so that I can also play with it :-))
A personal note
Ever since I've used the simulation tool "stella" in school (must have been year 2002 or so), I've wanted to write something similar. Math::Model is it. It was quite fun to implement in Perl 6. The only drawback is that it's quite slow.
Tue, 08 Jun 2010
This Week's Contribution to Perl 6 Week 6: Improve Book markup
Permanent link
This Week's Contribution to Perl 6 can be found on masak's blog.
Mon, 31 May 2010
This Week's Contribution to Perl 6 Week 5: Implement Str.trans
Permanent link
For this week's contribution to Perl 6 we ask you to write some Perl 6 code
that implements the trans method for Rakudo Perl. This is the backend for the
tr/// operator.
(Introduction to this series of challenges)
Background
The Perl 6 transliteration operator is also available as a method. It replaces all occurrences of some characters (or regexes) with a substitution string. The easiest case is:
say 'Hello World'.trans('a' => 'A', 'e' => 'E', 'O' => 'O'); # output: HEllO WOrld say 'Hello World'.trans('aeo' => 'AEO'); # same thing
The previous iteration of Rakudo had a PIR-based (and complicated)
implementation for trans. There are tests
in the official test suite for .trans.
What you can do
Please write a method trans that implements part of the
specification.
Since it's quite a lot to do, it's OK to only do parts. For example I
recommend to omit regexes altogether for now, and only implement literal string
patterns. The easiest approach is probably to create a hash that maps each
input pattern character to the transliteration, and walk the string character
by character by iterating over self.comb.
To test it without actually having to recompile Rakudo after each change, I recommend to copy the test that Rakudo can parse (ie the method tests, not the tests for tr///), and start it with
use v6; use Test; use MONKEY_TYPING; augment class Str { method trans(*@patterns) { # do your hacking here 'wrong return value'; } } plan *; is("ABC".trans( ('A'=>'a'), ('B'=>'b'), ('C'=>'c') ), "abc", "Each side can be individual characters"); is("XYZ".trans( ('XYZ' => 'xyz') ), "xyz", "The two sides of the any pair can be strings interpreted as tr/// would multichar"); ... done_testing;
Submission
Please send your submission to the perl6-compiler@perl.org mailing list, and set me (moritz@faui2k3.org) as CC, because the mailing list sometimes has a large delay.
If you have any questions, please ask the mailing list, me or (preferred) on our IRC channel, #perl6.
The best/most extensible/most complete/prettiest/whatever submission will make it into the next release of Rakudo.
Update: There have been two submissions discussed on perl6-compiler, and another one submitted as gist. If you want to work on this challenge, please improve one of the existing submissions, not write a new one from scratch.
Wed, 26 May 2010
This Week's Contribution to Perl 6 Week 4: Implement :samecase for .subst
Permanent link
For this week's contribution to Perl 6 we ask you to implement an option in
the string substitution backend that is be used for s/// style
replacements.
(Introduction to this series of challenges)
Background
In Perl 6, the string substitution operation s/// has a method
backend. Instead of s:g/foo/bar/ (globally substitute foo by bar)
you can write:
say 'some foo with sugar'.subst(/foo/, 'bar', :g);
Currently Rakudo doesn't parse the adverbs at the front, but supports the named arguments in the method form.
What you can do
Implement the :samecase named parameter. With this option, the
case (upper/lower) of the original string is applied to the substitution:
say 'The foo and the bar'.subst(/:i the/, 'that', :g, :samecase); # should produces 'That foo and that bar'
The actual case transformation is implemented in form of the
samecase($substitution, $pattern) function already. If the
replacement part is actually a code object, the samecase
translation should apply to its return value.
Your task is to hook that function into the subst
method in src/core/Cool-str.pm, and put some tests into t/spec/S05-substitutions/subst.t
in the pugs repository that demonstrate that your code works.
When you've modified the test and/or the source file, you can run it with
make t/spec/S05-substitution/subst.t
Submission
Please submit your patches to the perl6-compiler mailing list, and CC' me (moritz@faui2k3.org). As always, feel free to ask any questions about this question either on that mailing list, or on our IRC channel.
Update: A working patch from Hongwen Qiu has been applied, as well as some tests; more tests are still welcome.
Tue, 25 May 2010
My personal "I want a PONIE" wish list for Rakudo Star
Permanent link
In June we'll see a special Rakudo release codenamed Rakudo Star. I've done some development with and of Rakudo, and here's the list of features and bug fixes that I think are essential for a successful and well-received release:
- Backtraces with Perl 6 file names and line numbers (Update 2010-05-30: jnthn implemented those)
- Proper closure cloning (Update 2010-06-07: pmichaud has fixed it)
- Match objects which return Perl 6 (and not parrot) data structures (Update 2010-05-30: pmichaud laid the foundations for that, and I got it to a "good enough" state).
/<foo>/should pick up a regex namedfoofrom the lexical scope, not only from method lookup. (Update 2010-07-21: This is not going to happen, since the spec will change significantly at this point).- Using the same list or iterator twice returned from
maporgather/takeshould work (Update: pmichaud fixed that in The Big List Refactor, which was merged shortly before the 2010.06 release).
Other things that I consider nice to have, but not essential:
$/should be available in the RHS ofs///(seems hard to do with current Parrot semantics)usecurrently only accepts pairs, not proper argument lists. Would be nice to have that.- General Whatever-currying (ie
* op 3returns a closure of type WhateverCode) (Update: jnthn implemented it one or two days after this blog post) - Currently user-defined operators hide candidates of the same name from outer scopes. This is rather annoying.
Thu, 20 May 2010
The Perl Survey and Perl 6
Permanent link
Today I've participated in The Perl Survey, and I want to encourage you to do the same.
I was a bit disappointed that the list of Perl versions didn't include any Perl 6 - which I use sufficiently to mark that option if it existed.
It's a sad fact that parts of the Perl community haven't realized that Perl 6 is more than a dream, but comes with programs you can run today. Association with or funding from TPF doesn't seem to make you immune to that misconception.
Wed, 19 May 2010
This Week's Contribution to Perl 6 Week 3: Write supporting code for the MAIN sub
Permanent link
For this week's contribution to Perl 6 we ask you to write some Perl 6 code that parses command line arguments, and might end up in the code base of a Perl 6 compilers.
(Introduction to this series of challenges)
Background
In Perl 6 you can write a sub MAIN that is automatically called when the script is run, and it handles command line parsing for you.
So for example if you write
sub MAIN($filename, *@rest, :$verbose) { ... }
And you call the script as
perl6 create_many_copies.pl --verbose=2 /etc/password pw1 pw2 pw3
The parameters are automatically set to $filename =
'/etc/password', @rest = ('pw1', 'pw2', 'pw3') and $verbose =
2.
What you can do
Write a subroutine in Perl 6 that takes an array of command line arguments, and a hash of option names that are declared as Bool, and returns an array of positional arguments, and a hash of named arguments
sub process-cmd-args(@args, %boolean-names) { ... return @positional-arguments, %named-arguments; }
It should separate the named arguments (options) and the ordinary,
positional arguments. For example a command line argument of
--myname=23 should be result in a hash entry
%named-arguments{'myname'} = 23. If a named option is declared as
type Bool, then --myoption foo is turned into
%named-arguments{'myoption'} = True, @positional-arguments =
'foo'. Otherwise it is taken as
%named-arguments{'myoption'} = 'foo'.
The specification describes the various syntax forms in detail, but you are very welcome to implement only parts of them. For example it's recommended to ignore the negation forms, short names and spaces inside options.
We will then use the separate positional and named arguments to call the MAIN routine.
If you need some more background on how to write Perl 6 code, I recommend to start with a book that is currently being written (you can find a fairly up-to-date PDF version here.). See also our documentation overview.
Submission
Your program should run with the current Rakudo Perl 6 compiler - bonus points if you also provide some tests.
Please send your submission to the perl6-compiler@perl.org mailing list, and set me (moritz@faui2k3.org) as CC, because the mailing list sometimes has a large delay.
Update:: patrickas has submitted one implementation to this github repository. Instead of starting your own implementation, you can also contribute to this one (ask on #perl6 for commit access), and of course you're still eligible for winning a cool Perl 6 or Rakudo t-shirt.
If you have any questions, please ask the mailing list, me or (preferred) on our IRC channel, #perl6.
I will try to integrate the best submission into Rakudo (though it might not happen before the upcoming release on Tuesday).
Tue, 11 May 2010
This Week's Contribution to Perl 6 Week 2: Fix up a test
Permanent link
For this week's contribution to Perl 6 we ask you to fix a short test file in the official spec tests.
(Introduction to this series of challenges)
Background
The test file in
S05-grammar/parse_and_parsefile.t tests the.parse and
.parsefile methods of custom grammars.
However, it uses the outdated assumption that Grammar.parse
automatically searches for a match in a string, just like a regex match does.
That's not the case anymore; The current specification says that
.parse is anchored to the beginning and end of the string, which
means it always parses the entire string, or nothing at all.
What you can do
Update the test file to reflect the current specification, so that the parse and parsefile methods match the whole test string.
In the old version the test made sure that only the correct submatch was found; please replace that by a test for a non-matching grammar or test string.
The Rakudo Perl 6 compiler implements the parse and parsefile method. Please run your test file on Rakudo, and make sure it runs on Rakudo. Bonus points if you can finde a bug in Rakudo's parse or parsefile methods, and add another test that demonstrates the bug. (Disclaimer: I have no knowledge of such a bug; there might not be one at all).
Submission
<update> bubaflub has taken the challenge, and fixed the test in r30617. Of course further improvements to the test are still welcome.</update>.
For this challenge please join the #perl6 IRC channel, and ask for a commit bit to the test suite. You'll need to tell us your desired nick name and email address for the SVN user account.
When you build Rakudo by
following these instructions, run make spectest. This
will automatically checkout out a copy of the test into the t/spec
subdirectory of your rakudo directory.
Edit t/spec/S05-grammar/parse_and_parsefile.t, and then test
it by running
make t/spec/S05-grammar/parse_and_parsefile.t # if you need more diagnostic output, also run ./perl6 t/spec/S05-grammar/parse_and_parsefile.rakudo
Once you have the test file passing and correct, change to the
t/spec directory, and commit your changes:
svn ci -m '[t/spec] bring parse_and_parsefile.t up to date' S05-grammar/parse_and_parsefile.t
If you need any guidance, please don't hesitate to ask us either on IRC, or through the perl6-compiler@perl.org mailing list.
Sat, 08 May 2010
List.classify
Permanent link
Yesterday I implement
a nice Perl 6 built-in called classify.
Just like map it takes a closure and a list (or can be called
as a method on a list). Unlike map it doesn't just return the values from the
closure calls, but instead it constructs Pair objects from them,
and groups them by equal keys. Here's one example:
say <red brown blue yellow black>.classify({ $_.substr(0, 1)}).perl; # output: # ("y" => ["yellow"], "b" => ["brown", "blue", "black"], "r" => ["red"])
This takes a list of color names, and groups them by their first letter. It returns a list of pairs, of which the key is always the first character (returned by the closure), the value is an array of the input values that have this first character.
Of course you can assign the result to a hash, and index by key you're interested in:
my %h = <red brown blue yellow black>.classify({ $_.substr(0, 1)}); say %h<b>.join(', '); # output: # brown, blue, black
So far I haven't come up with a real-world use case for
classify, but I strongly suspect I'll run across one soon,
and I kinda like the function.
Have you written any code lately where such a built-in would have been beneficial?




