6 ms·
OK, but from a functional programming point of view (where structural pattern matching comes from), "case" should bind a value to a name, not mutate the value o
by brianberns 6y ago
OK, but from a functional programming point of view (where structural pattern matching comes from), "case" should bind a value to a name, not mutate the value of an existing variable. That seems nuts to me.
- hmry 6y agoI don't get it, isn't that exactly what it's doing here?
- magnusmundus 6y agoIt's mutating (not shadowing) `not_found` with the value of `status`. That can cause trouble if you rely on `not_found` keeping the initial value later somewhere. Which you would, e.g. with the global constant of `NOT_FOUND`. Honestly I think the issue is so troublesome only if there's a single case to match, though. With more expected cases it should cause pretty obvious bugs (easy to catch).
- deleted 6y ago[deleted]
- wendyshu 6y agoReassigning not mutating
- Dylan16807 6y agoReassigning to a variable is how you mutate a variable, isn't it? The value being [im]mutable is a different topic entirely.
- deleted 6y ago[deleted]
- carapace 6y agoThere 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>}
- Dylan16807 6y agoWait, 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?
- carapace 6y ago> 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.
- thomasahle 6y agoDoes it shadow the outside variable or mutate it?
- pansa2 6y agoMutates it. Python `match` statements do not introduce a new scope.
- lou1306 6y agoOuch, that's indeed pretty bad. I do expect `not_found = status` (that's how pattern matching works in several other languages), but it should be in its own scope, so that `not_found` is still `404` outside of the `match` block!
- pansa2 6y agoIn those other languages, if `not_found` is equal to 404 before the match block, how do you write a clause that only matches if `status` is 404? Do you have to use the integer literal 404 instead of the named integer `not_found`?
- yw3410 6y agoDepends on the language, but a lot of them use guard clauses (so case ... if cond =>).
- DougBTX 6y agoPretty much the same as in the PEP: https://www.python.org/dev/peps/pep-0636/#adding-conditions-to-patterns https://www.python.org/dev/peps/pep-0636/#adding-conditions-...
- deleted 6y ago[deleted]
- heisenzombie 6y agoElixir uses the “pin operator” “Use the pin operator ^ when you want to pattern match against a variable’s existing value rather than rebinding the variable.” iex> not_found = 404 404 iex> ^not_found = 200 ** (MatchError) no match of right hand side value: 200 https://elixir-lang.org/getting-started/pattern-matching.html#the-pin-operator https://elixir-lang.org/getting-started/pattern-matching.htm...