Group Abstract Group Abstract

Message Boards Message Boards

1
|
2.6K Views
|
0 Replies
|
1 Total Like
View groups...
Share
Share this post:

A suspected Echo and Print issue with newline

Posted 4 years ago

Postscript after writing this post: I thought I found a bug in Echo and Print. But in fact it was my mistake to misunderstand "Row".

In all my programs I use a global variable testLvl with which I can control echo outputs. I.e.: I can write:

testLvl = 3;
(* ... *)
If[testLvl >= 3, Echo[expr1, label1]]; 
If[testLvl >= 4, Echo[expr2, label2]];

enter image description here

To shorten this further, I have my own echo routine that essentially includes this query of testLvl:

ClearAll[echo];
echo[expr_, label_ : "", lvl0_Integer : 3] :=
  If[testLvl >= lvl0,
   Echo[expr, Row[{{testLvl, lvl0}, ": ", label}]]
   , expr];

testLvl = 3;
(* ... *)
echo[expr1, label1];
echo[expr2, label2, 4];

testLvl = 4;
(* ... *)
echo[expr1, label1];
echo[expr2, label2, 4];

enter image description here

In doing so, I ran into the following problem within my echo routine:

The label in Echo[expr, label] should be any expression. According to the documentation it does not have to be a String. Therefore, it could be any Row as an example.

This works:

Echo[E, "1.: E - Label as a String: "]; 
Echo[E, Row[{2, ".: E", " - Label as a Row: "}]]

enter image description here

If newlines appear in a String label, Echo still works fine (except for the indentation of the expression):

Echo[N[E], "3.: N[E]\nLabel as a String:\n"]

enter image description here

But when newlines occur in a non-string label, say a Row label, a problem occurs. The label is split and the expression appears somewhere in between:

Echo[N[E], Row[{4, ".: N[E]\nLabel as a Row:\n"}]]

enter image description here

I was afraid this is a Print bug. In any case, Print shows the same (assumed mis-) behavior:

Print[Row[{5, ".: N[E]\nLabel as a Row:\n"}], N[E]]

enter image description here

It occurs when Print outputs not only a pure Row or a sequence of expressions. Otherwise everything is fine:

Print[6, ".: N[E]\nLabel as a String:\n", N[E]];
Print[Row[{7, ".: N[E]\nLabel as a String:\n", N[E]}]];

enter image description here

Print's documentation says that Print[expr1,expr2,...] concatenates the expressions and effectively uses Row. I.e.: Print[Row[{expr1,expr2,...}]] should output the same. This remains true if one of the expressions is itself a Row, but the result seems wrong at first sight:

Print[Row[{8, "a.: N[E],\nLabel as a String:", "\n"}], N[E]];
Print[Row[{Row[{8, "b.: N[E],\nLabel as a String:", "\n"}], N[E]}]];

enter image description here

It wasn't until I was writing this post that I realized I had misunderstood "Row" in this context, since Row exhibits the same behavior. The elements of Row are not simply concatenated like in a typewriter, but each part is formatted separately in StandardForm (line wrapping if necessary) and the individual results are concatenated:

Row[{Row[{8, "bR.: N[E],\nLabel as a String:", "\n"}], N[E]}]

enter image description here

Going back to my original problem (see example 4 above) you just have to convert the label to a String to fix it. Of course, you can then no longer place arbitrary expressions in the label, but only those that can be meaningfully converted to a string. To solve our newline problem, it is better to use EchoFunction when the label ends with a newline:

Echo[N[E], Row[{4, ".: N[E]\nLabel as a Row:\n"}]];
Echo[N[E], 
  ToString@Row[{9, 
     ". = 4.Fixed: N[E]\nLabel as a Row converted to String:\n"}]];
EchoFunction[
   Row[{Style[
       Row[{10, ". = 4.Fixed: N[E]\nLabel as a Row echoed with \
EchoFunction:"}], "EchoLabel"],
      "\n", #}] &][N[E]];

enter image description here

Because it is difficult to determine in the general case whether a label ends with a newline, I make a new function echoNl that brings the expression under the label:

ClearAll[echoNl];
echoNl[expr_, label_ : "", lvl0_Integer : 3] := Module[{myLbl},
   If[testLvl >= lvl0,
    myLbl = Row[{{testLvl, lvl0}, ": ", label}];
    EchoFunction[Row[{Style[myLbl, "EchoLabel"], "\n", #}] &][expr]
    , expr]
   ];

testLvl = 3;
(* ... *)
echoNl[expr1, label1];
echo[expr2, label2, 4];

testLvl = 4;
(* ... *)
echoNl[expr1, label1];
echo[expr2, label2, 4];

enter image description here

This is my final solution.

Attachments:
POSTED BY: Werner Geiger
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard