Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Java is pass-by-value, Dammit (and so are Ruby and Python, Dammit) (javadude.com)
108 points by raganwald on Dec 6, 2009 | hide | past | favorite | 73 comments


The user refractedthought at reddit had the best explanation IMO:

Ok, I think the real losers in this discussion are the ones who fail to see both sides of the issue. We can cherry pick "refrence" definitions if we want, but really the nuts and bolts come down to this: Passing by value means that a copy of the parameter is made when the function is called and any changes to that variable will not be reflected outside of the function. Passing by reference means you pass a pointer to your data (and nothing more) so the function can dereference the parameter and affect data that exists outside of the function.

All non-primitives in Java are implicit pointers, so when you pass one of these into a function, you are passing a pointer (or reference) to data that exists outside of the function. However, the reference itself, as it exists inside the function, can be changed to point toward something else. Essentially, the implicit pointer is passed by value, and that value can be altered without affecting anything outside the function.

So technically yes, you could get away with calling this pass-by-value. However, the spirit of pass-by-reference is maintained for any part of the data that most people care about. The syntax is different from a pass-by-reference in C++, and there's a silly little trick you can do by changing the reference pointer (or silly trick you can't do by changing the pointer outside the function) but for all practical purposes you are doing the same thing.

In my opinion, if you want to insist that Java strictly follows pass-by-value, then I think it has ceased to be a relevant distinction.


I strongly disagree. Proper terminology is incredibly relevant.

As stated in the original article, pass-by-value and pass-by-reference have well-known definitions within the computer science community. There is no ambiguity here.

When we excuse the lazy use of such terms incorrectly, we hamper the ability to communicate clearly and effectively. Please stop.

The core misunderstanding seems to be a conflation of 'pass a reference by value' and 'pass-by-reference'.

Passing a reference by value != pass-by-reference. The End. Q.E.D.

Pass-by-reference means that the compiler takes a reference of (or, getting a pointer to) the parameter passed in to the function. This is not the same as passing an existing reference (pointer) to the function (by value). Java only allows the latter (primitive types aside).

A side issue is that some developers mistakenly believe that pass-by-value roughly implies a deep copy, and thus that the 'spirit' of pass-by-reference is the avoidance of a deep copy.

I would posit that many C++ functions that operate on object parameters do so via a pointer (a.k.a. reference) passed by value, just as Java does:

  void modify_my_object(MyClass *myObject) {
      myObject.setName("New Name");
  }

  int main(void) {
      MyClass *myObject = new MyObject("A Name");
      modify_my_object(myObject);
      // myObject.name is now "New Name"
  }
This is pass-by-value, and there is no deep-copy happening there.

Just because many developers don't take advantage of (or don't understand the semantics of) pass-by-reference does not excuse ignorance of the well-known definitions of those terms.


So technically yes, you could get away with calling this pass-by-value. However, the spirit of pass-by-reference is maintained for any part of the data that most people care about.

And if there's any time you can afford to be loose about the spirit vs. the "technical" letter of the thing, it's when you're talking to a compiler. Right? I agree with the article. If you don't like the meaning of a technical term with a clear meaning, or if you simply don't have any occasion to use it properly, that's no excuse for repurposing it in the same context to mean something different that leads to confusion.

It's worthwhile to remember that (true) pass by reference isn't just a curiosity from obsolete languages. It's common for people entirely new to programming to expect that function parameters might, or actually do, work that way. The terms are at least useful to explain things to new learners.

In my opinion, if you want to insist that Java strictly follows pass-by-value, then I think it has ceased to be a relevant distinction.

Even if you work only with pass by value languages, you should still respect the terminology. Some mathematicians only work with continuous functions, but they don't say, "Hey, this word 'continuous' would be a lot more useful if we redefined it to draw a useful distinction among the functions we actually work with." So "pass by reference" doesn't mean what you want it to mean and doesn't seem very useful to you. Invent your own terminology. Don't destroy existing terminology by sowing confusion. And that's all you can accomplish -- there are too many people walking around who already know what "pass by reference" means for you to get away with redefining it.


dschobel's comment clearly demonstrates how the distinction between pass-by-value and pass-by-reference in Java is not purely academic: http://news.ycombinator.com/item?id=979799

