[squeak-dev] Debugger - Proceed button (was: Why is ModificationForbidden not an Error?)

Eliot Miranda eliot.miranda at gmail.com
Tue Sep 29 12:24:06 UTC 2020



> On Apr 11, 2020, at 12:13 PM, Jakob Reschke <forums.jakob at resfarm.de> wrote:
> 
> 
> Think of this: you may not be able to reasonably proceed after an unresumable error without modifying the system or the context. But the IDE lets you do just that: you can change something on the stack in the debugger, or implement the missing method, then proceed and violà, you just reasonably proceeded from an otherwise unresumable error.
> 
> I suppose the methods you mentioned are recursive/repeating to allow for exactly that kind of workflow.
> 
> One should naturally be allowed to Proceed from the notifier window of a Halt or Warning.
> 
> Which leads us to the topic of exception-specific or context-specific buttons in the notifier once again. I don't remember which topic it was, but I wished for that already once during the last few months. Maybe it was the deprecation warnings and now we have an explanation how to deal with Warnings in the notifier and those text actions that allow to disable the warnings on the spot. And as always I'd like to point out that Common Lisp has a nice concept for responding to exceptions both automatically and interactively, with user-code-registered restart operations that can be invoked from the debugger: http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html In Smalltalk you can already use #return, #retry, #resume etc in an exception handler, but you cannot access the handlers nicely from the debugger, and you cannot "resume somewhere along the way to the exception".

*1.  Good points. Good analysis.

