I'm writing a new module that optimizes sets of conditions into decision trees. Initially I allowed the user to specify conditions as strings, and if that condition began with a "!", it would be the inverse of the condition without the "!".
But then I thought, "the user will more than likely have condition *objects* if the conditions are anything but trivial". Then you can't just put a "!" on the front. The way Haskell and ML do this is by allowing data constructors: symbols that can take arguments and be pattern matched against. I thought that this was a particularly elegant way to solve the problem, so I implemented it in the Symbol::Opaque module. Now I want it for Perl 6. Here's my proposal. Let's generalize the backtick from unit support into data constructor support. The following are equivalent: 4`meters `meters(4) The postfix form is only available for single-argument constructors, but the prefix form can be used with more than one argument: `foo(4, 5) These things don't need to be declared, but you can use a "data" declaration to give them a type (which does Symbol, the type of all such constructors): data Quux (`foo, `bar, `baz); Now whenever you create a `foo, it is a Quux. These can overlap: data Foo (`baz); data Bar (`baz); A `baz object is now both a Foo and a Bar. These could be easily extended to allow type signatures, to come up with those nice type-checked data structures that we're using for PIL. But I'm not proposing that part yet. Here's what makes them so useful: they can be bound against: sub to_SI (`meters($m)) { `meters($m) } sub to_SI (`feet($f)) { `meters(feet_to_meters($f)) } Here's an excerpt from my module (perl6ized): sub invert ($in) { my `not($x) := $in ?? $x :: `not($in); } Or maybe that's: sub invert ($in) { `not(my $x) := $in ?? $x :: `not($in); } Anyway, the point is that bindings can fail. In boolean context, they return whether they succeed; in void context, they blow up if they fail (probably "fail"). As multimethods: multi invert (`not($x)) { $x } multi invert ($x) { `not($x) } Which I like the best. Pairs are values: like numbers. `foo =:= `foo. They can just have sub-values.