Have you wanted to start playing with Perl 6 but find yourself wondering what to write? I use Pugs, a Perl 6 implementation being written in Haskell and have been tremendously enjoying Perl 6. Like many, I’m impatient, but the work on Perl 6 has been progressing quite well and I’m quite keen to see the alpha. However, if you’re like me, you probably do better with a new language by actually writing something in it. Well, not only do I have something for you to write, you can actually help out the Perl 6 effort!
Recently I stumbled across 99 Problems in Lisp, which was in turn apparently borrowed from 99 Problems in Prolog. I’ve started 99 Problems in Perl 6.
I started out by writing a program which would take the text of the “99 Problems” and split them into separate test files for Perl 6. The first one looks like this:
use v6-alpha; use Test; plan 1; # P01 (*) Find the last box of a list. # # Example: # * (my-last '(a b c d)) # (D) is <a b c d>.[-1], 'd', 'Find the last box of a list.';
Each test file contains the entire text of the problem, though some refer you to previous problems. At the current writing, only the first 24 have been “solved” and the rest contain “skip” tests. If you can solve a problem, feel free to send an email to one of the Pugs mailing lists. Commit bits are handed out very liberally. Then you can add the solution and work on other problems.
To give you an example of how some of the languages compare, here’s the “lotto” problem (Draw N different random numbers from the set 1..M) in Lisp:
(defun range (ini fim)
(if (> ini fim)
(if (eql ini fim)
(cons fim nil)
(cons ini (range (- ini 1) fim)))
(if (eql ini fim)
(cons fim nil)
(cons ini (range (+ ini 1) fim)))))
(defun remove-at (org-list pos &optional (ini 1))
(if (eql pos ini)
(cdr org-list)
(cons (car org-list) (remove-at (cdr org-list) pos (+ ini 1)))))
(defun rnd-select (org-list num &optional (selected 0))
(if (eql num selected)
nil
(let ((rand-pos (+ (random (length org-list)) 1)))
(cons (element-at org-list rand-pos) (rnd-select (remove-at org-list rand-pos) num (+ selected 1))))))
(defun lotto-select (num-elem max-elem)
(rnd-select (range 1 max-elem) num-elem))
Wow! That’s hideously verbose and I suspect there’s a better way. Here it is in Prolog:
range(I,I,[I]).
range(I,K,[I|L]) :- I < K, I1 is I + 1, range(I1,K,L).
remove_at(X,[X|Xs],1,Xs).
remove_at(X,[Y|Xs],K,[Y|Ys]) :- K > 1,
K1 is K - 1, remove_at(X,Xs,K1,Ys).
rnd_select(_,0,[]).
rnd_select(Xs,N,[X|Zs]) :- N > 0,
length(Xs,L),
I is random(L) + 1,
remove_at(X,Xs,I,Ys),
N1 is N - 1,
rnd_select(Ys,N1,Zs).
lotto(N,M,L) :- range(1,M,R), rnd_select(R,N,L).
That’s better, but not much. The Haskell solution isn’t much better:
import System.Random
diff_select :: Int -> Int -> IO [Int]
diff_select n to = diff_select' n [1..to]
diff_select' 0 _ = return []
diff_select' _ [] = error "too few elements to choose from"
diff_select' n xs = do r <- randomRIO (0,(length xs)-1)
let remaining = take r xs ++ drop (r+1) xs
rest <- diff_select' (n-1) remaining
return ((xs!!r) : rest)
Here it is in Perl 6:
subset Positive::Int of Int where { $_ > 0 };
sub lotto (Positive::Int $count, Positive::Int $range) returns List {
return (1 .. $range).pick($count);
}
(The current implementation of Pugs does not yet support a ’subset’, so that’s not yet included in the test problem.)
Needless to say, that’s much easier to read. And look! A better type mechanism :) Part of the reason why that works so well is that Perl 6 is heavily focused on solving problems that programmers really face. Now, rather than testing whether your ‘Int’ is in the allowable range, you can carefully define a special ’subset’ which details what that allowable range is.
So go out there and do my homework! Things which will help:
- You might want to check the README first.
- Read the latest Perl 6 documentation,
- Hang out on #perl6 on irc.freenode.net
- For Firefox users, create a “perl6doc” keyword search using http://www.google.com/search?q=site%3Aperlcabal.org/%20%s