>> Am Sa., 11. Apr. 2020 um 16:38 Uhr schrieb Thiede, Christoph <Christoph.Thiede at student.hpi.uni-potsdam.de>:
>> Just another thought: I see some confusion around the Proceed button in the debugger, and I felt the same confusion sometimes ago. Please forgive me for the sacrilege, but should we maybe question its general existence?
>> 
>> Depending on the domain, it actually performs a mix of #retry (made possible by the quite confusing recursive implementation of Object >> #at:, Object >> #doesNotUnderstand: and others, I did not yet found any other motivation than the Proceed button to use recursion here) and ignore (#resumeUnchecked:, especially useful for UnhandledWarnings and Halts). Would it be a reasonable goal to eliminate this button in the pre-debugger window and replace it with two buttons, Restart and Ignore? We could hide even hide the restart button if not appropriate (i.e., the exception is not an error).
>> 
>> What do you think?
>> And it would be great if anyone here could explain why Object >> #at: & Co. are recursive! :-)
>> 
>> Best,
>> Christoph
>> 
>> Von: Squeak-dev <squeak-dev-bounces at lists.squeakfoundation.org> im Auftrag von Thiede, Christoph
>> Gesendet: Samstag, 11. April 2020 16:32 Uhr
>> An: Chris Muller; The general-purpose Squeak developers list
>> Betreff: Re: [squeak-dev] Why is ModificationForbidden not an Error?
>>  
>> Hi all! Thank you very much for having this interesting discussion :-)
>> 
>> 
>> 
>> @Chris:
>> 
>> > > -1. :-) Warnings are Notifications,
>> 
>> > As are Errors.  Right?
>> 
>> Nope, sorry ;-)
>> <pastedImage.png>
>>  
>> <pastedImage.png>
>> 
>> 
>> > The two main use cases of ModificationForbidden present opposite perspectives onto it.  For "protection from accidentally modifying a literal in a CompiledMethod", I understand the inclination to make it an Error.  However, for the context of db handling, [#markDirty + #resume] is normal processing, not an "error", and not even exceptional, either, so perhaps this is just a semantic irritation sensitivity on my part.. sorry. 
>> 
>> > But if they want to use ModificationForbidden for a Write Barrier, they'll probably want to extricate it from Error in the handler:
>> > 
>> >    [ myDbApp doStuff ]
>> >      on: ModificationForbidden
>> >      do:
>> >           [ : forbidden |
>> >           forbidden object beWritableObject.
>> >           forbidden resumptionValue: forbidden retryModificationNoResume.
>> >           forbidden resume: forbidden resumptionValue ]
>> >      on: Error
>> >      do: [ : err | myDbApp logErrorAndNotifyUser ]
>> 
>> This clarification was very helpful for me. I was not aware of your second use case before.
>> 
>> In my opinion, we are talking about two completely different use cases for the same exception.
>> Literal protection is a low-level error, comparable to out-of-bounds things and primitive failures. You almost never do want to ignore or fix them.
>> Write barriers for #markDirty, on the other hand, sound like a domain-specific topic to me that should neither raise an error, nor eventually signal an UnhandledError, but be resumed automatically (unless handled differently) by a #defaultAction that removes the barrier (and additional handlers could, if desired, turn on some cache or so).
>> I have never dealt with Magma or any other DB framework for Smalltalk, but why do you (or would you) use these VM-based mechanisms for a high-level feature? Without knowing any details about your application, personally I would probably design an own exception (DirtyModification?) for that purpose. This would allow you to clearly distinguish between low-level errors ("whoops, I just made an attempt to change a read-only code literal") and higher-level exceptions (DirtyModification). If we would follow my proposal to raise ModificationForbidden from Object instead of Context, you could also consider to override #modificationForbiddenFor:at:put: in your database objects to raise DirtyModification instead of ModificationForbidden (in the same way as some classes override #error or #primitiveError).
>> 
>> However, focusing again on the literal protection aspect, I still don't see when the current default #resume behavior of ModificationForbidden would be ever helpful. MF >> #resume calls Exception >> #resume: which does nothing more than to return resumptionValue! When do we actually need this resumptionValue?
>> Why can't we design MF like the following:
>> 
>> #resume - not possible, will signal IllegalResumeAttempt
>> #retryModification - retries the modification and returns nothing special
>> #forceModification: - makes the object to modify writable, retries the modification and, optionally, makes the object read-only again
>> 
>> > If we don't want to break things (that are somehow wrong according to contemporary notion), we could make it a Warning in the Squeak 5.x release stream and turn it into an error with Squeak 6.0. That is: make it an Error today in Trunk, but if we would create a 5.4 release, we would have to remember changing it back... :-/
>> 
>> IIRC ModificationForbidden was introduced in 6.0alpha the first time?
>> 
>> Best,
>> Christoph
>> Von: Squeak-dev <squeak-dev-bounces at lists.squeakfoundation.org> im Auftrag von Nicolas Cellier <nicolas.cellier.aka.nice at gmail.com>
>> Gesendet: Samstag, 11. April 2020 11:16:00
>> An: Chris Muller; The general-purpose Squeak developers list
>> Betreff: Re: [squeak-dev] Why is ModificationForbidden not an Error?
>>  
>> In this case we might want specialized subclasses...
>> 
>>> Le sam. 11 avr. 2020 à 03:45, Chris Muller <asqueaker at gmail.com> a écrit :
>>> I think so, because if you try to use it for something else, it'll get entangled with your application's standard error handling.  Regular apps have error handling like:
>>> 
>>>    [ myApp doStuff ] on: Error do: [ : err | myApp logErrorAndNotifyUser ]
>>> 
>>> and so for the use-case, Protect CompiledMethod Literals from Accidental Modification, inheriting from Error will allow the best backward compatibility with existing handlers.
>>> 
>>> But if they want to use ModificationForbidden for a Write Barrier, they'll probably want to extricate it from Error in the handler:
>>> 
>>>    [ myDbApp doStuff ]
>>>      on: ModificationForbidden
>>>      do:
>>>           [ : forbidden |
>>>           forbidden object beWritableObject.
>>>           forbidden resumptionValue: forbidden retryModificationNoResume.
>>>           forbidden resume: forbidden resumptionValue ]
>>>      on: Error
>>>      do: [ : err | myDbApp logErrorAndNotifyUser ]
>>> 
>>> But now that I'm handling ModificationForbidden separately, what if I want Protect CompiledMethod Literals from Accidental Modification, too?  I'm no longer handling correctly for that, because the handler has to assume they're signaled in the context of the DB use case and not the Protection use case.
>>> 
>>>  - Chris
>>> 
>>>> On Fri, Apr 10, 2020 at 12:06 PM tim Rowledge <tim at rowledge.org> wrote:
>>>> 
>>>> 
>>>> > On 2020-04-09, at 6:55 PM, Chris Muller <asqueaker at gmail.com> wrote:
>>>> > 
>>>> > The two main use cases of ModificationForbidden present opposite perspectives onto it.
>>>> 
>>>> In that case perhaps we actually need two different signals? 
>>>> 
>>>> tim
>>>> --
>>>> tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim
>>>> Useful random insult:- Has an inferiority complex, but not a very good one.
>>>> 
>>>> 
>>>> 
>>> 
>> 
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20200929/7c5f055e/attachment.html>


More information about the Squeak-dev mailing list