I think we are saying the same thing. Your term "pass reference by value" is the same as what I called "give a new name to an existing thing".
I simply like to avoid the terms "pass by reference" and "pass by value" to avoid comparison with other languages. But if you want to use "reference" and "value", then your term "pass a reference by value" is a good description of how it works - both for objects and primitives.
Coincidentally, just before I saw your comment I changed what I said about "The reason is that primitives are immutable" to make it more clear.
The real reason is that we instinctively write different code for the two. If a function parameter named 'val' is a primitive, we're not going to try to change a property on it. If we do, it won't work, because the primitive is immutable. (That's the point I was trying to get at with my original comment.) The same would be true, of course, with an immutable object.
And when we pass an object into a function, we may reassign the name completely inside the function, as in the mutatePassByReference() function in your fiddle, but more likely we will write code that manipulates its properties, as in your mutatePassReferenceByValue().
So the immutability of primitives isn't the direct cause of what is sometimes thought of as different behavior for objects and primitives. It's an indirect cause, because it leads us to naturally write different code for the two.
That's what I was really trying to get at (in my usual long-winded way): JavaScript doesn't treat objects and primitives differently, we programmers do.
> I think we are saying the same thing. Your term "pass reference by value" is the same as what I called "give a new name to an existing thing".
>I simply like to avoid the terms "pass by reference" and "pass by value" to avoid comparison with other languages.
The terms mean the same thing in every language. Some people (as shown in the article and this thread) don't understand what "pass-by-reference" means and incorrectly use it to apply to javascript.
The pass-reference-by-value behavior is shared by a lot of languages, I'm not sure why you want to avoid comparison with them.
> The pass-reference-by-value behavior is shared by a lot of languages, I'm not sure why you want to avoid comparison with them.
That's a fair point. I just think a lot of JavaScript programmers are confused about this, and end up thinking that primitives and objects are passed in two different ways. Even MDN makes this mistake:
That's true, "pass by reference" and "pass by value" are clearly defined terms in computer science. The problem is that legions of JavaScript programmers think that one or the other of those terms must apply to JavaScript, when neither one correctly describes the language's behavior.
This leads to the widespread misconception that objects and primitives are handled in two different ways, one passed by reference and the other by value.
I doubt there would be any serious compiler design lecture about implementing a JavaScript engine that would use anything other than "pass by value" to decribe how arguments are placed into the stack upon calling a function.
The problem is trying to apply terms without understanding what they actually mean.
This is exactly the problem I've been talking about.
A compiler design lecture about implementing a JavaScript engine should not use the term "pass by value" to describe JavaScript's behavior.
Most JavaScript engines to date have been written in C/C++. Function parameters are passed by value in these languages, unless you use a reference parameter in C++.
This means that if the argument is a struct, the function receives a copy of the struct, not a reference to the original struct that was passed in.
Placing arguments into the stack is an implementation detail and it can be done either way.
For example, we can hold a reference to a struct representing a primitive value and place it onto the stack. If we let our callee modify this struct we get a behavior you understand as pass-by-reference. Otherwise we can copy this struct into a new struct on write and replace the reference on the stack. This way we are passing references, but implementing pass-by-value behavior. We can do the same for non-primitive data structures, etc.
So these things are about behavior, not implementation. And Javascript does have a behavior where it passes certain things as references implicitly stored in variables. It's in no way pass by value.
I don't know why it's so hard to understand. It's not the essence of passing by reference, you are mixing implementation details with semantics.
If you can modify something that you didn't __explicitly__ use as a reference, you have an implicit pass by reference behavior. It doesn't matter if you can't modify the root reference itself of a nested structure, but only the children. You still can modify something that you didn't explicitly specify, so it is still pass by reference.
And by the way, CS has no precise terminology about this, CS prefers to neglect usability side of programming languages altogether.
But they are not actual terms and are not even conventions, just some things somebody used somewhere that you choose to stand behind. And I choose not to and prefer to use more common understanding of them.
See, it's all about usability and how users understand things. If one way of passing things leaves them with no side effect and another way lets called functions modify shared state without them realizing - these are the big distinctions. It really adds nothing if we call two slightly different variations of passing references by different names instead of more common and intuitive "pass-by-reference".
> But they are not actual terms and are not even conventions, just some things somebody used somewhere that you choose to stand behind. And I choose not to and prefer to use more common understanding of them.
Yes, they are actual terms. You are choosing to be wrong and spread misinformation.
> It really adds nothing if we call two slightly different variations of passing references by different names instead of more common and intuitive "pass-by-reference".
Yes, it really does. The "slightly different variation" has a huge impact on how you write code. PHP, for example, does pass-reference-by-value by default (same behavior as Javascript) but it can also do pass-by-reference if you specify that in the function definition.
see: https://www.tehplayground.com/nzi7SxTxXrrlqTZf
You used to be able to specify pass-by-reference when calling a function, but that was deprecated in 5.3 and removed in 5.4. It was removed precisely because it is important the the person writing a function knows if the variables he is using are pass-by-reference or pass-reference-by-value.
Since it is all about usability and helping users understand things, please stop trying to remove important meaning from the established term "pass-by-reference".
> The "slightly different variation" has a huge impact on how you write code.
From my years of experience with a language that has both variations (Perl) - it doesn't have much impact on how you write code at all, except making the language a bit more flexible and expressive in rare situations.
I consider usability of programming languages to be rather important and would like wrong ideas not to be claimed as terminology there nor conventions. Wrong people shouldn't be pushing wrong terms into the field they have no understanding of.
I simply like to avoid the terms "pass by reference" and "pass by value" to avoid comparison with other languages. But if you want to use "reference" and "value", then your term "pass a reference by value" is a good description of how it works - both for objects and primitives.
Coincidentally, just before I saw your comment I changed what I said about "The reason is that primitives are immutable" to make it more clear.
The real reason is that we instinctively write different code for the two. If a function parameter named 'val' is a primitive, we're not going to try to change a property on it. If we do, it won't work, because the primitive is immutable. (That's the point I was trying to get at with my original comment.) The same would be true, of course, with an immutable object.
And when we pass an object into a function, we may reassign the name completely inside the function, as in the mutatePassByReference() function in your fiddle, but more likely we will write code that manipulates its properties, as in your mutatePassReferenceByValue().
So the immutability of primitives isn't the direct cause of what is sometimes thought of as different behavior for objects and primitives. It's an indirect cause, because it leads us to naturally write different code for the two.
That's what I was really trying to get at (in my usual long-winded way): JavaScript doesn't treat objects and primitives differently, we programmers do.