[Tim] > So what would this look like in Continuation Python? [Sam] > Here's my first hack at it. Most likely wrong. It is > REALLY HARD to do this without having the feature to play with. [Skip] > The thought that it's unlikely one could arrive at a reasonable > approximation of a correct solution for such a small problem without the > ability to "play with" it is sort of scary. Yes it is. But while the problem is small, it's not easy, and only the Icon solution wrote itself (not a surprise -- Icon was designed for expressing this kind of algorithm, and the entire language is actually warped towards it). My first stab at the Python stack-fiddling solution had bugs too, but I conveniently didn't post that <wink>. After studying Sam's code, I expect it *would* work as written, so it's a decent bet that it's a reasonable approximation to a correct solution as-is. A different Python approach using threads can be built using Demo/threads/Generator.py from the source distribution. To make that a fair comparison, I would have to post the supporting machinery from Generator.py too -- and we can ask Guido whether Generator.py worked right the first time he tried it <wink>. The continuation solution is subtle, requiring real expertise; but the threads solution doesn't fare any better on that count (building the support machinery with threads is also a baffler if you don't have thread expertise). If we threw Python metaclasses into the pot too, they'd be a third kind of nightmare for the non-expert. So, if you're faced with this kind of task, there's simply no easy way to get it done. Thread- and (it appears) continuation- based machinery can be crafted once by an expert, then packaged into an easy-to-use protocol for non-experts. All in all, I view continuations as a feature most people should actively avoid! I think it has that status in Scheme too (e.g., the famed Schemer's SICP textbook doesn't even mention call/cc). Its real value (if any <wink>) is as a Big Invisible Hammer for certified wizards. Where call_cc leaks into the user's view of the world I'd try to hide it; e.g., where Sam has def walk (self, x): if type(x) == type([]): for item in x: self.walk (item) else: self.item = x # call self.suspend() with a continuation # that will continue walking the tree call_cc (self.suspend) I'd do def walk(self, x): if type(x) == type([]): for item in x: self.walk(item) else: self.put(x) where "put" is inherited from the base class (part of the protocol) and hides the call_cc business. Do enough of this, and we'll rediscover why Scheme demands that tail calls not push a new stack frame <0.9 wink>. the-tradeoffs-are-murky-ly y'rs - tim
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4