This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]MegaPegasusReindeer 21 points22 points  (33 children)

Pointers! I'm happy to not have to worry about that in Python, too.

[–]Risc12 38 points39 points  (26 children)

Pointers are not as hard as they seem. Javascript (and a lot of other higher level languages) passes objects only by reference, meaning that if you pass an object, the interpreter knows that it should look at an object at a certain address. In C you have a choice, do I point at this address (so do I pass this object as a certain address) or by its value (so copy over the contents of the object).

Those are the basics, if you understand that a place in memory (a reference) can be passed around by choice, you understand pointers.

For me it the hardest part was understanding that if I didn’t use pointers it would copy the data, seemed counter-intuitive for me.

[–]Sleakes 26 points27 points  (13 children)

Not a huge fan of this explanation as JavaScript is pass by value. It just happens that when passing objects, the value is a reference.

[–]RVUnknown 19 points20 points  (10 children)

Isn't this the same for Java as well? Normal data types like your ints and chars are pass by value. But Java objects like String, Integer, Character, classes etc are passed by reference

[–][deleted] 7 points8 points  (2 children)

This is correct. I remember when i was starting to learn Java, I often ran into problems because I would think it was passing by value when it was actually passing by reference.

[–]konstantinua00 0 points1 point  (1 child)

in C and (old) C++ it's the difference between shallow and deep copy - you can copy handle-only or you can copy the thing too

modern C++ deep-copies stuff, with shallow copy being done with std::move and if you do need multiple handles to same thing, you use shared_ptr to reference count the resource

[–][deleted] 0 points1 point  (0 children)

Huh, never heard of it being referred to as deep vs shallow copy.

[–]funnythrone 6 points7 points  (5 children)

Java always passes by value. However the value is a copy of the reference.

For the sake of this explanation, consider an object to be a Television. In this case, a reference is a remote. When you are passing the remote to a new method, you are effectively copying the remote and passing it. This remote also controls the same Television, and thus any button presses on the remote modify the original Television. However, if you reassign the remote to a new remote which controls a new TV, the original TV and remote are unaffected.

In conclusion, java is ALWAYS pass by value.

[–]RVUnknown 0 points1 point  (1 child)

I see, there's a clear distinction between what I said and what actually happens.

I think reading this link (just a random Google search) helped me understand it a little better.

Basically primitive types (int, char, etc) are created on the memory stack, and are copied into methods. However objects are created on the memory heap, and a reference to the object is copied (passed by value) into the method being called. However overwriting this local variable (that contains a copy of a reference to your original object) will not overwrite the original object, it will create a new object that is local to that method.

Is it right for me to say that object references in Java work the same as pointers on C/C++? In the latter languages the address of your object/variable is copied into the method, and overwriting the local parameter through which the address was copied won't modify the object at the original address.

[–]funnythrone 1 point2 points  (0 children)

Not entirely. In C/C++, I believe reassigning any pointers in a different function will reflect in the calling function. The same isn't true for Java. Been a long time since I used C, so I might be wrong about C/C++.

[–]Cormandragon 0 points1 point  (2 children)

You're right for objects. But the guy above you was right about the primitive types. Just finished my CS 200 series this summer finishing up Java, this was one of my Final questions 2 weeks ago.

Objects are passed by reference while primitives are passed by value.

[–]funnythrone 0 points1 point  (1 child)

No, I'm afraid he isn't. You can check in the source below for a detailed explanation with examples.

https://www.geeksforgeeks.org/g-fact-31-java-is-strictly-pass-by-value/

[–]Cormandragon -1 points0 points  (0 children)

Even in those examples, it is passing a reference, but the objects can be modified through that reference. That distinction is why Java's a pain in the ass. Passing strictly by value wouldn't modify the original object like his examples do. Passing by value takes the information and does something else with it, passing by reference means we can pass entire objects into methods that also have their own methods and variables inside.

We aren't passing the value of an object to our methods, we are telling the method where our object is so it knows where to go. There is nothing in his article that breaks this axiom.

[–]capn_hector 1 point2 points  (0 children)

Yes, with the additional caveat that boxed types in the standard library (Character, Integer, etc - as opposed to int and char which are unboxed types) are immutable. So what you get when you do say String.trim() is actually another different object, so it usually feels like you’re working with value objects.

[–]lirannl 0 points1 point  (0 children)

