A slice can lose capacity simply by calling a function

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun May 3 23:23:41 PDT 2015


On 05/03/2015 06:06 PM, Jonathan M Davis via Digitalmars-d-learn wrote:

 > On Sunday, May 03, 2015 15:21:15 Andrew Godfrey via 
Digitalmars-d-learn wrote:
 >>
 >>> I really don't think that it's an issue in general, but if you
 >>> do want to
 >>> guarantee that nothing affects the capacity of your array, then
 >>> you're going
 >>> to need to either wrap all access to it
 >>
 >> I agree with everything Jonathan said in both threads EXCEPT that
 >> this is not an issue.
 >>
 >> The syntax "slice.capacity" gives the impression that 'capacity'
 >> is a property of the slice.
 >>
 >> Such lack of consistency is a SERIOUS issue for D, especially
 >> when it occurs in something as basic as an array.
 >
 > I really don't see the problem. It's a natural side effect of how dynamic
 > arrays work in D.

The problem is described in those two sentences of yours: The behavior 
of a language construct depends on the implementation detail. 
Unfortunately, it is backward. Normally, the semantics would be layed 
out and then those semantics would be implemented.

It is not the case with D's dynamic arrays.

(Aside: Heck, we (at least you and I) can't even decide whether dynamic 
arrays and slices are the same thing. (For the record, yes, they are the 
same thing from every vantage point: They have the same semantics and 
they are implemented in the same way.))

Saying that there is no problem would be contradicting yourself. These 
are your quotes from the following thread:

 
http://forum.dlang.org/thread/mhtu1k$2it8$1@digitalmars.com#post-mailman.597.1430448607.4581.digitalmars-d-learn:40puremagic.com

- "it seems like so few people understand it"

- "pretty much everyone has trouble with them initially"

- "I _still_ occasionally end up \"Aha!\" moments"

So, yes, this is a problem.

The problem is even worse because we can't come up with a consistent way 
of describing the semantics after the fact (after how they are 
implemented). The following are some of my attempts:

   "sharing may terminate when the length of the slice increases"

   "capacity is first-come first served"

However, they are only mostly correct, not always. And that's the part 
that is frustrating the most: There is no way of "understanding" the 
semantics so that one can "explain" them to at least to one's self.

 > The only thing I can see that could be changed without

Please note that at least I am not interested in changing anything: I am 
interested in a way of explaining the semantics. I could not find that 
way yet. (I am eagerly waiting for your DConf talk to see how you make 
sense of it all.)

 > You'd still have to understand how D's
 > dynamic arrays work to understand how the capacity for a dynamic array
 > works.

I am happy that I do my part by opening threads like this one to shine 
more light on what array capacity is not.

 > And most code really doesn't care about the capacity of an array. If
 > you profile and find that appending to an array is a hot spot in your
 > program, then you dig in and use reserve or Appender or use something 
other
 > than a naked array, and you figure out what works best for your 
particular
 > use case, but for most code, it just works to use ~=. And if you're
 > concerned about reallocations even before profiling, then it's trivial to
 > just call reserve first or to use Appender. And unless you're doing
 > something like constantly slicing and appending to each slice (which I
 > expect to be a rare thing to do), you're really not going to run into
 > problems.

I am sorry but that is missing the point. This issue is not only about 
performance.

Note that I may not be the only programmer who writes the entire 
application. Imagine that I write a function inside a library. Do I have 
the *right* to append to my parameter slice? Do I have the right to 
disturb my caller's slice? The answer is a resounding NO, in capital 
letters. If I lose my caller's potentially precious and carefully 
crafter capacity, perhaps after a call to reserve(), then I am a bad 
library function.

As a programmer, I need guidelines. Here is what I have at this point: 
Never append to a parameter slice.

 > Sure, the semantics of D's dynamic arrays take some getting used to -

Yes, they do: I started learning D about 6 years ago. How many years 
more do you reckon until I get them?

 > especially if you want to understand all of their ins and outs.

Yes I do.

 > But I really
 > don't see why it's a big problem.

I said it before why it's a big problem: "The elements are const, the 
slice is passed by value, but the [slice is affected]." The loss of 
capacity itself is not a big deal. However, this behavior conflicts with 
other parts of the language (as well as at least C and C++).

 > For the most part, D's dynamic arrays just
 > work.

I know you are not trolling but I can't take your brushing off this 
issue with phares like "for the most part". That's the frigging problem! 
"For the most part" is not sufficient. Unless somebody explains the 
semantics in a consistent way, I will continue to try to do it myself. 
(Remember: Never append to a parameter slice. Good function, good!)

 >
 > - Jonathan M Davis
 >

Ali



More information about the Digitalmars-d-learn mailing list