Autrijus Tang wrote:
On Tue, May 03, 2005 at 05:32:44AM -0700, Larry Wall wrote:
: # Type Instantiation?
: sub apply (&fun<::a> returns ::b, ::a $arg) returns ::b {
: &fun($arg);
: }
The first parameter would be &fun:(::a) these days, but yes.
(Stylistically, I'd leave the & off the call.)
I am still advocating for :() beeing the type sublanguage.
But I'm not sure if @Larry are already that far ;)
Why not &fun:( ::a returns ::b )?
So, the "returns" trait is not part of a function's long name, but
it can still be matched against (and instantiated)?
The long name of a function consists of three parts:
1) the invocant type list
2) the parameter type list
3) the return type list
like &code:( Int, Dog : Str returns Bool ). Actually the ?+*
markers should be in there, too. Nesting should work as well,
but might not need the colon?
Hrm, is it specific to the "returns" trait, or we can match against
any traits at all?
Well, I think everything that is part of the type language/system
should go into :(). That IMHO includes does, where and ranges.
This was because I couldn't think of other operators other than ","
to operate on types inside :(). Come to think of it, there are lots
of other things possible:
my $SomeType ::= :((rand > 0.5) ?? Bool :: Int);
I guess this drives the typechecker to the brink of madness---or beyond.
OTOH, junctive types in the sense of glb and lub would be fine in my mind!
Also, is it correct that (4, 2) can be typed as both a :(Eager) list and a
:(Any, Any) tuple? Is it generally the case that we can freely typecast
unbounded list of values from (and to) bounded ones?
Uho, big can of (type)worms! First of all we might run into the
co-/contra-variance
issue of parametric types. Secondly it should work only one way. The other way
round would be a type error unless tuple and list are equal types. The usual
type
theoretic definition of subtyping on tuples is to demand that the subtype
relation
holds pairwise. But note that type theory doesn't really handle imperative
features
very well.
But it makes :(int $x) terribly ambiguous if it's an evaluative
context. (Which is why we wanted :() in the first place, to avoid
such evaluation.)
Ups, I would hope we only have type variables inside of :() expressions,
that is ones prefixed with the :: type sigil. And I would like to see a
constraint language. So that e.g. the classical "feed the animal" method
type can be specified generically:
subtype &eat:( ::a does Animal : does Food of ::a ) of Method;
invocant : parameter
I'm not sure if that syntax is supported, though.
Such a method should be callable on all objects that
1) do the Animal role
2) for which a class exists that does the corresponding Food role
Or more concrete:
class Cow does Animal {...}
class Grass does Food of Cow {...}
class Meat does Food of ::Tiger {...}
sub foo ( Cow $elsa, Grass $green, Meat $raw )
{
$elsa.eat( $green ); # OK
$elsa.eat( $raw ); # error
$_.eat( $raw ); # works if $_.does( Tiger )
}
The above errors might be detectable at compile time,
but not these:
sub bar ( Animal $elsa, Food $green, Food $raw )
{
$elsa.eat( $green );
$elsa.eat( $raw );
}
not to mention something vague like
sub baz ( $x, $y )
{
$x.eat( $y );
.eat; # topic eats itself? Sorry, couldn't resist.
}
Also note that &bar is not necessarily a subtype of &foo because it
depends on Food[Cow] and Food[Tiger] beeing subtypes of Food, while
Cow is a subtype of Animal.
But it might be only me striving for CBP (Constraint Bounded Polymorphism).
YMMV :)
--
TSa (Thomas Sandlaß)