Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Reassigning to a variable is how you mutate a variable, isn't it?

The value being [im]mutable is a different topic entirely.



There aren't actually "variables" in Python in the sense of named values, instead there are namespaces where values are stored and looked up under string identifier keys. (Just to add spice, some values, namely function and class objects, do get their names embedded in them, but this is only used for debugging. They are stored in enclosing namespace dicts like other values.):

    >>> def f(): pass

    >>> g = f

    >>> g
    <function f at 0x000001B4A686E0D0>

    >>> locals()
    {'__annotations__': {},
    '__builtins__': <module 'builtins' (built-in)>,
    '__doc__': None,
    '__loader__': <class '_frozen_importlib.BuiltinImporter'>,
    '__name__': '__main__',
    '__package__': None,
    '__spec__': None,
    'f': <function f at 0x000001B4A686E0D0>,
    'g': <function f at 0x000001B4A686E0D0>}


Wait, what's your definition of variable?

Because what you're describing fits perfectly into what I would call a variable. There is a mapping from an identifier to a slot that can store a value (or reference), and that mapping is stored in a specific scope. I would call that mapping a variable.

I'm not sure exactly why you mentioned objects that have names embedded in them. Is that relevant to the definition you're using?


> Wait, what's your definition of variable?

With full formality, the definition of "variable" depends on context. In assembly language and C variables are names for storage locations in RAM, in Python they are name bindings in a dict data structure.

One distinction we could make is whether the names are compiled away or kept and used at runtime.

In any event, the important thing is to keep clear in one's mind the semantics of the language one is using. In Python you have values (objects of various types: ints, strings, tuples, lists, functions, classes, instances of classes, types, etc.) some of which are mutable and others are immutable, and you have namespaces: dicts that map strings to values. These namespaces have nothing to do with the location of the values in RAM.

So it doesn't really make sense in Python to speak of "mutate a variable", you can mutate (some) values, and rebind values to names (new or old).

> I'm not sure exactly why you mentioned objects that have names embedded in them. Is that relevant to the definition you're using?

Not really, it's just another little point that sometimes confuses some people when they are coming to grips with the idea that in Python values are not associated with names except by namespace bindings. There are some values (function and class objects) that do get associated with names.


I suppose, but it's very strange to say "Assigning to a variable is classified as mutating the variable in some languages but not others, even though the underlying mechanism works exactly the same way."

Shouldn't terms like this be cross-language?


The underlying mechanism doesn't work the same though, e.g. in C assigning to a variable "mutates" the contents of RAM, in Python it mutates the namespace dictionary (which of course also results in some RAM contents changing too, but through a relatively elaborate abstraction.)

> Shouldn't terms like this be cross-language?

Variables in C are different beasties than variables in Python, and variables in Prolog are different from both, and none of those are like variables in math. It's a source of confusion that we use the word "variable" for a host of similar concepts. The word "type" is similarly overloaded in CS. (See https://www.cs.kent.ac.uk/people/staff/srk21/research/papers... )

FWIW, I'm just explaining what wendyshu was on about above. :)


That's not exactly how C works, but I wasn't going to use C as my primary example, I was going to use Rust. You have to write "let mut" to let a variable be reassigned/mutated, and variables in Rust are almost identical to ones in Python as far as being an abstract 'namespace' binding.


> That's not exactly how C works

Sure, I elided a bajillion details, and who knows what the CPU is doing under the hood anyway? :)

I've never used rust (yet) so I can't really comment on that.

FWIW namespaces in Python aren't abstract, they exist as dicts at runtime. You can modify the dict you get back from locals() or globals() and change your "variables" in scope:

    >>> d = locals()
    >>> d['cats'] = 'meow'
    >>> cats
    'meow'




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: