4 ms·
Thoughts on Return, Break and Continue
- coolgeek 5y ago> Allowing breaking out of blocks, you don’t need the continue keyword: 'loop: loop 'block: { // continue break 'block; // break break 'loop; } I get the intellectual appeal of experimentation, self-imposed constraints, minimizing instruction sets, etc. But forcing block labeling in order to avoid the necessity of continue statements seems like a wrong turn,
- politician 5y agoHow about just goto?
- adamrezich 5y agoone of the coolest features in Jon Blow's "jai" language is how, in lieu of making "iterators" a first-class language feature, instead you can define a "for_expansion" for your structs, which then lets you define what it means to iterate over your struct with a "for" loop. that's neat on its own but then you can actually redefine what "break", "continue", and "remove" (keyword that you can use for whatever you want but semantically it's supposed to be "remove item from collection during iteration in a safe way that doesn't affect the rest of the for loop"): Foo_Storage :: struct { items: [..] int; some_other_data_structure: Bar_Storage; } for_expansion :: (using storage: *Foo_Storage, body: Code, flags: For_Flags) #expand { for something: some_other_data_structure { for `it, `it_index: items { #insert (remove=#assert(false), break=break something) body; } } } foos: Foo_Storage; for foos { /*...*/ } I've never seen anything like this in any other language and I've found it to be an incredibly useful tool to have at your disposal.
- Supermancho 5y agoPython allows you to remove items as you iterate through them. Surprised it's such a rare feature.
- jdmichal 5y agoThe Java `Iterator` interface has a `remove` method, that in my experience is rarely used. Apparently rarely enough that it wasn't even a concern when hiding the `Iterator` instance in its foreach loop implementation. Otherwise, this seems like a case of operator overloading. Sure, as long as `continue` and `break` do something like they're supposed to, it works. But how often is that true, when it's also NOT true that simply implementing something like an `Iterator` interface with a fixed implementation of those operators? If the only advantage is in providing the ability to break expectations, that's probably just a bad idea.
- adamrezich 5y agosince there's no such things as iterators in this language, it's the responsibility of the programmer of the for_expansion to make the keywords do what makes sense in the context of iterating over the struct in a for loop. I don't understand why you think it's a bad idea. you write a struct for your data container, you write a for_expansion that allows for it to be iterated over in a for loop, and you optionally define what break, continue, and remove do in the context of the for_expansion you wrote. it's not as open to unexpected craziness as operator overloading can be because these keywords only work in the context of a for loop, and you are defining how a for loop is handled for your struct... where's the issue?
- jdmichal 5y agoThe issue is that those keywords are expected to work a particular way, just like operators. Just like the operator + is expected to do some sort of addition operation, the keyword `break` is expected to do some sort of loop exit operation. The ability to reprogram the break operator to do anything else isn't useful for anything other than breaking expectations. And having to program the same break mechanics into every single iterable type rather than simply implementing an `Iterator` interface which then has those operators implemented seems less optimal. Which is why I said, it seems like the only advantage is the ability to break expectations. Which is arguably, realistically a disadvantage.
- chenglou 5y agoJai is, imo, doing it right! For custom iteration one really _just_ wants it to be a little syntax sugar over a regular loop. Most other languages end up constructing some paradigm for iteration that drags in OO, FP, some interface concepts, generics, etc. Never mind that some edge-case async generator iteration can't leverage the `for` syntax; they deserve to stand out and be examined anyway. Especially in the case of Jai, where you'd want assurance that the for loop isn't incurring some weird function, allocation and other hidden overhead. No sufficiently smart compiler needed. Compare that to e.g. Swift's iteration, with corners of undefined behaviors, potential allocations, and a collection types hierarchy that feels more like doing taxonomy than just looping. Though to be fair, Jai's loop is rather intense in its usage of a macro system's features. Related: Common Lisp loop macro: http://www.ai.sri.com/pkarp/loop.html http://www.ai.sri.com/pkarp/loop.html
- mgraczyk 5y agoIMO jumping to labels is obviated in modern languages by low cost inline lambdas. Instead of complex loop breaking logic, stick the body in a lambda and use return. It's easier for me to follow and gives you more control over what's in scope. It also makes refactoring easier later on.
- brandmeyer 5y agoI am reminded of "Lambda: The Ultimate GOTO" https://dspace.mit.edu/handle/1721.1/5753 https://dspace.mit.edu/handle/1721.1/5753
- xg15 5y agoNo offense but the article sounds a bit as like rediscovering GOTO. That's all and well, but we should keep in mind why GOTO was abandoned in the first place. I mean yes, in the end, control blocks and break/continue statements are just special cases of jumps. But the innovation was in the other direction: Discovering that the vast majority of jumps can be classified into a small number of categories - ifs, switches, loops, break, continue... The amazing thing is that you can even restrict your language to allow only jumps from those categories - and you will not lose expressiveness but your programs will suddenly become significantly easier to analyse.