"How would you know what types are compatible for a particular operation?"

Operations are functions so the question is the same as "How would you know
what types are compatible for a particular function"

which gets to inspecting a routine's arguments. This SO page helped me
figure that out
https://stackoverflow.com/questions/52515445/how-to-get-all-the-signatures-of-multi-sub-or-build-ins
.

Let's start with a user-defined routine that has coercion in it, taken from
https://docs.raku.org/type/Signature#Coercion_type

> sub foo(Date(Str) $d) { say $d.^name; say $d };
&foo
> say .signature for &foo.candidates;
(Date(Str) $d)

>From that I'd say that routine expects a Date, and can also take a Str
which the Date class would coerce into a Date.
Well from that, and also from knowing the example I got it from

Let's look at addition, the infix + routine- it is a multi with many
candidates

> say 'multi', .signature for &infix:<+>;
multi($?, $?, *%)
> say 'multi', .signature for &infix:<+>.candidates;
multi($x = 0)
multi(\a, \b)
multi(Real \a, Real \b)
multi(Int:D \a, Int:D \b --> Int:D)
multi(int $a, int $b --> int)
multi(Num:D \a, Num:D \b)
multi(num $a, num $b --> num)
multi(Range:D \r, Real:D \v)
multi(Real:D \v, Range:D \r)
multi(Rational:D \a, Rational:D \b)
multi(Rational:D \a, Int:D \b)
multi(Int:D \a, Rational:D \b)
multi(Complex:D \a, Complex:D \b --> Complex:D)
multi(Complex:D \a, Num(Real) \b --> Complex:D)
multi(Num(Real) \a, Complex:D \b --> Complex:D)
multi(Instant:D $a, Instant:D $b)
multi(Instant:D $a, Real:D $b --> Instant:D)
multi(Real:D $a, Instant:D $b --> Instant:D)
multi(Instant:D $a, Duration:D $b --> Instant:D)
multi(Duration:D $a, Instant:D $b --> Instant:D)
multi(Duration:D $a, Real $b --> Duration:D)
multi(Real $a, Duration:D $b --> Duration:D)
multi(Duration:D $a, Duration:D $b --> Duration:D)
multi(DateTime:D \a, Duration:D \b --> DateTime:D)
multi(Duration:D \a, DateTime:D \b --> DateTime:D)
multi(Date:D $d, Int:D $x --> Date:D)
multi(Int:D $x, Date:D $d --> Date:D)

This gives some answers, there isn't much coercion going on, only
"Num(Real)" when adding to a Complex.
The first couple candidates raise questions for me

   1. multi($x = 0) - how is there a single-arg candidate for an infix
   operator?
   2. multi(\a, \b) - does this accept everything, is it a "cleanup"
   candidate for error reporting?

I'm curious about how some candidates bind to bare names \a, \b while
others use sigilled variables, I'm assuming that's due to the original
programmer's style preference.

The set difference operator that Joe also used in the example is similar,
this time with no coercion at all, and a few single-arg candidates that I
don't understand being compatible with an infix operator.

> say 'multi', .signature for &infix:<(-)>.candidates;
multi()
multi(QuantHash:D \a)
multi(SetHash:D \a)
multi(BagHash:D \a)
multi(MixHash:D \a)
multi(\a)
multi(Setty:D \a, Setty:D \b)
multi(Setty:D \a, Map:D \b)
multi(Setty:D \a, Iterable:D \b)
multi(Mixy:D \a, Mixy:D \b)
multi(Mixy:D \a, QuantHash:D \b)
multi(QuantHash:D \a, Mixy:D \b)
multi(Mixy:D \a, Map:D \b)
multi(Mixy:D \a, Any:D \b)
multi(Any:D \a, Mixy:D \b)
multi(Baggy:D \a, Mixy:D \b)
multi(Baggy:D \a, Baggy:D \b)
multi(Baggy:D \a, QuantHash:D \b)
multi(QuantHash:D \a, Baggy:D \b)
multi(Baggy:D \a, Map:D \b)
multi(Baggy:D \a, Any:D \b)
multi(\a, Baggy:D \b)
multi(\a, Map:D \b)
multi(\a, Iterable:D \b)
multi($, Failure:D \b)
multi(Failure:D \a, $)
multi(\a, \b)
multi(**@p)

-y


On Sat, Aug 21, 2021 at 3:59 PM Patrick R. Michaud <pmich...@pobox.com>
wrote:

> On Sat, Aug 21, 2021 at 12:50:21PM -0700, Joseph Brenner wrote:
> > But then, in a case like this one, how would you know in advance
> > that it would work, without Just Trying It:
> >
> >   my @monsters      = < godzilla grendel wormface blob >;
> >   my $cool_monsters = < godzilla ghidra mothera >.Set;
> >
> >   say @monsters.WHAT;          # (Array)
> >   say $cool_monsters.WHAT;     # (Set)
> >
> >   my $just_monsters = @monsters (-) $cool_monsters;
> >   say $just_monsters; # Set(blob grendel wormface)
> >
> > A set difference operation seems to know what to do with arrays,
> > without any explicit conversion steps.  I don't think you can get
> > that just from studying the type graphs
>
> More likely, the set difference operation tries to coerce both of its
> operands into Sets, and arrays know how to make themselves into a Set
> (via the .Set() method inherited from List).
>
> It's much like the way the subtraction operator (&infix:<->) tries
> to coerce its operands into Numeric types, by asking the operands to
> return their "Numeric" value, or the way the concatenation operator
> (&infix:<~>) coerces its arguments into Stringy types.
>
> Pm
>

Reply via email to