On Mon, Jul 04, 2005 at 04:09:59PM +0200, "TSa (Thomas Sandlaß)" wrote:
: 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.

Well, there's something to be said for that, but my gut feeling says
that we should reserve the explicit generic notation for compile time
processing via roles, and then think of run-time lazy type aliasing
as something a little different.  So if you really want to write
that sort of thing, I'd rather generalize roles to work as modules
containing generic subs:

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

Otherwise people are tempted to scatter generics all over the
place, and it's probably better to encourage them to group similarly
parameterized generics in the same spot for sanity.  It also encourages
people to instantiate their generics in one spot even if they're
calling them from all over.

: 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.

I think people should say "does FooStuff[Int]" and automatically alias
all the routines to the Int form so we don't have to scatter :[Int]
all over.  Or if they just say "does FooStuff", they get lazily-bound
type parameters.

: > 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.

Actually, I was holding those up as bad examples of scope visibility,
so I'm agreeing with you there.  (Which is why I suggested that we
require a "my" context, even if only implied by the formal paramter list.)

: Thus I opt for an explicit
:    subtype T of $obj.type; # or just $obj perhaps?
:    T $x := $obj;
:    my T $y = $x;

Yuck.  I think that completely obscures the lazy type binding.
Plus you've managed to omit the "my", so you've created a global
subtype T.  (Unless, as I'm leaning towards, we make such bare "inner"
types illegal, and require "my", "our", or "*".)

: 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;

I think any lexically scoped declaration should be governed by a "my"
(either explicitly or implicitly), and that includes type declarations.
A bare :[T] or :(T) outside a declaration is not good enough.
It's okay if there's already a "my" outside, in which case you're
declaring both the variable and the type, but there also needs to
be a way of scoping "my" to the type without declaring the variable.
I want to be able to distinguish

    my (T) $x := $obj


    (my T) $x := $obj

And maybe that's just how we should leave it.  I confess that

    my [T] $x := $obj
    [my T] $x := $obj
    method foo ($self: [T] $x) {...}

are prettier, and more reminiscent of generics, but I worry about
confusiion with [$h,[EMAIL PROTECTED] bindings, and with reduction operators.
On the other hand, (T) looks like a cast, and [T] isn't *really*
all that ambiguous.  Given how often these things will occur in
other contexts that use colons for other things, I don't think it's
a very good plan to go with :[T].  These are visually confusing:

    my :[T] $x := $obj
    method foo ($self: :[T] $x) {...}

Bare [T] would preclude its use in rvalue context, however, as it
might be taken as a reduction operator.  No big loss, in my estimation.
Could maybe allow [my T] there, I suppose.


Reply via email to