Data constructors / Unidirectional unification

1 view
Skip to first unread message

Luke Palmer

unread,
Aug 4, 2005, 8:37:46 PM8/4/05
to perl6-l...@perl.org
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.

Reply all
Reply to author
Forward
0 new messages