5 ms·
For those unaware, Ruby blocks (and procs) are more flexible than anonymous functions as most language implement them. The article briefly goes over that, menti
by maxlapdev 1y ago
For those unaware, Ruby blocks (and procs) are more flexible than anonymous functions as most language implement them. The article briefly goes over that, mentioning that lambda (regular anonymous functions) and procs (blocks) don't treat execute `return` the same way. There are also particularities with regard to next (continue) and break.
I made a post about the niceties of blocks: https://maxlap.dev/blog/2022/02/10/what-makes-ruby-blocks-great.html https://maxlap.dev/blog/2022/02/10/what-makes-ruby-blocks-gr...
- jbverschoor 1y agoWhich is exactly what I don’t like about them. They should’ve used a different keyword or something. This runs you into problems similar to missing a break in such statements with many language
- HellzStormer 1y agoI don't understand what problem you are referring to? A different keyword for what? for the return? for the break? Care to share an example problem?
- jbverschoor 1y agoReturn for example would be return_caller or something (naming is hard) Return in lambda/proc is error-prone
- chowells 1y agoFlexible in a way, sure. But non-locality is generally a bad property, not good. Adding it is a workaround for all the enumeration methods using blocks in a way that makes people think they're weird looping syntax instead of a fundamentally different idea. People want to do early returns from looping over a collection, so take the easy solution of adding more messy language semantics instead of finding a semantically simple solution instead. (For that matter, have fun working out the semantics of break and next when used in a block that isn't an argument to an enumeration method. How do you as a method author opt in to distinguishing between the two after yielding to a block?) This is generally the case with Ruby everywhere. Why does that thing have an edge case with weird semantics? To work around the edge case with weird semantics somewhere else. It's all fine if you want to just try things until something works. But if you want to really understand what's going on and write code that's a first-class participant in the language features, it gets really frustrating to try to deal with it all.
- vidarh 1y agoIt's really not that complex. For my (buggy, unfinished, languishing without updates) prototype Ruby compiler, lambda and proc (and blocks) are all implemented nearly the same way, with the exception that for proc/blocks, return/break/next will act as if having unwound the stack to the scope where the proc was defined first (or throw an error if escaped from there). The distinction is very obvious when you think of it in that way - a proc acts as if called in the context/scope it was defined, while a lambda acts as if called in the scope it is called in. > How do you as a method author opt in to distinguishing between the two after yielding to a block? You don't. A block acts as a proc, not a lambda. If you want lambda semantics, then take a lambda as an argument - don't take a block/proc and be surprised it doesn't act like something it isn't.
- chowells 1y agoGiven that you completely ignored what I said I wanted to do and gave an answer for some other question, I'm pretty sure it's more complicated than you think. I want to write a method that takes a block and distinguishes between next and break, exactly like the methods of enumeration do. It's obviously possible because a super common interface does it. Last time I looked, that interface does it by being written in native code that interfaces with the interpreter. That is, it's not part of the language semantics. It's a special case with weird rules unlike what anything else gets to do. Or at least it was. Maybe the language has actually made it accessible since then, but I'm not optimistic. That's not the ruby way.
- kayodelycaon 1y agoI think you’re seeing the base language. Effectively blocks are self-contained chunks of code. You can change things around them, but you can’t change how keywords work inside them. Because you’re crossing a method boundary when you call a block you’re not able to access next and break. (Or capture return.) Ruby is defining scope here and C methods are not limited by the language they define.
- 1y ago