Is there something special required to use Appender.clear

Steven Schveighoffer schveiguy at gmail.com
Wed Jan 30 16:15:37 UTC 2019


On 1/30/19 7:32 AM, FeepingCreature wrote:
> On Monday, 28 January 2019 at 15:16:54 UTC, Steven Schveighoffer wrote:
>> It will inspect the allocated length from the GC if the array is 
>> appendable from the beginning. So it's not always going to reallocate.
>>
>> e.g.:
>>
>> string x = "abc".idup;
>>
>> auto app = x.appender;
>>
>> app ~= "xyz"; // does not reallocate.
>>
> 
> Fair enough.

Wow, I take this back. I tried it, and it DOES reallocate.

In fact, appender when given data that's not mutable avoids the check 
for appendability, and extension into the block.

So indeed, using appender on a string that is appendable reallocates on 
first append. I agree with you now, Appender on an existing string is 
near useless.

Looks like there were some changes that fix one problem, but may have 
inadvertently created this problem. And I'm rereading my comments in 
this PR, finding that I was not exactly correct on my analysis: 
https://github.com/dlang/phobos/pull/2046

In short, there's a question of purity, which was already on the 
Appender's functions, causing issue with immutable data. I think this 
won't be strong pure anyway, because appender's functions are not 
strong-pure (there's always mutable data inside it).

I think we should avoid the mutability check in that call.

> My problem is this.
> 
> const and immutable are *not* well supported in the standard library at 
> the moment. What I want is that I can use the idioms of the stdlib, 
> semantically, in a way that lets me *not care* about const or immutable, 
> that lets me express the patterns I want without having to worry about 
> whether some type deep inside my code, a dub library, or phobos itself 
> decided to declare a field immutable.
> 
> Appender covers two usecases: "capacity caching" and "memory reuse." 
> Both of those usecases have two const variations: "possibly immutable" 
> and "mutable".
> 
>    mutable capacity caching | mutable memory reuse
> ---------------------------+---------------------
> immutable capacity caching | immutable memory reuse
> 
> But instead of cutting between capacity caching and memory reuse, down 
> the middle, Appender cuts between mutable and immutable, left to right. 
> I think this is a symptom of a broad negligence of constness as a 
> first-class property - constness works sometimes, and it's nice if it 
> does, but it can't be *relied* on to be well supported. This makes using 
> const in D an eternal uphill struggle. Why even go to all the trouble to 
> make a new major version of the language just to introduce constness, if 
> it's not going to be treated as a first-class concern? I don't want to 
> have to sprinkle static if(isAssignable!T) everytime I want to use a 
> library type. If Phobos offers me as generic a data structure as 
> Appender, parameterized on T, it should work for T, regardless of what T 
> is doing, and *certainly* regardless of what fields in T are marked 
> const. Especially considering that if a field is not marked as const, 
> that hardly means it's not going to lead to bugs if its memory is reused 
> while you're referencing it!

Appender covers appending, which works for both mutable and immutable 
data. The clear function, if called on immutable data, would allow for 
immutable data to be overwritten, which is undefined behavior. This 
should be harder to do than just calling a member function.

Note that if we fix the above problem, there is a workaround:

app = app.data[0 .. 0].assumeSafeAppend.appender;

Which includes the greppable assumeSafeAppend property.

The biggest problem I see is not necessarily that immutable arrays 
should be clearable, but that arrays of types with const items should be 
clearable. I can't say I agree with immutable pieces, as again, that 
leads to potential UB. I know it's a PITA, but we have to consider as a 
library type all possible usages, not just focused ones.

I can see a PR that allows clear for types that are not assignable, but 
only have const data, being accepted. Const doesn't guarantee no 
mutability, so it's not UB to modify data that in some other alias has a 
const reference. I don't know if we have a way to determine this 
separate from immutability.

-Steve


More information about the Digitalmars-d-learn mailing list