Autrijus Tang wrote:
Imagine:
pugs> '1.28' * '2.56'
3.2768
What is (or should be) going on here here?
My personal favorite is
[5] none of the above -- that should be a type error. ;)
But only if MMD doesn't find a unique handler. That is I would
favor 'type error' =:= 'no handler || ambiguous handlers' where
ambiguous means most specific with respect to all parameters
and not Manhattan distance. But again: mind the sig ;)
I further think that &infix:<*> is either simply implemented
for :(Any,Any) and relies on &prefix:<+> to retrieve the
numerical value of both operands, or it is overloaded for
one( :(Str,Str),
all( :(Str,Str), :(Num,Num), :(Str|Num,Str|Num) )
).
The last :() in the &all might be surprising, but it is needed to
avoid 1.28 * '2.56' beeing ambiguous in symmetrical MMD. Good
style would be to let homogenous overloads &infix:<*>:(::X,::X)
return ::X to keep the semantics of '*' as multiplication in a
type as set interpretation. Actually letting &infix:<*>:(Any,Any)
return a Num might force all more specific multis to return at most
Num or produce type errors.
All that said, and under the assumption that the types of literals
are known at compile time, I'm basically opting for a modified [2]:
multi sub infix:<*> (Str $x, Str $y) returns Str { ... } which
might be an optimized version that uses lowlevel types and doesn't
dispatch two times to &prefix:<+>. But the language semantics can
be achieved with &infix<*>:(Any,Any --> Any). Note, that this -->
is not part of the current syntax but type theorists will find it
very intuitive.
pugs> '1.28' * '2.56'
'3.2768'
--
$TSa == all( none( @Larry ), one( @p6l ))