It's a relevant distinction because it's required to explain code behavior.


"it has ceased to be a relevant distinction."

I think this distinction ceased to be relevant in the late 70's...


When I was interviewing java devs of all levels few (less than 10%, I'd say) could flat out say "it's pass by value for everything, for non-primitives you're passing references by value" but a lot more (roughly half) could trace the following code correctly.

  Object x = null;
  makeString (x);
  System.out.println (x);

  void makeString (Object y)
  {
    y = "This is a string";
  }
Maybe it's just a disconnect between theory and practice?


Yes. Practical programming books usually don't talk about "pass by reference" or "pass by value" anymore, because (as people have pointed out) it's rarely a useful distinction these days, and the correct usage just confuses people because people take pass by value for granted. (C++ programmers basically see references as restricted, syntactically sweetened pointers that are passed by value. And that's almost always good enough.)

I use this as an interview question, too ("Is Java a pass-by-reference or pass-by-value language?") Nobody ever gets it, but I let people choose one of several languages to be quizzed about, and the ones who know this kind of terminology are usually game to pick a more difficult language. I don't hold it against them as long as their explanation of why Java is pass by reference shows a correct understanding of Java parameter passing. But I always set them straight afterwards ;-)


This.

Java sets up an environment where the parameter passing behavior just isn't surprising. If you've been programming in Java for a little while, it's very easy to have an intuitive feel for how parameters will act, without having to go back to theoretical principles.

Knowing about the theory behind pointers, pass-by-value, and pass-by-reference will still make you a better programmer. But Java's a stronger language for not requiring that knowledge.


You're replying to a comment that says "interviewing java devs of all levels... a lot more (roughly half) could trace the following code correctly." That means that the other (roughly) half of the "Java devs" interviewed found Java's pass-by-value behavior to be surprising, even though there are no exceptions to it.

So although Java's behavior is simple and consistent, the parent comment seems to flatly contradict your assertion, "If you've been programming in Java for a little while, it's very easy to have an intuitive feel for how parameters will act." It's also a perfect example of how programming in Java, or in fact any language with a parameter-passing mechanism and mutable variables, does require that knowledge, so your assertion that "Java's a stronger language for not requiring that knowledge" is nonsense.


You're right: calling it "very easy" was overstating things to the point of absurdity. I do think Java's behavior has a big advantage in being easier to understand than the theory behind it is ("less than 10%"), but I had completely glossed over the "roughly half" point the first time I read this, and it really hurts my claim that Java's approach is trivial to understand.

That said, I stand by "not requiring that knowledge". Java's behavior is understandable without having to know about value and reference semantics. That doesn't mean it doesn't require any knowledge. Specifically, I think it requires two points: (1) Variables are just names, so reassigning a variable doesn't change anything else in the system; (2) When you call a method on an object, you might change that object.

In support of this: I've also been doing a lot of interviews recently. In my (admittedly limited) experience, the people who have had trouble with Java's parameter passing behavior are more experienced developers who've done a lot of work in other languages. Their confusion isn't from Java's behavior, it's the caution about pass-by-reference that they've brought over from C and C++. I don't really see junior people making this mistake. So I suspect having just a little knowledge of the value vs. reference issue makes Java harder to understand, by bringing up new and confusing possibilities.

But, like I said, my experience is limited. If you do see new developers being confused by this aspect of Java (or Python, Ruby, or other languages with similar semantics), I'd be interested to hear about it.


This!? Was I asleep when "this" meme swept through the internet? Help me out: what do you mean when you say "This."???


What iron_ball said, plus a share of "I agree so strongly that I almost want to just repeat everything you said".

Alternately, it could mean: "I was reading LiveJournal five minutes ago, and haven't quite finished switching over to the Hacker News house style." ;)


"The comment to which I am replying is correct."


Oh dear, I was using the little up arrow for that :-)


I think that, instead of hiring those who correctly figure out what happens in this code, you should hire also those who have strong, almost allergic, reactions against it.

Do you really maintain stuff like this in your codebase?


No, I simply found it the easiest way to test understanding of pass-by-value vs pass-by-ref.


