3 ms·
He's not proposing to make blocks first-class! That would mean you'd be able to assign blocks to variables, and that makes little sense. Blocks would remain spe
by gizmo 15y ago
He's not proposing to make blocks first-class! That would mean you'd be able to assign blocks to variables, and that makes little sense. Blocks would remain special non-first-class entities.
- raganwald 15y agoNo, he isn’t proposing that blocks be entirely first class. Although... Why not? foo ? bar.map { |x| x * x } : bar.map { |x| x + x } Could be: bar.map foo ? { |x| x * x } : { |x| x + x } Perhaps this is too much or too Ruby-ish: function either (pred) { return pred ? { |x| x * x } : { |x| x + x }; } bar.map(either(foo))
- gizmo 15y agoConsider the following: function map(a, cc) { r = [] a.each{|e| r.push( cc(e) ) } return r } Now `cc` is some kind of callable. It might be a function or it might be a block. Suppose `cc` is a block defined as cc = {|e| return e } Does this mean the `return` in `cc` breaks out of the outer each-loop because it's a block as well, or does the return simply do the normal thing? In the first case you need case analysis every time you write a higher order function in order to make sure the code flow makes sense. This is unacceptable. The alternative is that the "return e" in `cc` behaves like it would in a lambda function (i.e. the map function works correctly). But that means that when you assign a block to a variable you change its semantic meaning. Also completely unacceptable. I see absolutely no way to make first-order blocks work.
- raganwald 15y agoIn the spirit of brainstorming, I think it’s cool to come up with some cases and ask, “what if?” In Yehuda’s article, he gives: withFile: function(block) { try { var f = File.open(this.name, "r"); block(f); } finally { f.close(); } } This is interesting: “block” appears to be a “callable” object. How does the code know whether it will be a block or a function? Can you assign the block parameter to a variable? Pass it to another function? What about: function firstClass (block) { return block; } Can I do this? If so: var thisIsaBlock = firstClass { |x| return x; } And we’re off the rails. Or worse: (function () { var local = ‘0xDEADBEEF'; return firstClass { || local } })()() If I am reading the code example correctly and my inference holds, then either (a) you have to do a lot of escape analysis to make this work, or (b) you get lazy and allow programmers to pass blocks around but emit an exception if you try to call a block once its lambda environment has already returned. I guess I need to read the whole proposal... I am sure this has been addressed.