views:

301

answers:

4

Why is it that so many programming languages make it possible for a function to modify an object passed to it as a parameter, without having some sort of syntax to make that clear to the caller. Eg consider:

SomeObject A(15), B
B = DoSomething(A)
print(A + " " + B + "\n)

Reading that code you would expect the output to be something like "15 75", ie A is what you constructed it to. However most languages make it possible for DoSomething to change the value of A. In C++ you can tell if its possible or not by looking at the declaration of DoSomething, eg by looking is the parameter is defined as a non const reference. However in many languages, such as Python there is really no way to tell without reading through the code for the function to make sure it never changes A.

Ive been bitten by this on a few occasions, especially when trying to work with someone else's code which uses this behaviour and usually results in going through the entire piece of code line by line to try and find what's changing the parameter...

Why is it that languages don't generally require some explicit syntax by the calling to say "yes this object can be modified", eg say "B = DoSomething(inout A)"?

Is there any codeing standards that help to prevent problems occurring, apart from the "never modify a parameter passed into the function"?

+1  A: 

The "coding standards" vary by language and among users/teams. C++ has const-correctness, which when properly used counts as a coding standard. C# has out and ref parameters for obvious cases. I'd say the only real consistency across a wide range of languages is the fact that parameter modifications should always be documented in the post-conditions of the function.

280Z28
Yes but it is rare for people to cast to the const type for each variable in C++ before passing it to a function, and as shown in my example, from the calling code a reference pass is invisible, you need to look at the function definition (which with modern IDE's is not so hard, but still requires you to check every function, rather than glance over code).Documentation is again something that doesnt stand out when glancing over a bit of code like my example, you have to go look it up.
Fire Lancer
+1  A: 

If you look at Java, a method can not really change the parameter (Java has only input parameters). But the parameter is often just a reference to some object to work with, which means that the method can change the object in any possible way. This makes reasoning about the semantics (without looking at docs) hard, quite the opposite to function programming.

You are right that this is undesirable, but in the short term it made things easier. Unfortunately, most often it is short term what counts, so we are still working with languages that support hidden side effects...

Bluehorn
Even then there are rules. As a simple example, getters shouldn't change the program state, so you can generally assume this as you are reading through code.
280Z28
A: 

This doesn't directly make your code-snippet more clear, but I want to mention it anyway: we're using a naming convention for the parameters to display exactly what you want. We use 'in', 'out' and 'io' prefixes. So the DoSomething declaration would look like DoSomething(ioSomeObject inA). When working in Visual Studio with Visual Assist you'll get a popup with the types and names of the parameters, and this documents possible side-effects. In my opinion this is more clear than documenting post-conditions.

Regards,

Sebastiaan

Sebastiaan Megens
At least use the `InAttribute` and `OutAttribute` if you must do this. But really, there's no need to document 'in' parameters since that is the expected case.
280Z28
XML documentation shows up in the IntelliSense as well, and you get immensely more information from that. Not only do I *strongly* disagree with this convention, but it violates very well established rules for naming parameters in CLI applications and sets off both FxCop and StyleCop.
280Z28
+1  A: 

My preferred design pattern for this is immutable data classes.

With mutable classes, you have to think about whether it gets modified.

A point of clarification, by my understanding, Python is pass by value just like Java and C (without modifiers). But what you are passing is usually a mutable object.

(Edit: almost all mainstream languages follow these semantics now. The most prominent exception is Lisp, where you can not only modify mutable objects, but reassign the value pointed to by a variable.)

Kevin Peterson
Python is not pass by value, and in my example it is perfectly possible python could change the contents of A if SomeObject is not an immutable type, eg it could call (assumign the parameter is called a in the function) "a.SetValue(55)" and it would change the value of the A object.
Fire Lancer