It is, but is it that important as to concoct an obscure example? I wanted to rip out my eyes when reading it ;-)


Can you write a traditional swap(a,b) method/function in the language?

What about languages that are immutable by default, like Haskell, OCaml, and Erlang? You can't write a swap function. Therefore, are they pass-by-value?

Actually, in OCaml, you can write the swap function.

   let swap a b =
     let temp = !a in
     a := !b;
     b := temp

   let x = ref 3 in
   let y = ref 8 in
   swap x y
But now, you are passing references by value, as Java does. So maybe they are pass-by-value. But, when your language is immutable, pass-by-reference (whatever that would mean), doesn't effect the language semantics. They are pass-by-(it's-moot).


I've really come to believe that all these terms should be explicitly understood to be domain specific. I can not think of a single term in common use that doesn't have edge cases and other such lacunae when it comes to application to real languages. You name the term, "object orientation", "functional", "reference" vs. "pointer", the distinction really only applies to a given language.

Even the putative "true" definition is usually only the "true" definition in the context of machine language, and something like a true Lisp machine might still end up with no applicable definition for common terms.

(Every time I say this, someone tries to correct me, but it is followed up by someone who then tries to debate the definition being used to correct me. It really is all relative.)

So, in this case, the definition being given for "-by-value" vs. "-by-reference" does hold across a wide variety of imperative languages, but as you point out has no meaning in strictly-immutable functional languages since even inside a given function you can't write a "swap", let alone as a function. The terms only have meanings in certain contexts.


Haskell is something like pass-by-name. At least staff only gets evaluated at most once. But it's definitely not pass-by-value, since not everything gets evaluated down to a value.


Your argument would get ensnared by that of the original post. If you take the description of Java's passing semantics, and s/object/thunk/ and s/primitive/unboxed value/, you get a perfect description of Haskell's passing semantics.


Indeed; pass by reference / pass by value is an irrelevant distinction in a referentially transparent language.


In the StateMonad I can write a swap function in Haskell.


Not one that, according to the original poster's definiton, would qualify Haskell as a pass-by-reference language.



I've heard that java is both pass-by-value and reference in one class, and then heard that it was pass-by-value only in another. The difference was that the first was at a university that primarily used java, and the second was at a university that primarily taught in C++.

The fact is the usefulness of these concepts depend on what language you're writing in. In java, where pointers aren't explicit, you need to know when you're assigning a variable a memory locale versus a value. In C++, where pointer assignment is explicit, that's not a useful concept, so pass-by-reference has a different meaning.

I honestly think we should come up with a different name for pass-by-reference the way it is used in C++. It's not like people actually write code using pass-by-reference anyway :D.


