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.

-Steve

Fair enough.

My use case is simply the standard usecase of Appender: I want to build up an array in a way that reduces GC churn. Maybe it's an array of structs that contain const members that I'll serialize to JSON and send on a socket. In that case, I know for a fact that no references will hang around past the serialization. That's what clear _is for._ I don't see why this would be different with const or immutable data; if you hold references past .clear being called you're in trouble *anyways.*

Right, this does seem like a big limitation. Keeping with the spirit of how slices don't own the memory in question, Appender is being conservative with what it doesn't know.

I wonder if it may be more appropriate to instead of preventing clear() on immutable/const arrays, to make it @system. Or maybe call it something different "dangerousClear" or something ;)

There definitely should be some way to fail if clear is called on an array that was passed into the constructor.

But I'm still not sure we should allow overwriting immutable memory without a cast, even in @system code.


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!

Reply via email to