The current intent in the Synopses is that using the :: sigil in a declaration makes it a generic type parameter and declares that name there.

As a minimal fix to make that work, refine it to say that use of :: as a sigil in a declaration on a name that contains only a single identifier (no :: scope parts, no twigils, no funny symbols as names) declares a generic type parameter.

sub (::Type $x) # declares generic type parameter as actual type of $x argument sub (::Type $) # ditto, but don't care what the value is. Value passed though.
  sub (::Type)   # the parameter is a type object.
sub ($x, $y --> ::+RetType) # Not a generic, but the current value of the context variable
  sub (::?CLASS $self, $x, $y)  # Not a generic, but special ? variable
sub ($x, ::Foo::Bar $y) # Not a generic, but current meaning of ::Foo::Bar sub ($x, ::Bar $y) # Generic, defines new Bar and ignores any current meaning

That would fix the problems with cases where you must use the sigil. But I still think the idea smells bad: that the sigil normally means a symbol of a particular type, can be omitted when that kind of symbol is expected, but leaving it on is "normal" and explicit but omitting it is a shortcut; except now the sigil means something different if you don't omit it but only in some places.

I still want to find a positive syntax for declaring generic types that harmonizes better. Many ways suggest themselves, but the hard part is coming up with something succinct. Larry, you never said what you thought of my idea of simply using more colons. That seems to have precedent in the language as it stands. ::::Type is probably the most precedent-harmonizing, but :::Type seems sufficient.

Using more words is not succinct. Using symbol prefixes hard because the grammar is already so crowded, unless you want to use a non-ASCII symbol like ⍈.

But suffixes, there is lots of room available. We already know that it has a :: sigil and a single identifier. Perhaps ::Type! connotes "declare me here", and goes well with the ? suffix of optional parameters.

And I close with this example of generics and signature extraction, because Perl 6 generics needs to be at least as powerful as C++ templates:

   sub (Positional ::Container[of => ::ValType] $x)

makes both Container and ValType available in the scope of the function's block, and ensures that whatever is passed also supports Positional. The only thing is, I had to make the parameter $x not @x. How can I name the container type as a generic, rather than the value type?


Reply via email to