HaloO Larry,

you wrote:
On Thu, Jun 30, 2005 at 09:25:10AM +0800, Autrijus Tang wrote:
: Currently, does this:
: : sub foo (::T $x, ::T $y) { } : : and this: : : sub foo (T $x, T $y) { } : : Means the same thing, namely : : a) if the package T is defined in scope, use that as the
:       type constraint for $x and $y
: : b) otherwise, set ::T to be the most immediate common supertype
:       of $x and $y.
: : Is this understanding correct? I'd like to disambiguate the two cases
: by making ::T in parameter list to always mean type variable (sense b),
: and the bare T always mean type name (sense a)?

I think it would be good to distinguish those, but I've been mulling
over whether ::T should be the syntax for b.  (And also whether b
is the "correct" way to think about it in Perl 6.)  The problem with
using ::T for "autovivify your type from the argument" is that ::($x)
doesn't mean that, and it looks like it should.

I think the point is that using a type variable in the signature of a sub
is too subtle for recognizing it as a type function that produces typed
subs. Thus---even if it resembles C++ templates---I suggest to put the
type parameters onto the sub:

sub foo[T] (T $x, T $y) { }

which basically constrains $x and $y to have the same type. A call
to &foo might automatically instanciate appropriate implementations.
With MMD and all methods and attributes beeing virtual this could
usually be a no-op as far as the code generation is concerned.
But the type checker has to know what constraints are in effect.


The syntax for explicit selection could be foo:(Int)('3','2') which
prevents the interpretation &foo:(Str,Str). OTOH, this might overload
the :() too much. Could we invent more colon postfix ops?
Thus the above were foo:[Int]('3','2'). And while we are at it
since () is more call-like and [] lookup-like we could reserve :()
for more complicated type literals and use :[] for formal type signatures
on subs as it is the case for roles.


 The :: does imply
indirection of some sort in either case, but it's two very different
kinds of indirection.  ::($x) can't declare a lexical alias for
some type, whereas ::T presumably could, though your formulation seems
more of a unificational approach that would require ::T everywhere.

In other words, if we do type binding like b, we would probably want to
generalize it to other binding (and assigning?) contexts to represent
the type of the bound or assigned object, and at the same time create
a lexical alias for the bare type.  So we might want to be able to say

    ::T $x := $obj;
    my T $y = $x;

The prime use of that feature is to ensure type homogenity for
temporary and loop vars in a certain scope. But the scope in the
above syntax is not apparent enough---to me at least.
Thus I opt for an explicit

   subtype T of $obj.type; # or just $obj perhaps?
   T $x := $obj;
   my T $y = $x;

With my proposal from above the short form could be

   :[T] $x := $obj;
   my T $y = $x;

or the current form with :()

   :(T) $x := $obj;
   my T $y = $x;


Regards,
--
TSa (Thomas Sandlaß)


Reply via email to