|
|
Subscribe / Log in / New account

Python multi-level break and continue

Python multi-level break and continue

Posted Sep 1, 2022 23:12 UTC (Thu) by tialaramex (subscriber, #21167)
In reply to: Python multi-level break and continue by bartoc
Parent article: Python multi-level break and continue

Right, Dijkstra's ketter is about the go-to feature as manifested at that time which is way more powerful (and thus dangerous) than anything mainstream languages support today. Dijkstra is arguing for what we have today, loops, procedure calls, structured control flow rather than just jumping around.

For the cleanup problem, I think C successors tend to offer defer here for that purpose. I don't like defer, but it's a more healthy solution than goto fail: type arrangements. I prefer something like Rust's Drop trait but I can see that feels too much like invisible magic for some C practitioners.


to post comments

Python multi-level break and continue

Posted Sep 1, 2022 23:35 UTC (Thu) by NYKevin (subscriber, #129325) [Link] (1 responses)

Strictly speaking, you can recover the goto that Dijkstra was talking about very easily in C. You just have to put all of your code in main, and then C's goto is functionally identical to the original goto.

> For the cleanup problem, I think C successors tend to offer defer here for that purpose. I don't like defer, but it's a more healthy solution than goto fail: type arrangements. I prefer something like Rust's Drop trait but I can see that feels too much like invisible magic for some C practitioners.

People have come up with many, many different solutions to the cleanup problem:

* try-with-resources (Java)
* with/using statements (Python/C#)
* defer (Go)
* Destructors (C++, Rust)
* finally (just about any language that supports exceptions, including several of the above)
* Higher-order functions like Haskell's withFile
* Optional types (which allow you to coalesce the happy path with the unhappy path so that you only have one code path and don't need to "handle" cleanup specially)

Most of these options would require C to grow something vaguely resembling nontrivial data types (what C++ would call non-POD types), which will obviously never happen, but defer would make logical sense for C, IMHO. You could also make an argument for finally, because even without exceptions, it still intercepts early returns (as well as more convoluted nonsense like break and continue, and one imagines it could also do goto).

Python multi-level break and continue

Posted Sep 1, 2022 23:36 UTC (Thu) by NYKevin (subscriber, #129325) [Link]

> You just have to put all of your code in main, and then C's goto is functionally identical to the original goto.

For people with no sense of humor: This is a joke. Do not actually do this.

Python multi-level break and continue

Posted Sep 1, 2022 23:42 UTC (Thu) by bartoc (guest, #124262) [Link] (1 responses)

Well, you can get something much like rust's drop trait in gnu C (supported in clang as well) using __attribute__((cleanup)) and some macros. This actually ends up working really quite well and makes things much more ergonomic.

In any event I actually want all of goto, defer and drop/RAII. Defer is useful even with drop/RAII when you are interfacing with external code or doing something "one off". Goto remains useful for implementing certain algorithms involving state machines and tables.

While not super useful in combination with goto there is a related gcc extension called "labels as values" that I really wish would be standardized, since it allows writing code that would be almost impossible otherwise (like tracepoints).

Python multi-level break and continue

Posted Sep 2, 2022 11:08 UTC (Fri) by tialaramex (subscriber, #21167) [Link]

While it's not something you'd put in a slim C-like language, if you have say, closures, then drop replaces the need for the defer feature. You can just build a utility type whose purpose is to run a closure when it is dropped, so then when you make the utility type and specify a closure, it will run that closure when the scope ends, the exact same feature as defer but now just a utility type.

There are (of course) several of these in Rust crates already, suiting different tastes but it's also trivial to build your own instead.

And for state transitions I'd definitely again rather have high level types representing this than try to do it with goto. Pattern matching and sum types make this sort of thing feel very ergonomic to me compared with C. In fact while I understand a C successor isn't going to have Rust's quite sophisticated ControlFlow type, it'd be nice to at least have say <control.h> defining CONTINUE and BREAK so that Library A's maybe_do_stuff() and Library B's repeat_until_done() both agree that CONTINUE is 1 (or 4, or 'Z' I don't care) while BREAK is 0 (or -26, or 5.16, again I don't care) rather than have a situation where Library A signals with -1 while Library B expects 0

Python multi-level break and continue

Posted Sep 7, 2022 15:39 UTC (Wed) by anton (subscriber, #25547) [Link]

I don't find anything in "Go to Statement Considered Harmful" that suggests that Dijkstra meant only variants of goto that are more powerful than those in C.


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds