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.


Reply via email to