Hi Damian —
I'm assuming that in the example you're asking about, you're calling it
with real values like:
var r1 = 1.2,
r2 = 3.4;
var x = max(r1, r2);
??
In general, when given a choice between a precise routine:
proc foo(x: real) { ... } // x must be a real (real(64))
And a generic one:
proc foo(x: ?t) { ... } // x can be any type
The first overload is chosen because it's a more precise match. This also
extends to families of built in scalar types like:
proc foo(x: real(?w)) { ... } // x can be real(32) or real(64)
because it's still a more precise match than the fully generic one. One
other way in which things can go wrong is if your call was actually:
max(1.2, 3.4);
since 1.2 and 3.4 are param values (known to the compiler), an overload
like:
proc foo(param x: real, param y: real) param { ... }
would be a better match since it takes param values and yours doesn't.
Note that in the routine you show below, the use of ': ?Real' on the first
argument says "I don't know what type 'x' will be, but whatever it is,
let's call it 'Real' for the rest of this routine." So it's very generic
rather than being very precise (you could pass in two ints, two strings,
two records of type 'R', etc.) I.e., your routine is identical to:
proc max(x: ?t, y: t): t { ... } // x can be any type, y must
// be a compatible type; the
// routine will return x's type
So the built-in version that takes two reals is still a better match /
more precise since it's specific to reals and this one is not.
If you were to create a function that was an equally good match (or
better) yet was "lexically closer" to your call, you could override the
built-in version as shown in the following example:
https://tio.run/##VY1BCsIwFET3OcXQVVJLaerO4AE8RghRA@lv@VRNEM8eGwqCqxmGNzPubhcfS3EzXcMNT8tgjTN0P3TgcXNDr40QC88Ok00yncDexg55N2oXvAXw4rD6SLK5EKZc8UaZLWe/PpgwtgkHHNtsxOe3GEiqv3I9YV3PlapgKV8
Also, when reasoning about cases like this when it's unclear why the
compiler is choosing a particular overload the --explain-call flag can be
very useful. As an example, for the program at the TIO link above, if I
saved the code and compiled it as:
chpl --explain-call=max:8 myProgram.chpl
the option says "explain how you resolved the call named 'max' at line 8
in my source" (there's also a format to name the file in case multiple
files have a call named max at line 8, but in practice this doesn't happen
often, so I usually skip the filename for simplicity; the 'chpl' man page
should have more details).
Hope this helps,
-Brad
Brad Chamberlain Principal Engineer
Cray, a Hewlett Packard Enterprise company
901 Fifth Ave, Suite 1000 | Seattle, WA 98164
+1-206-701-2077 [email protected] www.cray.com
On Sat, 14 Mar 2020, Damian McGuckin wrote:
I noticed that when I defined my own generic routine
proc max (x : ?Real, y : Real) : Real
and then called in it a 'proc main', Chapel ignored my routine and used the
generic routine from the Math module to create a real(64) routine which it
then proceeded to call rom my 'proc main'. Mine got lost.
Is this deliberate?
Regards - Damian
Pacific Engineering Systems International, 277-279 Broadway, Glebe NSW 2037
Ph:+61-2-8571-0847 .. Fx:+61-2-9692-9623 | unsolicited email not wanted here
Views & opinions here are mine and not those of any past or present employer
_______________________________________________
Chapel-developers mailing list
[email protected]
https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.sourceforge.net_lists_listinfo_chapel-2Ddevelopers&d=DwICAg&c=C5b8zRQO1miGmBeVZ2LFWg&r=QUQW-BniEL_d2a7btR4rP5TPiNmpm1pG-Qa_xXzGVKc&m=OGTIQF6QKKiLQaaKkCrBnFSaiJLR5udFPW2uHyRfNUY&s=MR_w1kItGECbIX7wp3KZYfJNVM9hFG0R1eMEjIZzHu0&e=
_______________________________________________
Chapel-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/chapel-developers