11 ms·
A number of these points seem like reasonable opinions to have. But two which had me questioning the breadth of the author's experience were "Most programming l
by CurtHagenlocher 8y ago
A number of these points seem like reasonable opinions to have. But two which had me questioning the breadth of the author's experience were "Most programming languages pass function parameters by value." and "In every other language, arrays are called 'arrays'. In Python, they are called 'lists'."
To the author:
1. Java, JavaScript and C# all have types which are passed by reference. (They also have types which are passed by value.)
2. Python lists are not arrays, if by arrays you mean a C- or FORTRAN-style block of non-resizable memory which is indexed by position. Python lists are much more like the Java List or C# IList interface.
- SargeZT 8y agoAnd python does have arrays in the array module.
- colanderman 8y agoPython (and Java) do not pass anything by reference. They pass by pointer-value. (If they passed by reference, you could change to which value a caller's variable was bound, like you can in C++).
- alexhutcheson 8y ago> (If they passed by reference, you could change to which value a caller's variable was bound, like you can in C++) I might be misunderstanding you, but I don't think you can do this in C++. References can't be changed to point to a different object after initialization. If you have code like: void MyFunc(Foo& ref_param) { Foo new_foo; ref_param = new_foo; } The assignment above isn't "changing the value to which a caller's variable is bound". Instead, it's running the '=' operator on the Foo object to copy the state from new_foo to ref_param. To demonstrate this, you could run the following to see that the addresses are the same: Foo original_object; Foo& object_ref = original_object; MyFunc(object_ref); // object_ref still points to the same address assert(&original_object == &object_ref); Under the hood, C++ reference params are basically syntactic sugar for passing by pointer-value, so this behavior isn't surprising.
- colanderman 8y agoThe proper analogy for a Python object is `std::shared_ptr<Foo>`: in Python, all "objects" are actually reference-counted pointers to objects (thus making them shareable). And then yes, in C++, you can change to which object the caller's "object" (pointer-to-object) points to, if you pass a reference to that. This is not possible in Python: all you can do is pass that shared-pointer value around, not the value of the object itself, nor a reference to the shared pointer. This is a well-known distinction that goes by several names, see e.g. https://en.m.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing https://en.m.wikipedia.org/wiki/Evaluation_strategy#Call_by_...
- alexhutcheson 8y agoAh, got it. Your basic point is that C++ params can use two layers of indirection (pointer-to-ref, ref-to-pointer, pointer-to-pointer, etc.), while doing so in Python is clunky. Makes sense.
- lmm 8y agoThose languages use references rather than pointers (that is, their referring-things do not support arithmetic), so any name for what they do that involves "pointer" is a poor one. The distinction between passing the value of a reference being used by the caller and passing a reference to the caller's stack is so rarely important or useful that there's no consensus terminology for it. The distinction that's actually relevant and useful is whether, when we write f(a), f receives the (thing we would call the) value of a or a reference to the value of a (and in particular whether f can change the value of a). In Python, f can change the value of a (that is to say, the thing Python programmers understand to be the value of a); therefore Python is pass by reference as the term is usually understood (and certainly any term for its call style that uses "value" is more misleading than calling it "pass by reference").
- jerf 8y ago"The distinction between passing the value of a reference being used by the caller and passing a reference to the caller's stack is so rarely important or useful that there's no consensus terminology for it." And the reason for that is essentially all modern languages make copies of something when passing argument parameters. The only question is what they are passing and exactly how hard the language layer works to make it look as if you are or are not passing something by reference. I have to reach to something as obscure as Forth to find a language that does not work that way, and truly does not copy parameters into a function. (I haven't dug into Factor enough to know if under the hood it still copies parameters.) It's a very unusual choice to not copy something for a function call. (This is one of the ways our CPUs have been optimized for the languages we run; they make this intuitively expensive operation otherwise cheaper than it would be on a naively designed CPU.)
- com2kid 8y ago> And the reason for that is essentially all modern languages make copies of something when passing argument parameters. Then of course someone turns on whole program optimization for C++, half the code gets inlined into one terrifying large function, nothing is copied anywhere, and the code runs 2x faster. Then some poor SOB has to debug the assembly code for all of this and has nightmares for years after. Not like I'd know or anything. :)`
- pdonis 8y ago> They pass by pointer-value. No, Python doesn't even do that, because Python variables aren't names for storage locations to begin with. They're namespace bindings. Passing a variable to a Python function means transferring a namespace binding from the caller's namespace to the function's local namespace.
- arduinomancer 8y agoWhat is a namespace binding? Can you explain at a low level what that means?
- pdonis 8y agoCompare a variable assignment in C and Python. In C: int i = 17; Means "set aside one int's worth of storage and fill it with the bit pattern for the number 17". In Python: i = 17 means "create an int object with the value 17 and bind it in the current namespace dictionary to the name i".
- colanderman 8y agoThe semantics are identical.
- pdonis 8y agoIf you think this, I'm confused about what you mean by "semantics".
- deleted 8y ago[deleted]
- dagw 8y agoPython lists are not arrays In addition python also does have arrays if you want/need them: https://docs.python.org/3.7/library/array.html https://docs.python.org/3.7/library/array.html
- deleted 8y ago[deleted]
- cm2187 8y agoIf I remember VB6/VBA passes everything by reference by default, even value types.
- porpoisely 8y agoIn C#, all variables ( reference or value types ) are passed by value. Yes, even reference types are passed by value. If you want to pass variables by reference, you need to use special modifiers ( out or ref ).
- graycrow 8y agoYes, but for a reference types that value IS a reference, so if you change a complex type, that change will persist after return to the calling code.
- aurelwu 8y agostatic void Change(int[] myArray) { myArray = new int[5] {3, 1, 2}; } this will not change the array which was passed in and is a purely local change in C#. static void Change(ref int[] myArray) on the other side would change the array which was passed in.
- city41 8y agoBut it’s still pass by value. Passing by ref allows swapping out the entire object, which is not possible in a language such as JavaScript.
- sciurus 8y agoRight, but this is the same way Python works. Jumping back to the original argument in the post, the author claimed that Python was "going out of it's way to be different" by passing objects by reference value. C# provides a counterxample to that claim.
- porpoisely 8y agoYou are correct that changes to the object will be reflected in the calling code. But that's the nature of the reference, not whether it is called by value or called by reference. Whether you pass a reference by value or by reference, the changes to the object will be reflected in the calling code. And as I noted, it's all passed by value in C# unless you use modifiers ( ref or out ). The difference between "pass by value" and "pass by reference" for reference variables is how the variables themselves are handled. For example, if you pass a reference "by reference" to a function and set it to null, then the reference variable in the calling code is also set to null and will cause null ref exception if you try to access the object. Whereas if you pass a reference "by value", if you set the variable to null, the calling code variable isn't affected. Pass by value and pass by reference is not about objects or types really, it's about variables.
- brudgers 8y agoWhat Java, JavaScript and C# call "arrays" are each very much like what Python calls "lists'. In particular the indexing after push() and pop() type operations and the bigO of indexing. More abstractly, Historically, in computing "list" connotes pointers and "array" connotes sequential memory. The connotations imply engineering tradeoffs. [1] "List" may make more sense for a beginning programmer. It is an arbitrary context switch for programmers writing in multiple languages. Considering that one of the driving use cases of Python has been systems programming, "list" is misleading regarding performance characteristics. [2] [1]: For example as in Scala https://docs.scala-lang.org/overviews/collections/performance-characteristics.html https://docs.scala-lang.org/overviews/collections/performanc... [2]: googling "python arrays" returns a lot of results explaining the difference between Python's Arrays and Python's Lists. "List" is "foo => spam" and "bar => eggs" Pythonism gone too far.
- TheCoelacanth 8y agoNot true for Java or C#. In both of those languages, arrays are fixed-size and don't have anything like a push or pop operation. Both have an automatically resizing container backed by an array that is referred to as a list. Python's use of "list" matches the use in Java and C# perfectly.
- brudgers 8y agoRequiring a type definition, Python's Array type more closely matches Java and C# Lists than Python's List type. In Python, Arrays are sequence types and behave very much like lists[1] In other words, even in Python, arrays have similar semantics to Javascript Arrays not Java Arrays. [1] https://docs.python.org/3.4/library/array.html https://docs.python.org/3.4/library/array.html
- michaelt 8y agoWhat Java, JavaScript and C# call "arrays" are each very much like what Python calls "lists'. In Java and C#, 'arrays' are fixed size at creation time. Both Java and C# provide 'lists' which are variable sized* Python 'lists' are variable-sized. Seems like a consistent naming scheme to me? *there might be an underlying array that gets reallocated - but it's encapsulated within the list object; the reference to the list object is unchanged when this happens.
- phodge 8y ago> Most programming languages pass function parameters by value The biggest irony here is that if you wrote your code in C instead, you would actually pass more arguments by reference than in equivalent python, because you're going to use pointers for everything but primitive integer values.
- Koshkin 8y agoNo, the biggest irony is that C as a language does not even have a syntax for passing by reference. Everything, including pointers, is passed by value. References were introduced in C++.
- twblalock 8y agoJava passes by value. The value being passed happens to be a copy of a pointer (properly called a "reference" in the spec, which confuses people). A copy of a pointer points to the same place as the original pointer. For normal use cases this works very well. However, if you reassigned your copy of a pointer in the body of a function, the original pointer would still point to the same place it did before the function was called. That's not the same thing as actual pass-by-reference in languages like C++.
- InclinedPlane 8y agoAlso, in javascript the thing that's called "an array" is actually a hashmap, because everything in javascript is secretly just a hashmap.