Perl 6 lists/arrays are not linked list.
However, the Pair type can be used to build linked lists, and provides the functionality of those three Lisp functions.
Using nested Pairs
A Pair represents a key-value pair. For example when iterating a Hash, you get a sequence of Pairs.
If you think of a Pair as a cons cell, then you can build a linked lists à la Lisp as a Pair that has another Pair as its value, which in turn has another Pair as its value, and so on.
- The
=> operator (Pair constructor) fulfills the role of cons.
- The
.key method fulfills the role of car.
- The
.value method fulfills the role of cdr.
Example:
my $l = (1 => (2 => (3 => (4 => (5 => Nil)))));
say $l.key; # 1
say $l.value; # 2 => 3 => 4 => 5 => Nil
The => operator is right-associative, so that first line can also be written without the parentheses:
my $l = 1 => 2 => 3 => 4 => 5 => Nil;
If you wanted to declare the Lisp functions under their familiar names, it would look like this:
sub cons ($x, $y) { $x => $y }
sub car (Pair $y) { $y.key }
sub cdr (Pair $y) { $y.value }
Note, however, that there are no built-in convenience functions for doing list processing with such Pair-based linked lists. So if you wanted to do the equivalent of Scheme's length or append functions etc., then you'd have to write those functions yourself. All the built-in list processing routines assume normal Perl 6 lists or compatible Iterable types, which Pair is not.
Using normal Perl 6 lists
If you want to use normal Perl 6 lists/arrays as your data structure, but implement the behavior of the Lisp functions for them, I'd write it like this:
sub cons ($x, $y) { $x, |$y }
sub car (@y) { @y[0] }
sub cdr (@y) { @y[1..*] }
Some comments:
- Instead of using
flat, I used the | operator to slip the elements of $y into the outer list.
- The
first function does not do what you expect in your code. It is meant for searching a list. It interprets the first argument (in your case $aList) as a predicate, and the remaining arguments (in your case none) as the list to search, thus in your case it always returns Nil.
For returning the first element of a list, You can use the [ ] positional subscripting operator instead, like I did here.
- The
return keyword is optional; The result of the last statement of a function is automatically returned.