It occurred to me that being able to set up 'pure' functions in such a
way that they are lazily evaluated when passed a superposition might
be a win.
And then I got to thinking about what would be required from the
language to allow me to implement this functionality in a module. I am
assuming (for the purposes of this example) that functions will get
called with 'simple' argument lists, no defaulting etc, and a maximum
of one superposed argument...)
class PureFunction is Sub {
# I'm assuming here that 'apply' is equivalent to func(...)
method apply(*@arglist) {
my @curry_list;
my $super_arg;
for @arglist; .param_list -> $arg; $param {
when Superposition {
die "Too many superposed args" if defined $super_arg;
$super_arg = $arg;
}
otherwise {
push @curry_list, ($param.symbol => $arg);
}
}
return FunctionApplication::Superposed
.new( superposition => $super_arg,
func => $self.given(*@curry_list) );
}
}
}
class FunctionApplication::Superposed is Superposition {
my $.superposition;
my $.func;
method force ($self is rw:) {
return $self = ($.func($.superposition)).force;
}
method eigenstates {
.force.eigenstates;
}
}
method Superposition::force ($self:) { $self }
The idea being that, when you do
a_pure_func($val1|$val2|$val3)
instead of Perl going away and doing the calculation right away, you
get back a 'special' superposition which stores an 'invocation
description' and calculation is deferred until you need to get a
superposition's list of possible states.
If that were all there were to it of course then there wouldn't be
much gain from doing this, however, consider:
# Ignore duplicates, it's a proof of concept dammit!
method FunctionApplication::Superposed::choose {
loop {
$.function($.superposition.choose);
CATCH Exception::SuperPositionExhausted { die $@ }
CATCH Exception::ChooseFailure { redo }
otherwise { throw $@ }
}
}
method Superposition::choose($self:) {
for @.states -> $state {
when Superposition {
loop {
my $val = try {
$state.choose;
CATCH Exception::SuperPositionExhausted { last }
otherwise { die $@ }
}
yield $val;
}
}
otherwise { yield $state }
}
throw Exception::SuperPositionExhausted: $self;
}
And, ooh, look, we have something that'll Do The Right Thing with the
nondeterministic algorithm I posted last week.
*Damn* but Perl 6 is going to be a potent programming language...
--
Piers
"It is a truth universally acknowledged that a language in
possession of a rich syntax must be in need of a rewrite."
-- Jane Austen?