In a message dated Thu, 31 Aug 2006, Juerd writes:
Hm. I don't know how "but" works exactly, but in the realm of syntactic
sugar, this is appealing:
$foo but s/foo/bar/
I like it.
This should be easy to make work in theory, but for the problem with
C<but>'s semantics which I'll get to in a moment. C<but> can already take
a closure in addition to a role or enum:
my Point $p .= new;
$p.x = 3;
$p.y = 0;
my Point $z = $p but { .y = 17 };
in which case,
$x but { ... }
just translates into
do given $x { ...; $_ }
So extending it so that
$x but s/foo/bar/
just translates into
$x but { s/foo/bar/ }
seems like very simple and natural sugaring. You can obviously already use
that latter syntax of simply wrapping the substitution in a closure.
Except distressingly it doesn't do anything....
I think these semantics are Almost Right, but yet Entirely Wrong. The
problem is that C<but> reads to me as a *mutating* operator. That is, I
would expect the above code snippet to give me a C<$z.y> of 17, but leave
C<$p.y> as 0. Surely this is what one would expect from analogy of
0 but True
which I wouldn't think anyone wants to cause all uses of 0, from then on,
to booleanize true.
But yet C<but> with a closure doesn't copy, given the translation above,
or even allow modification, since C<given> doesn't either. $_ (in the
above case, $p) is set to point to the same object, and so $p.y and $z.y
are both modified (or rather, they both refer to the same object, which is
modified during assignment).
In other words, I would actually expect
$x but { ... }
to translate to
do given $x -> $_ is clone { ...; $_ }
where C<is clone> is a conjectural way of calling .clone if the argument
is an object type but reduces to C<is copy> if the argument is a value
type. (Neglecting for the moment that a pointy block doesn't appear to be
a valid argument for C<given>. Is this correct? If so, why?)
I do not think that C<but> should mutate its LHS, regardless what its RHS
is.
Trey