5 ms·
No, 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 fo
by raganwald 15y ago
No, 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.