On Sat, Oct 22, 2005 at 06:00:38AM -0400, Damian Conway wrote: : Autrijus wrote: : : >Indeed. Somehow I think this makes some sense: : > : > sub Bool eqv (|T $x, |T $y) { ... } : : Except that it prevents anyone from ever writing: : : multi sub circumfix:<| |> (Num $x) { return abs $x } : multi sub circumfix:<| |> (Vec $x) { return $x.mag } : : which many mathematically inclined folks might find annoying. : : (It also precludes intriguing possibilities like: : : multi sub circumfix:«| >» ($q) { return Quantum::State.new(val => $q) : } : : which I personally would find irritating. ;-)
I considered | last week, but decided it was better to hold unary | in reserve, especially since it's likely to be confusing with junctions. And if we use | for type set notation, then unary | would preclude the ability to stack types, and I've been treating an utterance like my Mammal ¢T $fido where Bark :($a,$b,$c --> Wag) as having at least five implicitly ANDed type specifications: must do Mammal must do Class must do Scalar must do Bark must do Wag plus there must be three components that are Scalar, plus whatever extra type constraints Wag puts onto those three components. Having Mammal |T be ambiguous with Mammal|T would be bad, at least visually. Anyway, having mulled over all this while off in Amsterdam and Budapest, my current thinking is that the ascii shortcut for ¢T is simply "class T", so you could write any of: sub Bool eqv (¢T $x, T $y) sub Bool eqv (class ¢T $x, T $y) sub Bool eqv (Any ¢T $x, T $y) sub Bool eqv (Any class T $x, T $y) and mean the same thing. Basically, ¢T is a close analog of &t, which is the variableish form for "sub t". When used in a declaration, both of them introduce a bare name as an alias into whatever scope the declaration is inserting symbols, albeit with different syntactic slots. So just as my &t := { ... } introduces the possibility of t 1,2,3 so also a my ¢T := sometype(); introduces the possibility of my T $x; Use as an rvalue can be either T or ¢T without declaring a new type. We're probably converging on a general rule that two or more declarations of the same variable in the same scope refer to the same entity: my $x = 1; # outer $x; { $x = 2; # bound to OUTER::<$x> if my $x = foo() {...} # new $x declared here if my $x = bar() {...} # same $x, "my" is optional baz(); # baz sees single inner CALLER::<$x>. } So too these would mean the same thing: sub Bool eqv (¢T $x, T $y) { my T $z; } sub Bool eqv (¢T $x, ¢T $y) { my ¢T $z; } Only the first declarative ¢ actually installs a new symbol T. An inner scope would of course establish its own type space, but the formal parameters to a block count as part of the block, which is why the second form above applies the existing T to $z rather than capturing the type of $z. But it's a bit like writing &foo() when you could just say foo() instead. Larry