I do believe this is why my university teaches Java for one year, then C for the second, before you even get to glance at (C++|Python|Perl|C#|other). I'm a compiler-writer, and we don't need different names - they have well defined meanings. What we need is people to stop misusing them. You've done it yourself, because C doesn't have pass-by-reference. C++ does (ie, references...), but C does not. Stop doing it! Stop misusing those terms! You just read an article that actually spelled it out, and still misused them!


Redefining terms that have precise meanings into terms that have imprecise meanings based on vulgar precedent is a symptom of a pop culture. Cue Alan Kay quote in 3, 2, 1, ...


If it's a symptom of pop culture, then why is Middle English different from Old English?

It's a symptom of language, and it's impossible to stop.


To answer your (clearly rhetorical) question: Because language is the ultimate pop culture medium.


"In the last 25 years or so, we actually got something like a pop culture, similar to what happened when television came on the scene and some of its inventors thought it would be a way of getting Shakespeare to the masses. But they forgot that you have to be more sophisticated and have more perspective to understand Shakespeare. What television was able to do was to capture people as they were.

So I think the lack of a real computer science today, and the lack of real software engineering today, is partly due to this pop culture."

Full conversation: http://queue.acm.org/detail.cfm?id=1039523


Blah blah blah.

In Shakespeare's day, his plays were ribald entertainment for the masses. People are continuously complaining about how the old ways were better, and one is entitled to one's opinion, but the old ways are in the past and gone. Soon the last person who remembers them will be dead and there will be no one to complain about it, so what's the point?


Wow, that's one of the most pretentious paragraphs I've ever read. I mean, let's use the exact same argument, swapping television for books:

"In the last 25 years or so, we actually got something like a pop culture, similar to what happened when widespread literacy came on the scene and some of its perpetrators thought it would be a way of getting the Bible to the masses. But they forgot that you have to be more sophisticated and have more perspective to understand the Bible. What books were able to do was capture people as they were."


Except, historically that's absolutely wrong. Since the advent of printing, the Bible has been the most widely published book in the world because the masses, as they are, have historically been religious people.


OT: I did find it very interesting to learn that the second most popular book (up to the beginning of the twentieth century) was Euclid's The Elements after the printers were done pressing bibles.


The word 'reference' have precise meanings both when taking about references to objects in Java and when taking about pass-by-reference vs pass-by-value in function call semantics. But it is two different meanings.


Python, for one, doesn't help to make the matter any clearer. In fact, Python makes it look like pass-by-reference is used, even when it isn't.

For a better explanation than I could ever come up with: http://stackoverflow.com/questions/986006/python-how-do-i-pa...

Just to play devil's advocate: if it looks like a duck and quacks like a duck, why would I call it anything other than "duck"? It may be technically correct to say that (in Python, at least) everything is passed by value. But if it helps someone remember that lists may be altered when passed to a function and that tuples can't, what's the real harm?

Again: devil's advocate.


It is just the terminology that is confusing, because the word 'reference' has a different meaning when talking about parameter passing semantics, than when talking about references to objects.

The Effbot suggest we call Python call semantics for 'call-by-object-reference' http://effbot.org/zone/call-by-object.htm which makes it a lot clearer.


I think it's really important to understand why tuples can't be modified and lists can. If you explain it away with something factually incorrect about pass-by-reference, your doing a real disservice to whomever you are teaching.

After all, the issue here has nothing to do with parameter passing and everything to do with object design. It's important to understand that tuples are truly immutable and what the implications of that is.

Misuse of tuples and lists are one of the biggest problems I see in novice (and often not so novice) python code. How often do you see someone copying tuples (often inadvertently) when list semantics are far more efficient? That stems from a fundamental misunderstanding of immutability, something that might stem from not understanding how parameters are truly passed in the language.


Because it means they don't understand what's going on in the language runtime. That is, it betrays ignorance.


Meanings are only well-defined in their particular contexts.


In this case, the context is "programming languages." The term has a very well-defined meaning for all lanugages.


I think the confusion results from the fact that people use the phrase "pass by reference" without ever explicitly stating what the referenced thing is.

In the original sense of the phrase, I believe, that thing was the variable itself in the form of an alias, not the object/value that a pointer variable might be pointing to.


One set of English-language terms are being used by two communities.

1) Those of us who are language users care about use of the language from the perspective of the question, "If this thing gets passed in and I change it, does that change flow back to the calling method." Our perspective of pass-by-reference vs pass by value may originate from experiences learning C. We're probably wrong.

2) This guy is from the community of compiler people. He cares about implementation, and is probably correct.

We need a spoken language abstraction that allows people to discuss the things they care about, and then be able to distinguish between them. The people in the position to cry 'get off my porch' are in the best position to point the rest of us is the right direction.


It's not an academic point and he's not probably correct.

If you don't understand that it's pass by value of references for non-primitives then you won't understand why your variable x is null after the method call:

  Object x = null;
  fooMe(x);
  //is x null or a Foo?
  [...]

  void fooMe(Object y){
    y = new Foo();
  }
That's fundamental knowledge.


If you don't understand that it's pass by value of references for non-primitives then...

Right: pass by value, of references. That's the complete answer, and it's really misleading to say anything else.

I don't think any Java programmers actually have any misunderstanding here, even the worst of them know how this works. What's the problem?

Also, the article tries to use code like this:

  void swap(SomeType& arg1, Sometype& arg2) {
    SomeType temp = arg1;
    arg1 = arg2;
    arg2 = temp;
  }
to prove how different references in C++ are from Java.

