Hi Craig and Takeshi --
David's response came in while I was writing mine (woke up this morning
thinking "Oh, we never replied to that question!"), but just to add a few more
things:
* I agree with Takeshi that this would make a great Stack Overflow Q&A if
Craig (or someone) were willing to post the question there.
* we've considered supporting binary operator overloads as methods on
classes and records at times, but have not yet become sufficiently motivated to
do so. Note that one interpretation of the way Craig wrote it is that, being a
method, it's a ternary operator, taking `this`, `lhs`, and `rhs`. Instead, I
suspect that if we supported `=` as a method, it would need to be written
something like `proc =(lhs: T)`. Mostly what's happening here today, though,
is that the compiler is naively looking for a certain signature for `=`
overloads as a standalone function and is not finding it. This could be filed
as an error message improvement issue on GitHub to help provide users more
detail (e.g., hinting them to define operator overloads as standalone
functions, not methods)
* Here's yet another way to write this overload, though I think David's way
is cleaner. In this form, I'm asserting that `lhs` can be any instantiation of
A, but am not binding the type variable to any identifier; and then am using a
type query on the `lhs` I get (`lhs.T`) to constrain rhs:
proc =(ref lhs: A(?), rhs: lhs.T) {
lhs.val = rhs;
}
* Just to round things out (in case it's not obvious), similarly, Takeshi's
version could similarly be written:
proc =( ref lhs: A(?), rhs ): void where lhs.T == rhs.type {
lhs.val = rhs;
}
Hope this is helpful,
-Brad
________________________________
From: David Iten <[email protected]>
Sent: Wednesday, June 13, 2018 7:29:20 AM
To: Takeshi Yamamoto; Craig Reese; [email protected]
Subject: Re: record assignment overload within record definition?
Hi Craig,
You can use a queried type for the formal argument for 'A' to get the behavior
you're looking for. I'd move the definition for 'proc =' outside of the record
and define it as:
proc =(ref lhs: A(?T), rhs: T): void {
lhs.val = rhs;
}
The query expression is defined in section 10.8 of the language specification:
https://chapel-lang.org/docs/1.17/_downloads/chapelLanguageSpec.pdf .
The reason Takeshi's where clause version hits an error when 'T' has a default
type is that when the type for 'T' is left off of the formal argument it takes
on its default type, in this case 'A(real)'.
So:
proc =(ref lhs: A, rhs): void where lhs.T == rhs.type ...
Is equivalent to:
proc =(ref lhs: A(real), rhs): void where lhs.T == rhs.type
Because of this, there is no '=' function that matches for the 'ai = 100;'
line, so the assignment results in a type mismatch error.
Thanks,
David
On 6/12/18 5:13 PM, Takeshi Yamamoto wrote:
Hi Craig,
I'm also still learning Chapel so not veryn sure whether
this is the right way, but the following seems to work (with
chapel v1.16 on my computer):
record A {
type T;
var val : T;
}
proc =( ref lhs: A, rhs ): void where lhs.T == rhs.type {
lhs.val = rhs;
}
var ar: A( T = real );
ar = 1.23;
show( ar );
var ai: A( int );
ai = 100;
show( ai );
var astr: A( string );
astr = "hi";
show( astr );
proc show( arg: A ) {
writeln( "val = ", arg.val, " T = ", arg.T:string );
}
Results:
val = 1.23 T = real(64)
val = 100 T = int(64)
val = hi T = string
But if I add the default type to 'T' as
record A {
type T = real;
var val : T;
}
the program gives an error:
type mismatch in assignment from int(64) to A(int(64))
I don't know why this error occurs... (and hope other people will
give more hints :)
PS. I guess asking a question on Stackoverflow may also be useful,
because other people (not subscribing to this list) can see the Q/A also.
Best,
Takeshi
2018-06-13 5:24 GMT+09:00 Craig Reese
<[email protected]<mailto:[email protected]>>:
Chapel 1.17.1 newbie question (my real effort is much more complicated, but
this illustrates the issue):
record A {
type T = real;
var val : T;
proc =(ref lhs: A, rhs : T) : void {
lhs.val = rhs;
}
}
yields:
assign.chpl:4: warning: The left operand of '=' and '<op>=' should have 'ref'
intent.
There are a couple work arounds:
1) put the "proc =" outside the record (but then the T type is no longer
visible).
2) 1+ move "type T" outside the "record" (though it really doesn't otherwise
need that wider visibility).
I've run into this in a number of larger cases. Is there some magic to doing
assignment as a member vs.
non-member function?
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Chapel-users mailing list
[email protected]<mailto:[email protected]>
https://lists.sourceforge.net/lists/listinfo/chapel-users
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Chapel-users mailing list
[email protected]<mailto:[email protected]>
https://lists.sourceforge.net/lists/listinfo/chapel-users
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Chapel-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/chapel-users