Here is a version in OCaml. Not as short as the Perl 6, but not as long as the others either.
Don't mean to troll... but as soon as I read the title the following popped in to my head...
Havin' Perl Problems? I feel bad for you son. I got 99 problems but Perl aint one....
Tip of the hat to Jay-Z.
This is how I would solve the problem in C:
void lotto(int m, int *numbers, int n) { for (int i = 0; i < m; i++) { int j = rand() % (n - i) + i; int tmp = numbers[i]; numbers[i] = numbers[j]; numbers[j] = tmp; } }lotto takes m numbers from an array of n, placed at the start of the array. example usage:
int numbers[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};srand(time(NULL));
for (int test = 0; test < 10; test++) {
lotto(3, numbers, 10);
printf("%d %d %d\n", numbers[0], numbers[1], numbers[2]);
}
There's probably a much nicer way to rewrite the Lisp version.
Also would like to note, the Perl 6 version is short because the main algorithm is already implemented by the pick method.
shaurz: your code has a bug. Note that the Perl 6 version forbids integers less than 1. If you call lotto with negative numbers, your code breaks. I think it's fair to ask that functionality be equivalent when comparing programming languages :)
The bug is in the caller ;-)
I guess the point was to show that the problem is trivial, even in a terrible language like C.
Anonymous: that's a fair point, but there are two things to consider. First, Perl 6 is heavily focused on providing built-in solutions to common problems. Thus, .pick might sound like I'm cherry picking (hah!) solutions which look better in Perl 6, but it's common. Want to know if all elements in one list are contained in another?
if ( all(@one_list) == any(@other_list) ) { ... }Also note that some examples posted don't have the nice "Positive::Int" constraint, thus contain bugs. That's another feature which is harder to concisely duplicate.
Side note: Positive::Int should have been Int::Positive. It's better to go from the general to the specific rather than the other way around.
But, as the anonymous commenter said, this is just because the problem has already been solved in the language's standard library.
michele: nothing wrong with the problem being solved by a standard library or a built in feature. Regular expressions are one of the many built-in things which first drove people to Perl. However, what happens to your code if you pass in values less than one? The code's not functionally equivalent.
Of course, I just noticed that my code has the bug that I didn't validate that $count <= $range :)
(sorry, anonymous was me)
A bit nicer CL version:
Ovid, I think it does: if either of the values is < 0, or count > range, a ValueError exception will be raised (in the first case, it will have a misleading "sample larger than population" message, though).
this is a lame example. first off it doesn't work. second off it just relies on a builtin function called "pick". big whoop.
It seems to me that the Lisp / Prolog / Haskell versions take pains to be an efficient implementation and not construct a complete list of integers 1 .. $range before picking some. What is the time and space complexity of the different algorithms?
Ed Avis: it's tough for me to answer that, but I do know that Perl 6 also attempts to automatically make lists lazy, so it should be relatively efficient with large lists.
Too bad most of these problems seem academic exercises.
Compute prime numbers
Compute other math values
Sort lists of lists
Adam, those are problems I encounter all the time while programming. Just the other day I needed to find the least common multiple between two numbers (useful when you need to synchronize timing events, for example), that that requires finding the prime factors of numbers.
Sorting lists of lists is also extremely useful in a number of contexts, including reporting.
Other issues such as filtering and manipulating lists, generating combinations and permutations, working with trees and graphs, etc., are things that I find myself using now and then. While a number of the items are certainly things I haven't used, I certainly have used most of these concepts at one time or another.
By the way:
lcm(a, b) = a * b / gcd(a, b)
lcm(0, 0) = 0
gcd(a, 0) = a
gcd(a, b) = gcd(b, a mod b)
And, for what it's worth, here's one implemention of the lotto function in Lua, which avoids creating the temporary array, mostly.
do local meta = {__index = function(_, k) return k end} function lotto(count, range) local rv = setmetatable({}, meta) for i = 1, count do local j = math.random(i, range) rv[i], rv[j] = rv[j], rv[i] end return unpack(rv, 1, count) end endYou're being a little harsh on the other solutions frankly. Line count / character count is not a measure of code quality.
Your argument is in fact: "Look, perl6 has more useful libraries than these other languages!"
Which is a good argument, although a single example is hardly convincing. CPAN might be though! (for those who find it useful)
If you want to make claims about readability, then go and define the pick function in your example & then make the comparison...
I am totally new to perl package installation. Currently i want to insall Net:Pcap pacakage.
Can any one please let me know the procedure in complete how to do it.
I have tried cpan.org, (Through CPAN i am facing build problem on cygwin) tried ppm (facing problem with proxies).
Please can any one tell me how can i do it.
Thanks in advance,