But the reason something like that might work in C++ is not that the semantics of parameter passing are different (references cannot be reseated in C++ any more than in Java), but that C++ uses the assignment operator to overwrite the contents of the lhs, and invokes the copy constructor automatically. The true equivalent code in Java works just fine, assuming the copy constructor and set method do the right things (which is a potential pitfall in C++, as well):

  static public void swap(SomeType arg1, SomeType arg2) {
    SomeType temp = new SomeType(arg1);
    arg1.set(arg2);
    arg2.set(temp);
  }


SomeType could be a primitive type. Your java code won't work for int or float or Object * (if you could have such a thing).


Right, but that's more a statement about Java's quirky treatment of primitives than anything else - those are certainly passed by value, but nobody has ever argued anything else. The only confusion/argument is over whether Object types are passed by value or by reference, and it's massively misleading to say they're passed by value, since if you don't know the rest of the story, you'll write code that doesn't run correctly.

The only reason that code won't work for Object is that you can't add a copy constructor or "set" method to Object, not because of any difference in reference semantics. In a real-world implementation we might try to simulate duck-typing by accepting an Object and using reflection to check for the appropriate methods on the object, and though it would be a bit slow it would work for any object type that had the methods defined.

My main point was that for any type SomeType that lets the Java code compile, it will do exactly the same thing as the analogous code does in C++, assuming you've defined the class methods appropriately. Which makes it a very poor illustration of the difference between reference semantics in Java and C++.


> 1)

The abstraction of "this thing" getting passed is certainly useful. However, things are clearer if you imagine two variables which happen to be defined in different scopes being set to the same object. Hopefully these questions are trivial to any Java programmer:

If you have two variables set to the same object, and then change the object, are the two variables still set to the same object? Yes.

If you have two variables set to the same object, and then set one of the variables to a different object, are the two variables still set to the same object? No.


I found this article rather surprising since I come from a primarily Java background.

Do any other languages besides C++ allow this definition of pass-by-reference? The reason I ask is that it seems silly for me to change the way I talk just to satisfy one language that i don't even code in.

And if so, when would it actually be practical to use this? The idea of reassigning a parameter in a function and then having that reassignment affect variables OUTSIDE the function sounds very strange to me (and possible even dangerous).


I disagree with the sentiment that you should simply ignore proper semantics because it's inconvenient. As the article points out, this stuff really does matter.

There are classes of problems that these type of true reference semantics can be quite helpful. In C/C++ the technique is largely used in contexts where you want to return multiple values from a function, as there is no native support for dynamic tuples. Such is the way of statically typed languages.

There are also cases where this type of reference to a pointer magic can really improve the efficiency of the algorithm.

True reference passing is a tool. For those living in dynamic languages (as I do now), not a particularly relevant one. But that doesn't make the distinction any less important.


It used to be very common in Turbo Pascal, where if I remember correctly you had to use the keyword ref.


  def swap(a, b):
    t = a
    a = b
    b = t

  def swap2(a, b):
    t = a['v']
    a['v'] = b['v']
    b['v'] = t

  x = 3
  y = 8
  xx = {'v': x}
  yy = {'v': y}

  swap(x, y) # changes nothing
  swap(xx, yy) # changes nothing
  swap2(xx, yy) # changes 'v' values in xx and yy, but not x or y


Hence the word "traditional" in the article.


I think in C++... if you want to be sure the method/function does not alter the data globally and speed is not a concern, then pass by copy. If you want the method to alter the data globally, then pass by reference. If you want speed, but don't want alteration then pass by const reference.


  a, b = b, a
:)


That has nothing to do with the semantics of passing parameters to functions.

    def swap(a,b):
      a,b = b,a
does not work.


implicit tuple packing in python doesn't count ;)


I think I first saw this debated in comp.lang.java in 1996: http://bit.ly/5XOSey I don't think the arguments have changed much.



Actually in Python is pass-by-reference with lists and dictionaries.


This is a common point of confusion. There are two distinct orthogonal language properties at play here:

1) Variables being references(pointers) to objects.

2) Function arguments being passed by reference or by value.

In Python, all variables are pointers to heap allocated objects, and these pointers are simply passed by value when calling functions.

In C++, it is much easier to understand this distinction as it provides full control to the programmer on both aspects.


Lists and dictionary aren't special, and they aren't pass-by-reference in the sense referred to in the article.

    def foo(my_list):
      my_list = [ "my", "new", "list" ]
