5 ms·
A previous mistake does not make a convincing argument for making a new mistake. Also, the mutable default arguments problem is quite difficult to solve in any
by toxik 6y ago
A previous mistake does not make a convincing argument for making a new mistake. Also, the mutable default arguments problem is quite difficult to solve in any other way. Python never copies things for you.
Pattern matching is a desired feature, but the shortcomings are too costly for what it provides. You just outlined yourself the quickest foot-gun I've ever seen.
My second problem is that this violates many of the invariants you rely on while programming Python. f(x) always gives you the value of applying f to x. Nope, not in case. | means bitwise or. Nope, not in case. a means the value of a. NOPE. Not in case.
- pfalcon 6y ago"f(x)" and "|" inside a regular expression mean something different. Similarly here, pattern matching has its own sub-language (a DSL).
- toxik 6y agoCoincidentally, regular expressions are not part of the Python syntax. They're just string literals.
- craftinator 6y agoAre you being intentionally ironic here, or do you not know that regex DSL is written only inside of strings in python, not within the Python's syntax?
- globuous 6y agoIsn't it the same in ML though (using the same syntax in different contexts) ? Compare `| [a, b] => a + b` and `let my_list = [a, b]`. Same in JS, `let {a, b} = {a: 1, b: 2}` and `let d = {a, b}`. It's weird at first but then you just get used to it. edit: updated list name since pipe ("|") and small L ("l") look kind similar in the code snippets.
- contravariant 6y agoA variable name has never referred to the value of it in expressions where it is being assigned. In 'def f(a,b,c)' or '(a,*_) = x' the term 'a' doesn't refer to the value of a either. A match statement in this sense is just an assignment that has a graceful failing mechanism (rather than e.g. '(a,*_) = x' which throws for empty lists). And I think the ship on '|' has sailed with the dictionaries.
- lovasoa 6y ago> the mutable default arguments problem is quite difficult to solve in any other way. Python never copies things for you. Why would it be a problem to do a copy in this case? > f(x) always gives you the value of applying f to x Not if it is preceded by "def" > | means bitwise or. Not if it had been overloaded, like many popular libraries do. > a means the value of a Not if it is followed by "=" How is that different from the new pattern matching syntax ?
- toxik 6y ago> Why would it be a problem to do a copy in this case? How are copy semantics even defined unambiguously? > Not if it is preceded by "def" In that case it is analogous, def f(x) DEFINES what f(x) means. For class definitions it's different, and it is indeed debatable if `class A(SuperClass)` is good syntax. I would have preferred `class A from SuperClass`, but that ship has sailed. > | means bitwise or. Not if it had been overloaded, like many popular libraries do. You missed the point willingly I think. See sibling comment. You cannot overload its meaning in a match, and the meaning is not related to what it otherwise means (bitwise or, set union, etc.). > a means the value of a Not if it is followed by "=" And again, this is by analogy. a = 1 means that you substitute a with 1 wherever a occurs. Not so with the pattern matching syntax. If we had a = 1 then a == 1. Where is this analogy for pattern matching? How do you even make the comparison? You do not. All of your counterpoints have reasonable analogies within the syntax itself (eg: the inverse of a function call is a function definition).
- yatac42 6y ago> Also, the mutable default arguments problem is quite difficult to solve in any other way. Python never copies things for you. Why would it need to copy anything? What's wrong with just evaluating the default argument expression every time the function is called with a default argument rather than once at definition-time? That's how it works in other languages.
- toxik 6y agoThat’s a good idea, I like that!
- enedil 6y agoThe variables used in the expressions might not be in scope (in fact they usually aren't). Also, I'm rather sure that's how it works in C++ (which by accident copies arguments instead of leaving a reference, but the single time default argument evaluation holds).
- yatac42 6y ago> The variables used in the expressions might not be in scope (in fact they usually aren't). That's solved easily enough by evaluating the expression in the scope where it was defined (again that's what other languages do). > Also, I'm rather sure that's how it works in C++ Default arguments in C++ work as I described: If you define `void f(int arg = g(x)) {}`, then calling `f()` n times will call `g` n times as well (using the `x` that was in scope when `f` was defined) - and if you never call `f`, `g` isn't called either. An example demonstrating this: https://ideone.com/vs26Oq https://ideone.com/vs26Oq