5 ms·
I'd disagree that this is a better translation. In python-land, `x` is just a name binding. The closest thing might be that `x` is something akin to a Box<T>, b
by joshuamorton 7y ago
I'd disagree that this is a better translation. In python-land, `x` is just a name binding. The closest thing might be that `x` is something akin to a Box<T>, but I don't know that that's cleanly expressible in rust.
Like in (modern) python you can totally do
def foo():
x: Union[str, int] = 1
x = "foo"
which would be akin to in rust ?? (sorry my rust foo isn't great).
Specifically the semantics don't work here because if you do ~this:
def foo():
x = 1
async takes_int(x)
x = "foo"
this will always work find in python (even in a hypothetical GIL-free python, even if you make the assignment actually async), whereas that wouldn't work in rust if you pass a mutable ref to takes_int (at least if memory serves).
Or I guess another way of putting this is that names in python can't be mutable.
- hope-striker 7y agoYou seem to be confusing mutable variables with mutable references. A name, in Python, is a mutable cell that holds a reference. Python names definitely correspond to mutable, not immutable variables in Rust.
- joshuamorton 7y agoWell no, for the reason I describe above: if you have the pattern mut a = 4 f(a) print(a) In rust and python, you'll always get 4 in python, but the value in rust depends on `f`. This means that the passed variable is immutable but shadowable, as in rust. (An object in python is much more like an Box/Cell, so the contained object can be mutated, but the reference to the box itself is immutable).
- hope-striker 7y agoThe value in Rust does not depend on f. I will be precise. There is no definition of f such that this function will print anything other than "4". fn main() { let mut x = 4; f(x); println!("{}", x); } Again, you seem to be confusing mutable references and mutable variables. If I had written f(&mut x) rather than f(x), you would be right.
- dilap 7y agoNo, the name is definitely mutable. Consider: x = 1 capture = lambda: x x = 'foo' print capture() If python were just shadowing, this would print 1. But it prints foo.
- joshuamorton 7y agoThat's an issue of scoping, not capturing. The x in the lambda isn't scoped to the lambda, it's scoped to the surrounding environment. So the x closes not over the lambda but the outer scope. So it's as expected given shadowing. Edit: Since I'm getting throttled: No, I'm saying that scoping rules are different in python and rust. In Rust (and cpp) there's the concept of scopes/closures as a first class feature. This concept doesn't exist in python (python has namespaces, I guess, instead, there's no good terminology here). See https://stackoverflow.com/questions/2295290/what-do-lambda-function-closures-capture https://stackoverflow.com/questions/2295290/what-do-lambda-f.... This is due to weird scoping, not name mutability. Second edit: Well ok on second thought I see where you're going here. I was trying to avoid thinking about copy-on-scope-change behavior, but you actually do have to consider that and you're right.
- hope-striker 7y agoShadowing is when you have two separate variables with the same identifier. It is beyond obvious that all the x's refer to the same variable in dilap's example. Contrast that with an actual example of shadowing[0], in which it is clear that the same identifier is being used to refer to two different variables. [0]: https://en.wikipedia.org/wiki/Variable_shadowing#Python https://en.wikipedia.org/wiki/Variable_shadowing#Python
- joshuamorton 7y agoI'm using shadowing in the rust sense, not the python sense.
- hope-striker 7y agoThey are the exact same sense! The exact same idea of shadowing is also present in, for example, sentences in first order logic.