Is this question really that difficult?

Page 2 - Seeking answers? Join the AnandTech community: where nearly half-a-million members share solutions and discuss the latest tech.

Cogman

Lifer
Sep 19, 2000
10,280
131
106
I know I must be missing something, because stateless functional programming is a major topic of interest on Hacker News, but how the hell do you create an actual system in that way?

I don't think you can totally escape state.

That said, I do find that more stateless/immutable objects are just easier to deal with (especially in threaded situations).

For an example of how this works well, look at http servers/clients. They communicate by message passing and as a result you eliminate a whole host of concurrency problems.

But even in non-concurrent code. It is usually much easier to reason around an object that never changes after creation.
 

BrightCandle

Diamond Member
Mar 15, 2007
4,762
0
76
In many ways the interface of StringBuilder doesn't have to change much in order to make it immutable, but it does require that the returned StringBuilder always be used for ongoing calls and that it is returned from the methods called. You would use an immutable StringBuilder very similar

val sb = new StringBuilder("Hello World")

val result = sb.append("abc").append("efg")

println(result.toS)

If the question is how to do this more efficiently than just basic String concatenation actually that is kind of easy. The whole point of the StringBuilder is to avoid O(n^2) time for repeated String concatenations, because string's + ends up copying the Strings to make new ones. To do a similar thing in StringBuilder you delay the creation of the String until the toS call and simply store all the appends in reverse order in a linkedList of Strings. That is one very simple way to only allocate the space at the end for one single String at the end.

As a programming approach it does have a few advantages. Its much easier to test each individual piece, there are no side effects to the methods so the result you know will be in the return in its entirety. Not saying its necessary but this as an alternative does not have the same problem as GoodDay does with questioning its outside influence, which in many ways makes it hard to reason about what GoodDay is meant to do.
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
If the question is how to do this more efficiently than just basic String concatenation actually that is kind of easy. The whole point of the StringBuilder is to avoid O(n^2) time for repeated String concatenations, because string's + ends up copying the Strings to make new ones. To do a similar thing in StringBuilder you delay the creation of the String until the toS call and simply store all the appends in reverse order in a linkedList of Strings. That is one very simple way to only allocate the space at the end for one single String at the end.

But if you are appending to a list inside the StringBuilder, are you not changing its state? You need to record the list of parts that are to be concatenated into the final string. Unless I'm mistaken, that's state, and it's changing.
 

Train

Lifer
Jun 22, 2000
13,572
66
91
www.bing.com
...To do a similar thing in StringBuilder you delay the creation of the String until the toS call and simply store all the appends in reverse order in a linkedList of Strings. That is one very simple way to only allocate the space at the end for one single String at the end.
That's not how string builder works at all, and would add little performance gain as you still would have to allocate a new string on each append. Allocations are expensive.

It uses a character buffer internally (at least from .Net 4.0 on) that doubles in size every time you hit its capacity. When you append a string it basically copies the char array of that string into the buffer.

Prior to .Net 4 it actually used a single string, but INSIDE the system namespace strings are(or were?) mutable, so it basically cheated by expanding a single string on each append.
 

skriefal

Golden Member
Apr 10, 2000
1,418
3
81
That's not how string builder works at all, and would add little performance gain as you still would have to allocate a new string on each append. Allocations are expensive.

Why would it need to allocate a new string? The string passed to Append would be considered immutable, so the new entry added to the linked list would point to already-allocated memory. There may be other allocation(s) needed to append an entry to the linked list, but that would depend on the implementation of the linked list class.

Purely an academic question, of course, as a dynamically-growing character buffer would likely be more efficient than an implementation using a linked list of the appends. Possibly easier on the garbage collector, too, but again that would depend on the allocation efficiency of the linked list implementation.
 
Last edited:

dighn

Lifer
Aug 12, 2001
22,820
4
81
this shouldn't be difficult to anyone who uses languages that pass objects by reference, which is pretty much any object oriented language.