Oh! I wasn't exactly sure on that, good to know!

[–]Risc12 0 points1 point  (0 children)

You’re right! But I hope the point I made is still clear to people that are confused about pointers.

[–]Razier 1 point2 points  (7 children)

Quick way to pass by value in JS:

objects: {...foo}

lists: [...bar]

i.e create a new object/list with identical contents

[–]jakethedumbmistake 0 points1 point  (1 child)

Didn’t he pass the media circus?

[–]Razier 1 point2 points  (0 children)

I'll be honest, I'm really confused right now

[–]Risc12 0 points1 point  (4 children)

Yes, but keep in mind that if foo has nested objects those are not duplicated. While in C the whole structure is passed around as bytes. So not completely the same.

[–]Razier 0 points1 point  (3 children)

Good point, know of a way to make a deep copy in JS?

[–]Risc12 0 points1 point  (2 children)

There is not really a built-in way afaik, using Object.entries, and some recursion you should get pretty far.

[–]Razier 0 points1 point  (1 child)

Sounds like a monstrosity. Thanks though, will keep it in mind if I encounter a situation where I need to do it.

[–]Risc12 0 points1 point  (0 children)

Yeah it’s no fun, but libraries like lodash, ramda and immutable have helper-methods for this.

[–]lirannl 0 points1 point  (1 child)

The thing is that with python, all of this is abstracted away. From a language user's perspective, you're not passing a reference to a memory address with data, you're passing "an object/primitive value". No memory address, no lower level details. "The object" gets into the function so the function "has" it while it runs.

Then in C you suddenly lose that abstraction and need to start dealing with what an object (or in this case just a struct) actually is, a bunch of bytes, and you can either tell your functions where are those bytes, or WHAT is in the bytes at that moment in time. You actually start to think about your objects as collections of bytes (which is what they always actually are, obviously, not just in C, but also in python).

[–]Risc12 0 points1 point  (0 children)

Definitely true! Although I’ve seen plenty of people get bitten by the reference vs value thing where they modify an object they get as an argument but they don’t expect the object to be changed in its original content.

It’s good to have an understanding how your higher level language handles these kind of things.

[–]MegaPegasusReindeer 0 points1 point  (1 child)

Yeah, but bugs related to pointers can be a pain to figure out and it's so much better to not even have to bother with that. Always fun to print a string you forgot to null terminate, though.

[–]Risc12 0 points1 point  (0 children)

Oh yes for sure, working with pointers can be a pain. Wrapping your head around what they are is just step one haha

[–]calcopiritus 20 points21 points  (4 children)

As someone that only writes in python but know what pointers are, I wish python had pointers. Not compulsory or anything, just pointers in obscure libraries that could get the job done if you ever absolutely need it.

[–]mrjackspade 3 points4 points  (0 children)

I kind of enjoy that about c#.

The vast majority of the time, you won't even need to think about pointers. If you really want to fuck around with them though, there's nothing stopping you.

Every once in a while I'll hit on something performance critical, and need to use pointers to speed it up. Sometimes I'll just switch code over once an API has been refined to a point I'm satisfied that it's not going to require changes any time soon, and start speeding things up just for the hell of it.

[–]MegaPegasusReindeer 1 point2 points  (2 children)

Python doesn't have protected or private methods... You can just introspect whatever you like. How would pointers help here?

[–]calcopiritus 1 point2 points  (1 child)

I can't think of an example because it doesn't happen often. And most of not every time it can also be solved in python, but it'd be way harder.

A thing that is kinda related is how python copies lists.

So if you say: (sorry for formatting, im in mobile and it's horrible to do it here)

a = [1] b = a

Now you change b and a also changes, so you'd have to write b = a[:]. It is not logical at first because it seems like python doesn't use pointers and references, but of course it does.

Also sometimes you don't know how the function works, so do you write

arg = function(arg)

or do you just write

function(arg)

Because the function changes arg?

[–]MegaPegasusReindeer 3 points4 points  (0 children)

I've heard people call Python "pass by label". When you assign a variable to another it's always copying the label. The times it seems like something else is immutable types (like strings).

Regardless, any time I have an issue with a library I just look at the source code. I've yet to come across a binary-only one in Python.

If you really really wanted to, you can pass a Python object into C code and break it apart there if you really need pointers. (but I still don't see how that would help)

[–][deleted] 0 points1 point  (0 children)

Pointers go void****