How to make a custom Echo
Here is how I would approach this:
Clear[myEcho, myEchoCounter]
myEcho::stop = "Further output from `` will be suppressed during evaluation of In[``].";
myEcho[, ] := myEcho[];
myEcho[label_: Null, max_: 3][expr_] /; myEchoCounter[$Line, label] >= max := expr
myEcho[label_: Null, max_: 3][expr_] := (
If[Not@NumberQ[myEchoCounter[$Line, label]], myEchoCounter[$Line, label] = 0];
If[myEchoCounter[$Line, label] < max,
If[MatchQ[label, Null | None], Echo[expr], Echo[expr, label]]];
If[++myEchoCounter[$Line, label] == max,
Message[myEcho::stop, "myEcho"[label, max], $Line]];
expr);
Now
(myEcho["Before Table"][x]; Table[myEcho["Table"][x], {x, 10}]; myEcho["After Table"][x])
(Table[myEcho[, 3][x], {x, 10}]; Table[myEcho[, 6][x], {x, 10}])
Another way to do this:
In[1]:= << GeneralUtilities`
In[2]:= $MaximumEchoRate = 5;
In[3]:= Table[EchoHold@x, {x, 10}]
x \[Function] 1
x \[Function] 2
x \[Function] 3
x \[Function] 4
x \[Function] 5
During evaluation of In[3]:= Maximum echo rate exceeded, change $MaximumEchoRate to adjust.
Out[3]= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
crit = 2;
SetAttributes[MyEcho, HoldAll]
Module[{res},MyEcho[label_, return_, subexpr___] :=
If[NumberQ[label],If[label >= crit, return,
label++; res = Echo[return, subexpr];
If[label == crit, Print["Already " <> ToString[crit] <> " Echo here!\nNo more Echo allowed!!!!"]];res],
label = 1; Echo[return, subexpr]]]
$Pre =
Function[{expr}, ReleaseHold[Hold[expr] /. HoldPattern[Echo[subexpr__]] :>
With[{u = Unique[]}, MyEcho[u, subexpr] /; True]], HoldAll]
Similar results, but a bit more integrated and more carefully protected.
Note that one can still save the old $Pre
by adding it in front of this code.(one must limit the functionality of old $Pre
to an extent that full evaluation of expressions is forbidden)