Hi Greg --
Sorry for the delayed response. We had some network reconfigurations
going on Friday which made it a good day to avoid email and get some other
work done.
> 1. What does the declaration of an array as a return type look like?
> 'proc p() : [] int { }' doesn't seem to work, but you can leave
> off the type in the declaration and do 'return arrayvar;' and
> that gets figured out.
At present, I believe that the only two forms are a fully-specified array
type, e.g.:
proc p(): [D] int { ... }
or a fully inferred one:
proc p() { ... }
Ultimately, I think we'd like to support more inferred forms as well, such
as the form you show or:
proc p(): [D] { ... } // infer array's element type, not domain
proc p(): [] { ... } // infer both domain and elt type
> 2. Is this a wise thing to do? Can you return an array that's been
> created in a sub-routine?
> We had thought about doing was get a list of results from one
> sub-routine, where the number wasn't known in advance, for
> processing by another. The code might look like
> var matches : [] 2*(2*int);
> matches = find_matching_points(pts1, pts2);
> where find_matching_points counts the number of matches, creates
> an array to hold them, and then copies the matches into the result
> before returning it. We weren't sure if this would work, though,
> and took another approach.
Yes, you can return an array that's been created in a subroutine, and I
think this is something we're going to want/need to continue to support.
One motivating example, similar to yours, is a helper routine that reads
an array in from a file without knowing how large that array is going to
be.
As you may have seen in other threads, we're currently revamping the way
our automated-memory management is being implemented, and as part of that,
we're reconsidering how this case is implemented today (and how it should
be in the future), but I don't anticipate the feature going away.
Here's a toy sample program that demonstrates creating and returning an
array in a helper routine:
---
proc createarray(n) {
var D = {1..n, 1..n};
var A: [D] real;
forall (i,j) in D do A[i,j] = i: real + j / 10.0;
return A;
}
var B = createarray(3);
writeln(B);
writeln(B.domain);
writeln(typeToString(B.eltType));
var C = createarray(5);
writeln(C);
writeln(C.domain);
writeln(typeToString(C.eltType));
---
> 3. It seems to be a bad idea to put arrays inside records that are
> passed as arguments, because of the pass-by-value behavior. Is
> this a fair statement, or should it be safe?
Barring any bugs, records should be passed by 'const ref' by default, so
should not be copied when being passed around, nor should any array fields
within them. I wouldn't shy away from putting array fields in records for
this reason.
> One sub-routine used an inout intent on a record with arrays that
> it populated.
Note that 'inout' means "copy the record in; copy the record out", as
compared to (say), 'ref' or 'const ref' which says to pass a reference to
the record in/out. (So passing records by 'inout' would result in copies
of their fields).
> It would cause the program to segfault or die with
> a nil dereference about half the time.
I'm not sure what would be causing this, and would be interested in
getting a copy of such a test to look into it further.
> Changing the argument to
> an array of records, and also passing an index into the array,
> was stable (because the array is passed by reference, so it gives
> you access to the arrays inside the record without copying them?).
Huh... Doesn't seem like this should be strictly necessary...
> 4. The spec says that reference assignment for records is under
> discussion (p. 135). Does this also apply to a ref intent for a
> record argument?
No, 'ref' (and 'const ref') intents for record arguments are supported and
should work (AFAIK).
> 5. The spec (p. 170) says that domain.exterior(), interior(), and
> translate() can take a single integer argument, but this causes
> a compilation error.
> const dom : domain(rank=2) = { 1..10, 1..10 };
> writeln("exterior(2,2) ", dom.exterior(2,2));
> writeln("exterior(2) ", dom.exterior(2));
> The first call is accepted, the second produces
[errors]
Huh, you're right... I could've sworn we used to support the
single-integer form of these, so either my memory is off or else someone
retired them without updating the spec. I assume you'd find the
single-argument form a nice convenience? If so, I can dig deeper and see
if they were removed (and if so, why) or if I'm misremembering.
> 6. Many of the internal and standard modules use the low and high
> members of ranges. It seems that first and last would be safer
> if the step size or alignment caused them not to hit low/high
> exactly. Would it be a best practice to use first/last, or is
> the worry unfounded?
It really depends on the use case. For example, the exterior/interior
routines are designed to be in terms of a range's low/high values, even if
those values are not described by the alignment; but when iterating over a
range's value, using low/high can cause problems (and we've recently
found/fixed bugs related to this). The alignment capability of a range is
(relatively) new compared to a lot of the range code, so much of what's
there at present predates it (and other bugs may be lurking as a result --
it seems that the alignment capability has not been used much in
practice). Note that first/last will also take the sign of the stride
into account (e.g., first may be greater than last), so may not always be
what you want -- in such cases, alignedLow/alignedHigh may be the desired
values.
-Brad
------------------------------------------------------------------------------
_______________________________________________
Chapel-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/chapel-users