Background: While the previous discussions about assignment-expressions (PEP 572) (abbreviated AE below) have been raging one thing that was noticeable is that folks have been looking back to C for a solution.
But how are newer languages solving the problem today? Believe Ryan brought this up first on the list, but it had been in the back of my mind as well. Finally have compiled my research, corrections welcome. In alphabetical order: Dart, 2011: Design goal: Less confusing, conservative replacement for JavaScript. - Assignment is a statement, not an expression. - JS allows AE to used freely, Dart doesn't support them. - Only option is to write simple, mildly redundant code. Details: https://www.dartlang.org/guides/language/language-tour#assignment-operators https://github.com/dart-lang/sdk/issues/55 Golang, 2009: Design goal: Simple, maintainable replacement for C++/Java/C#. - Assignment is a statement, not an expression. - Precursors allowed AE to be used freely - Golang doesn't them but allows assignment inside the if statement: if x := f(); x < y { … } - No assignment in while (spelled for) currently allowed. Use mildly redundant code in other locations. Details: https://stackoverflow.com/questions/13127929/assign-and-compare-in-gos-while-equivalent https://clipperhouse.com/statements-are-statements-and-expressions-are-expressions-in-go-4087d103e3b7 Kotlin, 2011: Design goal: Terse, modern replacement for Java with high interop. - Assignment is a statement, not an expression. - Java allows AE to used freely, Kotlin doesn't support them. - Main option is to write simple, mildly redundant code. (Or use std lib functionality such as forEachLine, etc.) Details: https://blog.kotlin-academy.com/kotlin-programmer-dictionary-statement-vs-expression-e6743ba1aaa0 https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/ https://stackoverflow.com/questions/41537638/assignment-not-allowed-in-while-expression Rust, 2010: Design goal: Safe replacement for C/C++, etc. - Assignment is a statement, not an expression. - C/C++ allow AE - Rust doesn't, but allows an assignment clause in if/while. if let Some(3) = some_u8_value { … } while let Some(byte) = input.next() { … } Details: https://doc.rust-lang.org/book/second-edition/ch06-03-if-let.html https://doc.rust-lang.org/stable/rust-by-example/flow_control/while_let.html Swift, 2014: Design goal: Modern replacement for ObjectiveC with high interop. - Assignment returns Void - ObjC allows AE - Swift doesn't, but allows an assignment clause in if/while statements: if let NAME = … { … } if var NAME = … { … } while let line = aStreamReader.nextLine() { … } Details: https://stackoverflow.com/questions/34173084/what-was-the-reason-for-swift-assignment-evaluation-to-void https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/while-statement Conclusions ------------ It appears assignment expressions are no longer the favored solution for the "assign and compare" use case. Not one of these five newer languages supports them fully, as the language generations from C to C# did. Of those that have recognized the use case to be large enough—the solution has been rather more limited to the "if" and "while" statements only. Several folks here have expressed the same desire to confine AE there. Since Python's design goals are similar—to be safe and maintainable I'd recommend a similar strategy, with the addition of the list comprehension case. Going back to the C-style solution seems like the wrong direction. Since that would mean this special assignment functionality is not allowed to be used everywhere, it alleviates the pressure to make it fit into with/import/except statements. Furthermore, that frees up the keyword "as" again, which is Pythonic, short, memorable and has a history of being used for various assignment purposes, not to mention a prominent feature of SQL. In short, extend the "if/elif", "while", and comprehension to: if pattern.search(data) as match: … while read_next_item() as value: … May be best to disallow multiple assignment/conditions for now, but up for discussion. That leaves comprehensions, which could support a EXPR as NAME target also: filtered_data = [f(x) as y, x/y for x in data] or perhaps reuse of the if…as statement to keep it simpler: filtered_data = [y, x/y for x in data if f(x) as y] That variant might need an extra test if f(x) returns a falsey value, perhaps "is not None" on the end. Thoughts? -Mike _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/