Thread overview
why use string for this example of appender?
April 16
I think I got a handle on D's static and dynamic arrays, till I come to std.array and see all the shiny new tools. I can understand all the replace.. functions, but the appender function gave me pause. The documentation says appender "Returns a new Appender or RefAppender initialized with a given array."

My first thought that doesn't D's built in arrays already allow appending? (at least for dynamic arrays)  And the example shows the use of appender with string.  Isn't string an immutable array or characters?  Wouldn't this be the last data type you would want to be appending to?  Another thing that had me wondering is the use of put() down below; doesn't the append syntax (~=) give you the same exact functionality; so why bother?

void main()
{
    import std.array;
    import std.stdio: write, writeln, writef, writefln;
    auto w = appender!string;
    // pre-allocate space (this avoids costly reallocations)
    w.reserve(10);
    assert(w.capacity >= 10);

    w.put('a'); // single elements
    w.put("bc"); // multiple elements

    // use the append syntax
    w ~= 'd';
    w ~= "ef";

    writeln(w.data); // "abcdef"
April 16
On 04/15/2018 11:46 PM, WhatMeForget wrote:
>
> I think I got a handle on D's static and dynamic arrays, till I come to
> std.array and see all the shiny new tools. I can understand all the
> replace.. functions, but the appender function gave me pause. The
> documentation says appender "Returns a new Appender or RefAppender
> initialized with a given array."

New Appender allocates new memory. If an array is already available for an Appender to use, then it's more efficient.

> My first thought that doesn't D's built in arrays already allow
> appending? (at least for dynamic arrays)

Yes but Appender is reported to be faster presumably it uses a different allocation scheme and may be more free compared to dynamic arrays that must play well with GC and its pages.

> And the example shows the use
> of appender with string.  Isn't string an immutable array or
> characters?

Mutable array of immutable characters: immutable(char)[].

What is important is that existing elements shoould not mutate so that existing slices don't get confused. Appending is fine because a new array is allocated and copied for the appending slice. (Aha! This feature is likely why Appender is faster than a dynamic array: it does not have the feature of "element stomping prevention". (Something is wrong with my English at the moment. :p))

> Wouldn't this be the last data type you would want to be
> appending to?

It's not unusual.

> Another thing that had me wondering is the use of put()
> down below; doesn't the append syntax (~=) give you the same exact
> functionality; so why bother?

put() is old, ~= is new. Both are supported.

Ali

April 16
On Monday, 16 April 2018 at 06:46:36 UTC, WhatMeForget wrote:

> Another thing that had me wondering is the use of put() down below; doesn't the append syntax (~=) give you the same exact functionality; so why bother?

Appender also performs unicode-related conversions, so you can append dstring to string and vice-versa, wich may come in handy.
April 16
On 4/16/18 4:49 AM, Ali Çehreli wrote:
> On 04/15/2018 11:46 PM, WhatMeForget wrote:
>  >
>  > I think I got a handle on D's static and dynamic arrays, till I come to
>  > std.array and see all the shiny new tools. I can understand all the
>  > replace.. functions, but the appender function gave me pause. The
>  > documentation says appender "Returns a new Appender or RefAppender
>  > initialized with a given array."
> 
> New Appender allocates new memory. If an array is already available for an Appender to use, then it's more efficient.
> 
>  > My first thought that doesn't D's built in arrays already allow
>  > appending? (at least for dynamic arrays)
> 
> Yes but Appender is reported to be faster presumably it uses a different allocation scheme and may be more free compared to dynamic arrays that must play well with GC and its pages.

It's because it stores the relevant information in a local type vs. having to look it up in the GC.

It's also not all opaque calls (they can be inlined).

>  > Another thing that had me wondering is the use of put()
>  > down below; doesn't the append syntax (~=) give you the same exact
>  > functionality; so why bother?
> 
> put() is old, ~= is new. Both are supported.
> 

put is required for Appender to be an output range.

-Steve
April 16
Thanks all.  I sometimes feel like Michael Corleone: "Just when I thought I was out, they pull me back in!" :)

I realize it is not the place for it, but sometimes I wish the Library Reference explained things in terms of "why".