DEV Community

Discussion on: Weird behaviors of javascript: Primitive Types and Reference Types

 
pentacular profile image
pentacular

If it depicts 'passing a reference' not 'passing by reference', the large red text saying "pass by reference" is a bit confusing.

As far as I am aware, Go also does not have reference values.

Let me know if you can find mention of one in golang.org/ref/spec

I have a feeling that there is the same root confusion in both cases.

That is that people are introducing references as a way to explain things in terms of another language, say, C++, rather than understanding the language in its own terms.

Thread Thread
 
tbroyer profile image
Thomas Broyer

If it depicts 'passing a reference' not 'passing by reference', the large red text saying "pass by reference" is a bit confusing.

That was the sense of my initial comment: pointing the error in that image.
(remember I though the image "was" the post, and your comment criticizing that there was no "pass by reference" here, to which I replied that I agreed and it was actually "pass a reference")

As far as I am aware, Go also does not have reference values.

Go has pointers, which are references to other values (that can also be pointers). IIRC they are stricter than C++ pointers as you can make a pointer point to an arbitrary address in memory (so in Go it works more as a reference than a pointer to some memory address), and allow pass by reference by way of passing a reference by value (because Go also has address operators that allow you to get a pointer to variable). But Go also have slices where multiple slices can share the same underlying array: how do you can that if not "they all reference the same array"?

Maybe you're reading too much into the word "reference", or maybe others are reading to much into it. It's just a concept after all. What's your precise definition of "reference value" that makes you say that neither JS nor Go have that concept?

In the case of JS, it doesn't really matter whether primitive values are hold by references to them (and thus can possibly be "interned") or copied around, because they're immutable values anyway. It's more important to understand it for composite values like objects, particularly if they're mutable (if they're immutable, it doesn't matter semantically, but as an optimization on memory usage and the time it can take to copy those objects).

Sure there are different reading levels, and many people use those terms/concepts that allow them to port their knowledge of one language (and how it deals with memory) to another, but in the case of this article, it's a bit different: when doing a = b, it's important to understand that both variables share (or reference) the same underlying value (composite, mutable) in memory, so modifying that value through one variable means that the modification can be seen through the other variable.
The post is likely wrong actually for primitive values, depending on the JS runtime implementation: they're most probably not copied, but shared as well, but it doesn't really matter as, as I said, they're immutable anyway.

That is that people are introducing references as a way to explain things in terms of another language, say, C++, rather than understanding the language in its own terms.

People each have their own mental model of how things work, at different levels of abstractions depending on the language and where they come from. What does it mean to "understand the language in its own term" wrt the behavior the OP notices? He explains it with "reference values" vs "primitive values", which one mental model; possibly not accurate depending on how things are actually implemented, but conceptually OK anyway.

My own mental model of this is that there are values that exist "somewhere" in memory, and variables are labels that you put on them (or you could think of yarns, threads, wires attached to them on one end, and to the "code" on the other end; so when entering a function, you put your current state –local variables– aside and hold different yarns in your hands). That works very well for programming languages that abstract away the actual memory allocations, it certainly doesn't work that well for C/C++, but still allows you to understand most C/C++ code anyway.

Thread Thread
 
pentacular profile image
pentacular

but in the case of this article, it's a bit different: when doing a = b, it's important to understand that both variables share (or reference) the same underlying value (composite, mutable) in memory

So what this mental model does is to say that the values of a and b aren't the real values of a and b, they're special reference values, and the real, underlying value, is something else which depends on the properties.

Which leads to people making errors like saying that foo(a) is pass by reference because the value you're passing is a 'reference value' and the 'real value' of a is determined by the set of its properties.

But there's nothing in javascript which represents this 'real value', and no operators that operate on this 'real value' (because it doesn't actually exist in the language).

So you end up demoting the actual accessible value and promoting an imaginary and inaccessible kind of value and confusing the language with things like pass-by-copy-of-reference (which seems to be the fallback position when it's pointed out that it isn't actually pass-by-reference).

But at least I'm starting to get an idea of where these peculiar ideas are coming from -- so thanks for being able to talk through it. :)