On Thu, Mar 20, 2014 at 10:59 PM, J Luis <[email protected]> wrote:

> Well, ... thanks
>
> But "naive" question though. If we can do it with elaborate tricks, why
> not just have a clean & simple way?
>

The bottom line for whether something should be mutable or not is
psychological: is the thing a value or a container? Integers are naturally
immutable. If you modify an integer, you don't have the same integer with a
different value, you have a different integer. If you have two distinct
integers with the same value, they're not different, they're just different
copies of the same integer. Arrays, on the other hand, are naturally
mutable. If you have an array and you change the value in its first slot,
you still have the same array, just with different contents. Similarly, you
can have two different arrays that happen to contain the same values, but
that doesn't make them the same array.

So the question is whether a string is a value or a container. Julia isn't
alone in the design choice to make strings immutable. Java made the same
choice for various
reasons<http://programmers.stackexchange.com/questions/195099/why-is-string-immutable-in-java>,
as did Lisp, Scheme, Smalltalk, Python, Lua, Objective C, C#, and many
other languages. In C, strings are just arrays of bytes, so mutability is
quite natural. In higher level languages, however, strings are not
containers, but rather values in their own right. This indicates that they
should be immutable – "hello" and "hella" are simply different strings, no
matter how you derived one from the other, just as 1+2im is a different
complex number from 2+2im, even if you got the latter by adding 1 to the
former.

More concretely, mutable strings open you up to all kinds of nasty,
hard-to-track-down bugs when you're not thinking of a string as a container
of bytes. One of the worst bugs I ever had to find in Ruby was due to
string mutability. Since Ruby treats strings as values, yet they are
mutable, it's so easy to forget that doing str.gsub! deep in some
subroutine will affect what every single caller sees. In this case, it
modified an environment variable in place. Yikes. The bottom line is that
languages that treat strings as first-class values and not just containers
of bytes, strings should really be immutable.

Currently, Julia isn't making great use of the immutability of Strings –
under the hood, we use a mutable byte array. But we're going to change the
way strings are represented in 0.4 to something quite different.
Accordingly, if you are currently reaching under the hood of strings to
mutate them, that code will break.

Getting back to your original example, I would counter that you never
really want to just do something like "replace the 16th character of this
string" in isolation. How did you figure out the index 16? What you really
want to do here is replace every instance of the NUL byte with a space. The
replace function will do that for you:

julia> s = "@GMTAPI@-000000\0 -R-10/0/35/45 -JM14c -Ba2 -P > lixo.ps"
"@GMTAPI@-000000\0 -R-10/0/35/45 -JM14c -Ba2 -P > lixo.ps"

julia> replace(s, '\0', ' ')
"@GMTAPI@-000000  -R-10/0/35/45 -JM14c -Ba2 -P > lixo.ps"


Only want to replace one NUL byte? Just use replace(s, '\0', ' ', 1)
instead. Want to replace each NUL byte and any trailing whitespace with a
single space? That's easy too:

julia> replace(s, r"\0\s*", ' ')
"@GMTAPI@-000000 -R-10/0/35/45 -JM14c -Ba2 -P > lixo.ps"


So the fact that strings are immutable is compensated for by providing much
more powerful tooling to manipulate string values.

Reply via email to