In Swift arrays, dictionaries and strings are structures with value-semantics. As to why, well, to quote the Swift language reference manual: "One of the primary reasons to choose value types over reference types is the ability to more easily reason about your code. If you always get a unique, copied instance, you can trust that no other part of your app is changing the data under the covers. "
Behind the scenes, however, structures (including strings) are passed by pointer. Swift then uses copy on write so that the objects are completely copied only if and when the program attempts to change a value in them.
As such, a string parameter to a function has value semantics, but it behaves as if it's an immutable pass-by-reference object from a performance standpoint. Kind of the best of both worlds.
An exception would be a parameter specified as inout. (e.g. func f(s:inout String) )
What if you pass a string to a function, and a different thread then changes the original string? Does that also copy on write? Or does the function suddenly see the string change?
(Thread A and thread B both have access to the same string S, B passes S to function F, function F reads S, thread A changes S, function F reads S again)
Structurally, you have to jump through hoops to explicitly see that mutation occur (using types that don't support copy-on-write, aka not String). So answering your question, structurally, you're rarely mutating the string in place, unless the code can be certain that it's uniquely referenced. Since you aren't mutating in place, any other threads with a reference, end up still pointing at the static previous data.
In your example: thread A wouldn't successfully change S. instead, it would create S-prime, and
value types are always passed by copying. An inout parameter means "copy to pass in, copy to pass out, assign to original variable" - but the compiler is free to optimize that.
Swift strings are value types, just like C++ or C#. The value type contains a reference to the string text. (Ok, libc++ in llvm will actually tag the pointers on 64 bit platforms to stuff small strings *into* the struct directly, but I digress)
Swift strings are copy on write, where the reference count is used to determine if you possess a unique reference to the string before mutation. This is similar to how libstdc++ works, or at least used to work.
I believe C++ libraries have been migrating away from CoW
Why are strings passed by value? (Score:4, Interesting)
Strings are immutable pass-by-reference objects in most modern languages. Why did you make this decision?
Re: (Score:1)
Value semantics in Swift are very efficient, as values that don't change are never actually copied.
Re:Why are strings passed by value? (Score:5, Informative)
In Swift arrays, dictionaries and strings are structures with value-semantics. As to why, well, to quote the Swift language reference manual: "One of the primary reasons to choose value types over reference types is the ability to more easily reason about your code. If you always get a unique, copied instance, you can trust that no other part of your app is changing the data under the covers. "
Behind the scenes, however, structures (including strings) are passed by pointer. Swift then uses copy on write so that the objects are completely copied only if and when the program attempts to change a value in them.
As such, a string parameter to a function has value semantics, but it behaves as if it's an immutable pass-by-reference object from a performance standpoint. Kind of the best of both worlds.
An exception would be a parameter specified as inout. (e.g. func f(s:inout String) )
Re: (Score:2)
What if you pass a string to a function, and a different thread then changes the original string? Does that also copy on write? Or does the function suddenly see the string change?
(Thread A and thread B both have access to the same string S, B passes S to function F, function F reads S, thread A changes S, function F reads S again)
Re: (Score:2)
Structurally, you have to jump through hoops to explicitly see that mutation occur (using types that don't support copy-on-write, aka not String). So answering your question, structurally, you're rarely mutating the string in place, unless the code can be certain that it's uniquely referenced. Since you aren't mutating in place, any other threads with a reference, end up still pointing at the static previous data.
In your example: thread A wouldn't successfully change S. instead, it would create S-prime, and
Re: (Score:1)
value types are always passed by copying. An inout parameter means "copy to pass in, copy to pass out, assign to original variable" - but the compiler is free to optimize that.
Re: (Score:1)
Swift strings are value types, just like C++ or C#. The value type contains a reference to the string text. (Ok, libc++ in llvm will actually tag the pointers on 64 bit platforms to stuff small strings *into* the struct directly, but I digress)
Swift strings are copy on write, where the reference count is used to determine if you possess a unique reference to the string before mutation. This is similar to how libstdc++ works, or at least used to work.
I believe C++ libraries have been migrating away from CoW