I think the closest things we've got to pattern matching come from a combination of multiple dispatch, where clauses and signature unpacking. I don't know much about the latter, but a where clause can discriminate multiple dispatch variants based on parameter values rather than just the type, so you can say:
multi doSomething(@a where { .elems == 0 }) { # empty arrays only } multi doSomething(@a where { .elems >= 3 && .[2] == 4 }) { # arrays with a third element numerically equal to 4 } multi doSomething(@a) { # anything else } Which is pretty powerful, really. > This is a contrived example of what I'm referring to: > > sub traverse([Leaf $a]) { > # do something > } > > sub traverse([Tree $left, Tree $right]) { > traverse($left); > traverse($right); > } > > my $t = Tree(...); > traverse($t); You could do most of this with multidispatch and where clauses. It doesn't quite work because of the unpacking which pattern matching does, and also because Perl 6 data structures don't get built in the same way that Haskell ones do, and you've used a Haskell-like syntax for Leaf and Tree and so forth. Now, while it might be nice to say let me write a signature which accepts a Tree object which has a left and right subtree, and binds them to $left and $right respectively, arguably a where clause can check that the subtrees exist, and your tree class should have good accessors for the subtrees which make unpacking them a little pointless. This is where Perl 6 is not the same as functional languages, since it's got an imperative OO element as well. multi traverse(Tree $t where { all(.left, .right).defined }) { ... } Perhaps.