www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - What should array() return for const/immutable ElementTypes?

reply "David Nadlinger" <see klickverbot.at> writes:
The title says it all – currently, std.array.array() is broken 
for (some) ranges of const/immutable elements. Fixing it is not 
hard, but the question is: Should it always return an array of 
(head-)mutable elements (since it allocates a copy anyway), or 
should it preserve constness of the element type?

The latter is maybe be the more »consistent« behavior, as the 
return type would always just be ElementType!Range[], but has the 
disadvantage that if you actually wanted to construct a mutable 
array from an immutable range, you'd have to cast away immutable 
(with unclear semantics), whereas getting an immutable array with 
the first implementation would just require assumeUnique() (for 
most ranges, array() is not going to be strongly pure).

I have a fix ready, but will hold back the pull request until it 
is clear which semantics we want.

Thanks,
David
May 05 2012
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
David Nadlinger:
 Should it always return an array of (head-)mutable elements 
 (since it allocates a copy anyway), or should it preserve 
 constness of the element type?

Ideally the most useful result is a mutable one that is implicitly castable to immutable if the mapping function is pure. But I don't know if this is always possible. Bye, bearophile
May 05 2012
prev sibling next sibling parent "David Nadlinger" <see klickverbot.at> writes:
On Saturday, 5 May 2012 at 17:48:34 UTC, bearophile wrote:
 Ideally the most useful result is a mutable one that is 
 implicitly castable to immutable if the mapping function is 
 pure. But I don't know if this is always possible.

Implicit conversion to immutable would only work if array() is strongly pure, but this would require the passed in range type to have no non-immutable indirections (besides needing a pure implementation of array(), which is currently not the case due to appender, but this can be fixed). OTOH, I think it _could_ work for ranges operating on originally immutable data, but it seems like it doesn't typecheck in today's DMD/Phobos: ——— auto array(Range)(Range r) if (isIterable!Range && !isNarrowString!Range) { alias Unqual!(ForeachType!Range) E; E[] result; foreach (e; r) result ~= e; return result; } void main() { immutable x = [1, 2, 3]; immutable y = array(filter!"a == 3"(x)); } ——— David
May 05 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, May 05, 2012 18:57:05 David Nadlinger wrote:
 The title says it all =E2=80=93 currently, std.array.array() is broke=

 for (some) ranges of const/immutable elements. Fixing it is not
 hard, but the question is: Should it always return an array of
 (head-)mutable elements (since it allocates a copy anyway), or
 should it preserve constness of the element type?
=20
 The latter is maybe be the more =C2=BBconsistent=C2=AB behavior, as t=

 return type would always just be ElementType!Range[], but has the
 disadvantage that if you actually wanted to construct a mutable
 array from an immutable range, you'd have to cast away immutable
 (with unclear semantics), whereas getting an immutable array with
 the first implementation would just require assumeUnique() (for
 most ranges, array() is not going to be strongly pure).
=20
 I have a fix ready, but will hold back the pull request until it
 is clear which semantics we want.

I think that std.array.array should return an array of exactly the same= =20 element type as the range that was passed to it. If those elements are = const=20 or immutable in the range, then they're const or immutable in the array= . What _would_ be valuable would be for std.array.array to have another t= emplate=20 parameter allowing you to indicate the element type of the array (and w= hich=20 worked with type which the original element type was implicitly convert= ible=20 to, with the possible addition of making char and wchar arrays work wit= h=20 ranges of dchar). Naturally, it would default to the exact same type, b= ut it=20 would allow you to get an array of varying constancy without dup, idup,= or=20 casting. - Jonathan M Davis
May 06 2012
prev sibling next sibling parent "David Nadlinger" <see klickverbot.at> writes:
On Monday, 7 May 2012 at 00:22:56 UTC, Jonathan M Davis wrote:
 What _would_ be valuable would be for std.array.array to have 
 another template
 parameter allowing you to indicate the element type of the 
 array […]

Thanks a lot for the suggestion, that seems like a good way to solve the problem indeed. Any other comments? David
May 07 2012
prev sibling parent "David Nadlinger" <see klickverbot.at> writes:
On Monday, 7 May 2012 at 00:22:56 UTC, Jonathan M Davis wrote:
 What _would_ be valuable would be for std.array.array to have 
 another template
 parameter allowing you to indicate the element type of the 
 array […]

Thanks a lot for the suggestion, this indeed seems like a good solution. Any other comments? David
May 07 2012