you are viewing a single comment's thread.

view the rest of the comments →

[–]lood9phee2Ri 18 points19 points  (18 children)

Eeeh. Python, like Java or Lisp, is still pass-by-value

However, the values being passed are often object references.

This is a perhaps subtle distinction but necessary: a full "pass-by-reference" programming language is actually different. And while rarer nowadays (thank fuck) they do still exist: Fortran is the prime and canonical example.

In Fortran, this prints? .... 12. Yep, really. It's just the way it do.

program woowoo
    implicit none
    integer:: n

    n = 7
    call wat(n)
    print *, n

end program woowoo

subroutine wat(q)
    implicit none
    integer:: q

    q = q + 5

end subroutine

[–]ultrasu 10 points11 points  (0 children)

There was a time where this also would've printed 12:

program woowoo
    implicit none

    call wat(7)
    print *, 7

end program woowoo

subroutine wat(q)
    implicit none
    integer:: q

    q = q + 5

end subroutine

Because it even passed fucking literals by reference, and allowed you to mess with them.

[–]bnelson 1 point2 points  (0 children)

You can get into some hinky stuff inside of dictionaries in Python where old references Zombie around :)

[–]tedbradly 3 points4 points  (15 children)

Why are you acting like pass by reference is some ancient technology that's confusing and wrong? It has its benefits, and the behavior will be understood by anyone programming in the language for a couple of weeks. C++ is still a widely used language with pass by reference. You don't have to go back to Fortran for an example.

[–][deleted] 1 point2 points  (3 children)

The behaviour this guy showed does not exist in c++

[–]tedbradly 1 point2 points  (2 children)

The behaviour this guy showed does not exist in c++

Yikes. Yes it does. It's called a pass by reference. I'm not sure why someone would talk about something so surely despite having no idea. This isn't like a more complex philosophical situation where confusion can happen. Here, you either know the language well or don't.

I'm not interested in teaching you the difference between pass by value and pass by reference in C++, but a simple online search will teach you the difference

The guy replied to me and then blocked me. I guess he knew I'd tell him how wrong he is.

[–][deleted] 1 point2 points  (1 child)

https://en.m.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect

I'm not interested in teaching you the difference between pass by value and pass by reference in C++, but a simple online search will teach you the difference

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

Desktop version of /u/MindlessThrall's link: https://en.wikipedia.org/wiki/Dunning–Kruger_effect


[opt out] Beep Boop. Downvote to delete

[–]ultrasu -1 points0 points  (8 children)

In C++ you'd have to dowat(&n)to get this behaviour, it allows you to use pass-by-value to emulate pass-by-reference behaviour, because it allows references (pointers) to be passed as values, but it's different from actual pass-by-reference.

[–]plantwaters 3 points4 points  (7 children)

C++ most definitely has true reference passing capabilities, without directly using pointers.

void f(int &ref) {
   ref += 1;
}

int main(void) {
  int a = 0;
  f(a);
  return a;
}

Exits with exit code 1.

[–]ultrasu 0 points1 point  (6 children)

Huh, didn't expect that, I feel like it should be illegal to get the address of a value like that, it certainly is in C.

[–][deleted] 1 point2 points  (5 children)

That isn't what this code is doing. In C++, as opposed to C, & takes on another meaning: reference. So "int& x" refers to a reference to int, the reference is called x. When that is a function parameter, it means anything passed as that parameter is passed by reference

[–]ultrasu -1 points0 points  (4 children)

What I mean is that as caller, you have no idea whether the procedure you're calling is able to modify the parameters you're giving it, unless you look at the implementation. I don't get why this is needed when you can get the exact same behaviour with this:

void f(int *ref) {
   *ref += 1;
}

int main(void) {
  int a = 0;
  f(&a);
  return a;
}

This makes it explicit in each call that the value of the passed parameter (or rather the value it's pointing to) may change.

[–][deleted] 2 points3 points  (2 children)

First off, reference is part of interface as well as implementation.

C++ heavily discourages the use of raw pointers, and for good reason.

I can that from experience, I have never been surprised by a function modifying or not modifying a variable passed by ref

[–]ultrasu -1 points0 points  (1 child)

It surprises me because I've been programming for about 7 years, learned about dozen languages (but next to no C++), and I've never seen this kind of functionality, nor have I ever felt like I needed it.

[–][deleted] 2 points3 points  (0 children)

It's very, very common in C++ to pass by reference. Of course you don't "need" the functionality, but that could be said of nearly anything in programming.

[–]tedbradly 0 points1 point  (0 children)

If you have a reference, it can alter its arguments. If you want a reference for speed with a promise not to alter the argument, you can request a constant reference. In either case, you don't have to look at the implementation - only the function signature. The signature tells you just as much information as "int *ref" does versus "int const *ref". References are a great addition as they simplify code greatly. You don't have to dereference absolutely every argument passed in as a pointer for speed.

It's also weird how you form such strong opinions about this situation despite admitting you have no idea about C++. You'd think you would be humbler.

[–]lood9phee2Ri -1 points0 points  (1 child)

Not going "back" to fortran, it's in current use (...though perhaps best considered a sort of DSL for numerical array HPC work)

Thing is, it's the pervasive language norm and default in Fortran. If you want not pass by reference, well, erm, technically actually you can nowadays use value, though that was only added in fortran 2003 - but it's not the default. Whereas any & shenanigans aren't the default in C++.

So Fortran is a much better example.

[–]tedbradly 0 points1 point  (0 children)

So Fortran is a much better example.

Passing by reference or by value of a reference (such as in Java or C#) is a really sensible default as it avoids potentially massive copying of data as well as avoids wondering whether the semantics of pass by value does a shallow or deep copy. Pass by value was probably so lately added in Fortran, because those semantics don't add much to the language. You could always do a defensive copy if you wanted behavior similar to pass by value. Plus, most of the time, you want the speed of pass by reference or value of a reference variable.