isArray and std.container.Array

monarch_dodra via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Sep 29 06:30:05 PDT 2014


On Monday, 29 September 2014 at 10:18:09 UTC, Marc Schütz wrote:
> On Sunday, 28 September 2014 at 20:24:11 UTC, monarch_dodra 
> wrote:
>> On Sunday, 28 September 2014 at 19:06:09 UTC, Marc Schütz 
>> wrote:
>>> On Sunday, 28 September 2014 at 16:12:53 UTC, Meta wrote:
>>>> On Sunday, 28 September 2014 at 08:01:00 UTC, Nordlöw wrote:
>>>>> Is there a reason why isArray!T doesn't match T when T is a 
>>>>> std.container.Array? I'm asking because after looking into 
>>>>> msgpack-d because of
>>>>>
>>>>> http://forum.dlang.org/thread/aclapseyptgcwntdavwt@forum.dlang.org#post-aclapseyptgcwntdavwt:40forum.dlang.org
>>>>>
>>>>> I realized that this is the reason why msgpack doesn't 
>>>>> correctly pack std.container.Array.
>>>>
>>>> It's just an oversight in isArray as far as I can tell. I 
>>>> don't know if there's any specific reason that Array is not 
>>>> considered an array.
>>>
>>> I don't think so. std.container.Array is just a data 
>>> structure that behaves like an array, but there could be 
>>> countless other user defined data structures. It should not 
>>> get preferred treatment over those other types. At most, 
>>> isArray could check for the presence of .length, .ptr and 
>>> indexing/slicing. But I think isArray was intended 
>>> specifically for built-in arrays. It's description "is an 
>>> array (static or dynamic [...])" is probably meant to express 
>>> that, because it lists static and dynamic arrays, but doesn't 
>>> mention array-like containers.
>>
>> Yes, everything here is correct.
>>
>> Interestingly though, "Array" is not actually "array-like" 
>> (it's not a range, it doesn't slice), however "Array.Range" 
>> *is* an array-like structure.
>>
>> In regards to "isArrayLike", it would probably be more 
>> interesting to instead integrate it as a "isRandomAccessRange" 
>> range refinement, which would also allow "opSlice" operations, 
>> eg (myRange[0 .. 3] = 5).
>>
>> As for ".ptr", I think no range *trait* should expose 
>> (require) that, as it would most probably be an underhanded 
>> way to leak some abstraction, which would be better expressed 
>> as a direct call *prior*, rather than a range proper. EG:
>> myRange.ptr[0 .. 10].doSomeOperation();
>
> The question is whether you want to call something "array-like" 
> if it isn't stored contiguously in memory. Most algorithms 
> don't depend on it, but it's a significant divergence from what 
> isArray guarantees.

Right, but just because it *is* stored contiguous in memory don't 
mean you want to expose it. Array.Range is contiguous in memory, 
but it does not provide ".ptr".

Also, queue-like containers are not "fully" contiguous in memory, 
so *couldn't* expose ".ptr". They'd still get major benefit from 
"myRange[]=5" though.

Because of that, I think a trait like "isArrayLike" requiring 
full array-like behavior is not very useful. Rather, just 
"isSliceOpRange" would be better.


More information about the Digitalmars-d-learn mailing list