Argumnentation against external function operator overloading is unconvincing

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Sun Sep 25 04:48:38 PDT 2016


On Sunday, September 25, 2016 10:58:24 pineapple via Digitalmars-d wrote:
> On Sunday, 25 September 2016 at 04:06:41 UTC, Jonathan M Davis
>
> wrote:
> > Considering that a random access range is essentially an
> > abstraction for a dynamic array and that ranges were designed
> > with that in mind, I don't know how you can argue that dynamic
> > arrays shouldn't be treated as ranges.
> >
> > The auto-decoding is certainly an issue, but that only affects
> > ranges of char and wchar. The vast majority of dynamic arrays
> > are perfectly normal ranges.
> >
> > - Jonathan M Davis
>
> Phobos' range facilities vomit when you try to deal with static
> arrays, and they have to be coerced into dynamic arrays before
> they can be dealt with. This is silly.

Except that static arrays are bona fide containers, and their length can't
be mutated. They don't make any sense as ranges at all.

> It gets under my skin that length and opIndex and opSlice produce
> different results in phobos' ranges depending on one's current
> position in the range. This doesn't make sense to me, and the
> only reason I can conceive of it having become how ranges work
> throughout phobos is because that's how dynamic arrays work if
> you force them to act as though they were ranges.

It's because ranges are effectively a sliding window over whatever they're
iterating over. The only way that it would make sense for slicing or
indexing a range to refer to anything other than what the range currently
refers to is if there were some sort of container that they were a slice of,
and the vast majority of ranges aren't that way. They're not designed to
refer to anything other than what they currently refer to, and there is no
original for the indices to refer back to. A range is simply a list of
values. It may or may not be randomly accessible, and it may or may not
refer to anything else like a container. It could be purely generative (e.g.
a range over the fibonacci sequence or an infinite list of random numbers).
It really makes no sense for indexing or slicing ranges to do anything but
have the indices treat the current front of the range as index 0. I can
understand that that might be confusing at first if you're thinking of them
as specifically refering to elements of a container, but many ranges have
nothing to do with a container at all.

> In every single other language I've used, the concept of an
> Iterable and an Iterator are distinct and very separate. An
> Iterator is something that can be iterated over; an Iterable is
> something which can produce an Iterator for iterating over its
> contents. In D, arrays are Iterables, and phobos endeavors to
> force them to be Iterators as well. It defies years of basic
> design wisdom regarding how to differentiate a collection and the
> means by which one enumerates the items in that collection.
>
> Arrays are Iterables which should be able to produce an Iterator,
> in D's case a range. They should not themselves be Iterators.

Dynamic arrays aren't really containers in D. Unlike containers, they don't
own or manage their own memory. They're only slices of that memory. The fact
that you can append to them, and the GC will then increase the amount of
memory that the dynamic array refers to (possibly allocating a new block of
memory and changing which block of memory the dynamic array is a slice of)
certainly muddies things, but it's still not the case the dynamic array owns
or manages its memory. What owns or manages the memory depends entirely on
what allocated the memory (usually the GC, but not always). Even in the case
of concatention or appending, its the GC that manages the memory, not the
dynamic array (e.g. a dynamic array which is a slice of malloced memory is
going to result in a memory leak if you then append to it, and nothing else
was keeping track of that memory; the array itself doesn't know or care who
owns or manages its memory). And multiple dynamic arrays can refer to
exactly the same block of memory, which is a clear indicator that they don't
own or manage their own memory. And in that respect, they're definitely more
like iterators than containers.

So, yes, dynamic arrays in D are weird hybrids, but aside from operations
related to concatenation or appending, they don't act like containers at
all. They act much more like a pair of iterators being passed around
together. And both the language and Phobos are very consistent about that.

The one place with dynamic arrays and ranges that is totally wacko is narrow
strings, because they're auto-decoded, because then Phobos tries to stop
treating them like dynamic arrays. If it didn't do that, AFAIK it would be
completely consistent with how it treated dynamic arrays.

I think that you'll have an easier time understanding dynamic arrays in D
and ranges in general if you stopped trying to treat dynamic arrays as if
they were containers, since they really aren't. And the few operations that
make them sort of act like containers are not part of the range API and
therefore don't conflict with ranges at all.

- Jonathan M Davis



More information about the Digitalmars-d mailing list