←back to thread

2024 points randlet | 4 comments | | HN request time: 1.098s | source
Show context
js2 ◴[] No.17516019[source]
Background ("PEP 572 and decision-making in Python"):

https://lwn.net/Articles/757713/

replies(2): >>17516132 #>>17516693 #
jcelerier ◴[] No.17516132[source]
> The problem with the C-style of assignments is that it leads to this classic error: if(x = 0) {...}

yeah, if you code on 20 years old compilers with no warnings. GCC 4.1 warns about this (with -Wall) and Clang 3.4 warns about this too, without any warning flag.

replies(4): >>17516174 #>>17516220 #>>17517715 #>>17518178 #
Waterluvian ◴[] No.17516174[source]
I think that having strong opinions on how others should be developing software is how communities become toxic like this.

"Shooting yourself in the foot is your fault for not using a linter that detects accidental misuse of assignment!"

replies(3): >>17516217 #>>17516742 #>>17516875 #
TooBrokeToBeg ◴[] No.17516742[source]
I'm still puzzled to why would a compiler allow assignment in an explicit conditional (outside of loop syntax). It's like a baked-in blindspot that most people just want to ignore for some reason. Some languages actually guard against this well enough (eg Kotlin) and say "don't". Even with guards in place, it's not all that complicated to work around in the edge cases where you might want to do it.
replies(5): >>17517091 #>>17517115 #>>17519127 #>>17519910 #>>17519933 #
arkadiytehgraet ◴[] No.17517091[source]
Funny you should mention Kotlin; while I like the language a lot, I believe this particular feature would be of immense help in the following scenario:

Imagine you have a sealed class Foo, with `class Bar(x: String) : Foo()` and `Baz() : Foo()`.

Now, imagine you have a method, returning an object of type Foo: `fun foo(): Foo`

And you want to pattern match on the result of this method:

  when(foo()) {
      is Bar -> ...
      is Baz -> ...
  }
Now, the problem is: how do you access String field x in the first branch? The only way to do it now is to extract the methos call into redundant local variable, and then pattern match it instead of `foo()` directly as I did above.

Now imagine Kotlin had that feature; then we could just do the following:

  when(foo = foo()) {
    is Bar -> foo.x
    is Baz -> ...
  }
replies(2): >>17517234 #>>17520246 #
1. bpicolo ◴[] No.17517234[source]
One option is match statements. Great way to make this sort of inline assignment unnecessary
replies(1): >>17517267 #
2. arkadiytehgraet ◴[] No.17517267[source]
Could you please elaborate more on what you mean by match statements? Is it an already existing feature of Kotlin?
replies(1): >>17517291 #
3. bpicolo ◴[] No.17517291[source]
Ah, I guess `when` is literally Kotlin's equivalent of match.

What I'm thinking of here is Rust's match statements, which do give you the ability to make use of those intermediary values by making use of Rust's enum type.

https://doc.rust-lang.org/book/second-edition/ch06-02-match....

replies(1): >>17517337 #
4. arkadiytehgraet ◴[] No.17517337{3}[source]
I see; I agree that proper pattern matching would indeed solve that as well, as e.g. Scala does.