11

Behavior remains unchanged through Mathematica version 13.0.0


As noted by kguler the FrontEnd option: MessageOptions -> "MaxMessageCount" does not appear to have any effect on the number of times a Message is repeated before General::stop is issued and that particular Message is suppressed.

I would like to know if it is supposed to have this effect but is broken, or if it does something else entirely. I cannot find any documentation for this Option, and I cannot find any examples of its use either here or in the MathGroup archives.

Alexey Popkov
  • 61,809
  • 7
  • 149
  • 368
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371

1 Answers1

3

On[General::stop] and Off[General::stop] work without the FrontEnd, and the latter shouldn't be necessary for this functionality. Hence it is very doubtful that the developers would attach an option controlling their behavior to the $FrontEnd. If such an option exists, it should live in the Kernel.

According to the Documentation page for General::stop (emphasis is mine):

  • This message is generated after the indicated message has been generated for the third time in a single evaluation.

On the Documentation page for Message we read (emphasis is mine):

  • Between any two successive input lines, the Wolfram Language prints a message with a particular name at most three times. On the last occurrence, it prints the message General::stop.
  • Off[General::stop] makes the Wolfram Language not stop repeating messages.

Hence it looks like the maximum number of printed messages is hard-coded, and isn't supposed to be altered by a user.

Nevertheless, we are able to change the default behavior by overloading Message. For example, here is a simple solution intended for implementing manual subkernel management from my old MathGroup post:

I have found the solution. It exploits elegant hack by Todd Gayley. Here it is (of course, it must be evaluated in the slave kernel):

$globalMessageList = {};
Unprotect[Message];
Message[args___] :=
 Block[{$inMsg = True, $MessageList = $globalMessageList},
    Message[args];
    $globalMessageList = $MessageList;
    ] /; ! TrueQ[$inMsg];
Protect[Message];

One can fully emulate standard behavior of Messages in the slave kernel by checking the current value of $Line and comparing it with previous value:

If[TrueQ[$Line > lastLine], 
  LinkWrite[$kern,  
    Unevaluated[ExpressionPacket[$globalMessageList = {};]]]; 
  LinkRead[$kern]]; lastLine = $Line;

This recent answer contains a modern implementation for the built-in Parallel* functionality.

For the Main Loop, it can be implemented in a similar manner with the only addition that some built-in functions may depend on implementation details of Message, which updates some internal event counters including $MessageList (and affects event listeners as well). Hence it seems reasonable that we have to evaluate Quiet[Message[mn, args]] when we don't want a message to be printed, in order do not break this functionality:

Off[General::stop];
Unprotect[Message];
Message[mn_MessageName, args___] := Block[{$inMsg = True},
   If[Not[AssociationQ[$EvaluationMessages]] || $EvaluationMessages["$Line"] =!= $Line, 
       $EvaluationMessages = <|"$Line" -> $Line|>];
   If[! NumericQ[$EvaluationMessagesLimit], $EvaluationMessagesLimit = 3];
   If[KeyExistsQ[$EvaluationMessages, HoldForm@mn], 
     ++$EvaluationMessages[HoldForm@mn], $EvaluationMessages[HoldForm@mn] = 1];
   If[$EvaluationMessages[HoldForm@mn] <= $EvaluationMessagesLimit, 
     Message[mn, args], Quiet[Message[mn, args]]]
   ] /; ! TrueQ[$inMsg]
Protect[Message];

Here is how it can be used:

$EvaluationMessagesLimit = 1;
Do[1/0, 20]
$EvaluationMessages

screenshot

(The screenshot is from version 13.0.0; I don't know from where comes the ToExpression::sntx Message call.)

Alexey Popkov
  • 61,809
  • 7
  • 149
  • 368
  • 2
    I guess it's still unclear whether "MaxMessageCount" is supposed to do this or not? -- Related: EvaluationData and Internal`AddHandler (see https://mathematica.stackexchange.com/a/20371/4999) – Michael E2 Jan 28 '22 at 14:35
  • @MichaelE2 On[General::stop] and Off[General::stop] work without the FrontEnd, and the latter shouldn't be necessary for this functionality. Hence it is very doubtful that the developers would attach an option controlling their behavior to the $FrontEnd. (Thanks for the links, BTW!) – Alexey Popkov Jan 28 '22 at 15:33