Hacker News new | ask | show | jobs
by bff 6032 days ago
The value being passed in java is the value of the pointer, where the original pointer value cannot be changed by the function. This is pass-by-reference. Think of pass-by-reference as a special case of pass by value where the value of the pointer to an object is passed rather than the object itself.

If I wanted to write a function that accepted a vector and returned a slightly altered version of that vector I would make a function that does a deep copy and would return that - without ever needing to call the copy constructor myself. I think that it is nice that C++ gives me that option. I don't think that any language is flawless and it's clear that one programmer's feature is, in this case, another programmer's flaw. Keep in mind that this applies to your favorite languages as well.

Edit:

It occurs to me that the distinction is important in multithreaded programs as well. Beyond just worrying about whether or not the underlying data structure is thread safe, passing something by reference might mean sharing memory between two CPUs which can easily lead to a slowdown as the CPUs need to repeatedly flush and resynchronize what's in their cache. Thus unless I have specifically built a thread-safe class whose data has a real need to be shared between between threads I would send data from one thread to another by value rather than by reference.

1 comments

You just described why I believe pythons 'implicit is always better than explicit' is the most important language design fundamental ever conceived of.

The problem with the C++ approach is that it's default (pass by copy-constructor really) is rather implicit. Your doing a potentially a ton of work with a very innocent function call, with possible side-effects. At least the 'pass a reference by value' behaves the same way EVERY time.

For example, in C++:

myobj a; somefunction(a);

That copy constructor might trigger a database hit to create a new object if myobj was some sort of ORM. It might call 23 other constructors to fully complete it's deep copy. Who knows, as it all happens rather implicitly. In python, that would look like:

a = myobj() somefunction(a)

def somefunction(p): p = copy.deepcopy(p)

In that version I'm now implicitly providing that copy. In your multi-threaded example this is still better, as I get the best of both worlds. Ya, I might lose a bit of convenience... but that explictness is worth the trade-off IMHO.