Apocalypse 3
by Larry Wall
|
Pages: 1, 2, 3, 4, 5, 6
Editor's Note: this Apocalypse is out of date and remains here for historic reasons. See Synopsis 03 for the latest information.
RFC 054: Operators: Polymorphic comparisons
I'm not sure of the performance hit of backstopping numeric equality
with string equality. Maybe vtables help with this. But I think this
RFC is proposing something that is too specific. The more general
problem is how you allow variants of built-ins, not just for ==,
but for other operators like <=> and cmp, not to mention
all the other operators that have scalar and list variants.
A generic equality operator could potentially be supplied by operator
definition. I expect that a similar mechanism would allow us to define
how abstract a comparison cmp would do, so we could sort and collate
according to the various defined levels of Unicode.
The argument that you can't do generic programming is somewhat specious. The problem in Perl 5 is that you can't name operators, so you couldn't pass in a generic operator in place of a specific one even if you wanted to. I think it's more important to make sure all operators have real function names in Perl 6:
operator:+($a, $b); # $a + $b
operator:^+(@a, @b); # @a ^+ @b
my sub operator:<?> ($a, $b) { ... }
if ($a <?> $b) { ... }
@sorted = collate \&operator:<?>, @unicode;
RFC 104: Backtracking
|
|
As proposed, this can easily be done with an operator definition to call a sequence of closures. I wonder whether the proposal is complete, however. There should probably be more make-it-didn't-happen semantics to a backtracking engine. If Prolog unification is emulated with an assignment, how do you later unassign a variable if you backtrack past it?
Ordinarily, temporary values are scoped to a block, but we're using blocks differently here, much like parens are used in a regex. Later parens don't undo the ``unifications'' of earlier parens.
In normal imperative programming these temporary determinations are
remembered in ordinary scoped variables and the current hypothesis is
extended via recursion. An andthen operator would need to have a
way of keeping BLOCK1's scope around until BLOCK2 succeeds or fails.
That is, in terms of lexical scoping:
{BLOCK1} andthen {BLOCK2}
needs to work more like
{BLOCK1 andthen {BLOCK2}}
This might be difficult to arrange as a mere module. However, with rewriting rules it might be possible to install the requisite scoping semantics within BLOCK1 to make it work like that. So I don't think this is a primitive in the same sense that continuations would be. For now let's assume we can build backtracking operators from continuations. Those will be covered in a future apocalypse.
RFC 143: Case ignoring eq and cmp operators
This is another RFC that proposes a specific feature that can be handled by a more generic feature, in this case, an operator definition:
my sub operator:EQ { lc($^a) eq lc($^b) }
Incidentally, I notice that the RFC normalizes to uppercase. I suspect it's better these days to normalize to lowercase, because Unicode distinguishes titlecase from uppercase, and provides mappings for both to lowercase.
RFC 170: Generalize =~ to a special ``apply-to'' assignment operator
I don't think the argument should come in on the right. I think it would be more natural to treat it as an object, since all Perl variables will essentially be objects anyway, if you scratch them right. Er, left.
I do wonder whether we could generalize =~ to a list operator that
calls a given method on multiple objects, so that
($a, $b) =~ s/foo/bar/;
would be equivalent to
for ($a, $b) { s/foo/bar/ }
But then maybe it's redundant, except that you could say
@foo =~ s/foo/bar/
in the middle of an expression. But by and large, I think I'd rather see:
@foo.grep {!m/\s/}
instead of using =~ for what is essentially a method call. In line with
what we discussed before, the list version could be a hyperoperator:
@foo . ^s/foo/bar/;
or possibly:
@foo ^. s/foo/bar/;
Note that in the general case this all implies that there is some
interplay between how you declare method calls and how you declare
quote-like operators. It seems as though it would be dangerous to
let a quote-like declaration out of a lexical scope, but then it's
also not clear how a method call declaration could be lexically
scoped. So we probably can't do away with =~ as an explicit marker
that the thing on the left is a string, and the thing on the right
is a quoted construct. That means that a hypersubstitution
is really spelled:
@foo ^=~ s/foo/bar/;
Admittedly, that's not the prettiest thing in the world.