Executing this function will not change the value of the list passed to it, it will create a new list and reference it locally. If calling foo(old_list) caused old_list to now contain [ "my", "new", "list" ], then it would be pass-by-reference in the sense this article refers to.

EDIT: To clarify, you can mutate mutable arguments in-place, but you can't change what is being referred to by the identifiers used to refer to these arguments outside of the context of the function, which is what is meant by pass-by-reference in the article.


Though my_list.append("blub") does change the outside list. Does this matter?


In Python you never deal with an object itself, just a reference to it, so you can change the value of any mutable object you pass to a function, lists and dictionaries are just a couple of examples of these.

The problem (discussed by the article) is that "pass-by-reference" is a term that is used a couple of different ways. By someone's definition, this property of Python objects might cause them to consider the calls to pass-by-reference, but the way the author defined it in this article they are not.


You are wrong.

You can modify the original list in your example by having foo() call my_list.append("pwnd!"), for example. You can even use id() to verify that it really is the exactly same object that is visible to the caller and the callee.

Python doesn't pass by reference (in the aliasing variables C++ sense) and it doesn't pass by value (in the functional sense) but rather, it passes references.

Everything is an object anyway but objects aren't copied around. They're just bound or rebound to new variables.

In the above example Python creates new local variables for all function arguments and binds them to the objects passed in as arguments.

If those local variables are assigned to, they're just rebound to point to the new local object while the original variables in the caller code still remain bound to the original object.


you understand python fine; you haven't understood the article. read the article again - it's interesting, self consistent, and disagrees with the comp.lang.python consensus.


I acknowledge that everything in your post is true (save myself being wrong ;) ) and was not arguing otherwise. I know that you can mutate mutable arguments passed to functions in Python, I was just saying that it isn't actually pass-by-reference as the individual I was replying to was saying. I've edited my post to clarify. :)


I reason I think this discussion is ever a problem is because in C++ "pass-by-value" has an extra meaning: that a deep copy occurs. There's no precise term for this, so people started (incorrectly) using "pass-by-reference" to talk about parameters that don't get deep copied. After all, in languages that do it right (Java, Ruby, Python, CL) there's only one parameter passing technique, and therefore no reason to make the distinction.


There is a precise term for that and you said it - pass-by-value. Recall that somewhere each language turns into assembly and that in order to pass a value to a subroutine you must either place values into registers or push the data of the object you are passing onto the stack. Passing by value is desirable if you want to make sure that your local value is not modified. This gives the called function the freedom to modify it without worrying about side effects and without worrying about explicitly calling a copy constructor. Pass-by-reference comes from C++'s pass by reference, which is really just some sugar around passing a pointer by value and referencing it with the * operator in the function body (hence reference passing).

I disagree that there is a right or wrong to this - C++ was made to be a generic programming language and thus gives many options to the programmer. If by "do it right" you meant "hide all options except the one most commonly used" okay. Otherwise I strongly disagree with that sentence especially because I use different kinds of "pass-by" whenever I program in C++ and will be using rvalue reference from the C++0x. Different languages suit different needs.


Well the term is not very precise if the way that you're using it and the way the article is using it are completely different. The article makes it clear that the term "pass-by-value" refers to the fact that the callers' references cannot be unseated by the function call; but it does not mean deep copies are made, like by copy constructor, hence that's why it applies to Java. Allow me to illustrate:

vector<int> numbers; void f(vector<int> args);

Due to C++'s copying, args[0] has a different address than numbers[0], because a deep copy of the vector was made. As the article states, this is not what pass-by-value is referring to, otherwise it would be false that Java / Python / Ruby et al are pass-by-value. So I disagree that the terms are clear, but rather that there is confusion around these terms. As for wanting immutability, it's almost always better for C++ code to write functions not like f but instead like this:

void g(const vector<int>& args);

And apologies for the editorializing, but I do consider this a language design flaw, one inherited from the backwards compatibility for C, which already allowed struct's to be passed (non-pointer) as args and then copied to keep the caller untouchable. It makes C++ code more verbose and more error prone, and is quite difficult for new programmers to grasp.


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.


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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: