Hi Christoph,
... my point here is: Proceeding from an error almost always doesn't seem "right". :-) It is always a decision by the debugging programmer to override the default control flow and switch to the "next plausible alternative control flow", i.e., resume as if the error would have never been raised. Applied to the attempt to return from a method, for me, this means to ignore the return (thinking of it in message sends: to ignore the "thisContext (home) return"). Yeah, and if there is no further statement after that return, my best understanding of the user's intention to "proceed" would be to return to the place from where the block has been invoked ...
Agreed :) The more I think about it the more I like it ;) And well, the non-local return could have been a typo anyways... so actually, this makes the best sense and preserves all options open for the user - perfect!
Also, can you convince me why you would need some extra state in the exception for this?
No, I hated adding an extra state :) The only thing I really need for the full #terminate to work correctly is a way to distinguish between normal proceeding the computation and resuming the unwind procedure when the BlockCannotReturn error occurs inside an unwind block currently being evaluated. All I need then is a Warning the computation proceeds beyond the BlockCannotReturn; here's what I mean:
``` cannotReturn: result
closureOrNil ifNotNil: [ | resumptionValue | resumptionValue := self cannotReturn: result to: self home sender. ProceedBlockCannotReturn new signal: 'This block has ended, continue with sender?'. self pc > self endPC ifTrue: [ "This block has ended, continue with sender" thisContext privSender: self sender]. ^ resumptionValue]. Processor debugWithTitle: 'Computation has been terminated!' translated full: false ```
So if you're fine with this addition, full #terminate would recognize when it's beyond BlockCannotReturn and would continue unwinding the non-local return accordingly.
I think it's useful to warn the user about such an unusual (and new) option as Proceeding safely beyond BlockCannotReturn anyway :)
Argh, here is another example which does not yet match my expectations:
sender := thisContext swapSender: nil. true ifTrue: [^ 1]. "Proceed the BlockCannotReturn" thisContext privSender: sender. ^ 2
I think this should eventually answer 2. Apparently, the VM already has reset the pc in this example so we are helpless here.
There's something wrong with this example :) (or my understanding of it)
1) if you print-it or do-it you get Computation terminated instead of Block cannot return
2) so I wrapped it in [] value ``` [sender := thisContext swapSender: nil. true ifTrue: [^ 1]. "Proceed the BlockCannotReturn" thisContext privSender: sender. ^ 2] value ``` Now it raises BlockCannotReturn and returns 2 with your changeset (if Proceeded)...
BUT
if you debug it and: A) step through the ^1 - you get Message not understood B) step into ^1 - you don't get any error and can happily continue
I'm confused...
Many thanks for your comments and your proposed solution to cannot return; I'll update #terminate and remove my previous attempts from the Inbox. best,
----- ^[^ Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html