-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
continue in match makes the control flow fallthrough implemented #37684
continue in match makes the control flow fallthrough implemented #37684
Conversation
Wasn't this implemented in Godot 3.0 already? Or did the feature break over time? |
@Calinou in 3.0 it doesn't fall through, continue to search for another match instead |
This changes the meaning of |
documentation already states that continue will fall through the execution. (https://docs.godotengine.org/en/stable/getting_started/scripting/gdscript/gdscript_basics.html#match)
|
WeW I was just writing a state machine and this tripped me up, bad... :3 Would someone mind marking it a bug-fix pls? (At least it inconsistent with the docs) Or should I fix it in the docs for now for older versions? |
That's the thing, I don't know if this is a bug. It's been there for so long now that I'm afraid some people might be relying on this behavior. Even though potentially "relying on a bug" is not safe, changes in behavior in a game engine can completely break the game. so it's usually avoided in a patch release. Maybe if we ever do a 3.3... (definitely will change in 4.0 though). The reason I don't think it's a bug is because the original pull request mentions this as the implemented behavior:
However, the same person wrote the docs and stated that it was the same as a fallthrough in a I would say that the documentation is wrong. When docs don't match code, usually the issue is in the docs. I was surprised by this too (since I've never used the "fallthrough" in a match statement), but that's how it was originally meant to be. |
@vnen oh didn't know about the discussion but that's the same conclusion I drew from it. The only reason it was a little weird was, that, I was expecting it to work like Python. I changed my code to follow a more pattern matching notion. Pretty sure it's something that was inspired from Rust. @vnen For example say,
@ThakeeNathees How will it be handled by fallthrough. Without fallthrough it will go from first case to second. |
1. match val:
2. [var x, var y]:
3. continue
4. var z:
5. # do something with z here
6. pass once the execution met |
@ThakeeNathees exactly my point it is not handled..... :3 There is no definition of |
I believe you misunderstood what fall through means in the documentation, and that the current behavior is perfectly expected. The initial reseasonning behind the continue statement in match operations was first to avoid the need, as in a lot of other languages, to have a break in every statement. So instead of having this break, you would only have to specify when you want your code to check the next statement too. So in GDscript, you never need breaks, but if you want the next statement to run too, you can use a continue. Honesty the documentation has been really clear to me, I understand it' s not the behavior you have in several other languages with the continue keyword, but IMHO, it completely makes sense. That being said, to avoid confusion with other languages we could maybe rename the "continue" keyword in a context of a match statement, but I don't have any idea of a good alternative. |
Maybe even worse. (I read the commit code too before mentioning the issue, but I have no idea how runtime issues like these are handled in GDScript but I very much assume the best case would be a perf hit and runtime error or worst case a segfault)... Also from a pattern matching standpoint, this PR and proposal just don't seem useful. A rematching case is much more powerful than a fallthrough. Heck there are causes for concern that go much deeper, match val:
[var x, var y]:
print(x, ", ", y)
continue
var x:
print(x)
continue @ThakeeNathees |
@groud That seems like a sensible solution. Also, I was only confused because it wasn't clear to me that there was "pattern matching" with match statements. On a serious note, I think some change to the docs to mention this behaviour for the older versions of the doc is necessary, and a rename for the |
match val:
[var x, var y]:
print(x, ", ", y)
continue
var x:
print(x)
continue @swarnimarun if gdscript is an interpreted language we just can't jump from but the problem is that since the capture val to x line doesn't execute the value of x will be the same as val when just before match block started to execute, I'll fix it if we decided to go with this however since the new parser will implement this and people might be relying on this behavior I'm agree with @vnen |
Oooof it was sarcasm both the times... I know what the issue is and print is an example when it will cause a bug silently, using a function that requires certain type would mean that it will show the error at entirely wrong place. This is something that just can't be fixed. Because you can't just fall-through to next step here, you will have to match on pattern to get the next value. Which is exactly what it does at the moment... So I am not sure what you plan to do to fix it but it is already fixed. Only difference is if the match fails it skips the case. This means it falls through but just doesn't do it without matching. I am assuming you need a case like, match month:
Jan:
Dec:
Mar:
May:
Jul:
Aug:
Oct:
return 31 You can do a clean "or" separated multi pattern match instead which is much more sane. Now if you want conditional fall through, that's IMHO what I like to call code smell. You have array based matches like, [var x, ..]
[_, _, var x] If you want more pattern scenarios can be added which wouldn't be bad but I don't see how changing the usage of continue would be useful. On the contrary now I find that it would make it rather confusing to use, as you won't be able to use any of the patterns with var bindings in the subsequent cases the same way as ones without them if you used continue based non-matching fall through. Features that require adding exceptional cases without much useful functional enhancement are not something I would like. At the very least I am against replacing the current functionality. |
Honestly the way it's written begs for this misunderstanding. It's a series of steps on how to replace It only mentions
Which again misuses what a "fallthrough" means in this context. The text is now changed to better note it checks the next patterns. But I still think "fallthrough" should be removed (though this should be discussed in docs).
This is the reason it's not available in other languages as well. For example in Rust: match x {
None => None,
Some(i) => Some(i + 1),
} If you go from the first branch to the next, what would So the current behavior is the best we can do without getting in this conundrum. However, it's only there to replace guards, so I wonder if we should remove |
@vnen I would like guards as well maybe we can discuss it in a thread or proposal for it. But for now continue is enough. For 4.0 for sure though guards would be a better solution. But may as well discuss it further at a proper place. |
Given that this is a fairly old PR and that the discussion is mostly about the feature proposal and not the implementation, I suggest we close it and keep the discussion focused in godotengine/godot-proposals#160. See also godotengine/godot-proposals#4775 for a recent related proposal. |
Fix: godotengine/godot-proposals#160