9
$\begingroup$

Bug introduced in 3.0 and persisting through 13.0.1. Wolfram Cloud is not influenced.


This is an issue raised up when I use the function importCode, the following is a simplified sample reproducing the issue. First execute the following line to create 2 cells:

Scan[CellPrint@Cell[#, "Input"] &, {"1\n2", "3"}]

Then execute the first generated cell, you'll see:

enter image description here

As we can see, the output 2 goes to the end of notebook unexpectedly. (If you go on executing the cell containing 3, the 2 in output cell is eaten. This is expected, though. ) Is this a bug or by design? Any work-around? (Because of this, the function importCode isn't working well on code block with multiple outputs for the moment. )

$\endgroup$
6
  • $\begingroup$ Did you evaluate the output of your code? It seems so because of the In[] tags, but you don't say explicitly. I get this output from your code: i.stack.imgur.com/n5TkX.png. I get this when the output is evaluated: i.stack.imgur.com/yI4Mw.png. I get no 2 at all. I question whether Cell["1\n2", "Input"] represents proper input, the cell expression does not contain BoxData. (I don't know the answer, but I ran into trouble with recently.) $\endgroup$
    – Michael E2
    Jun 26, 2022 at 13:58
  • 1
    $\begingroup$ If you enter 1, return, 2, I get a cell with a cell expression like this: Cell[BoxData[{"1", "\[IndentingNewLine]", "2"}], "Input", CellChangeTimes->{{3.865240719373975*^9, 3.8652407198856688`*^9}}], with the input split into a list of strings. $\endgroup$
    – Michael E2
    Jun 26, 2022 at 14:00
  • $\begingroup$ @MichaelE2 Yeah I evaluate the generated cell. Sorry for the vagueness. Clarified. One should not evaluate the second cell containing 3, otherwise the 2 in output cell will be eaten. $\endgroup$
    – xzczd
    Jun 26, 2022 at 14:03
  • 1
    $\begingroup$ I ran into the cell expression trouble here: mathematica.stackexchange.com/questions/269750/… $\endgroup$
    – Michael E2
    Jun 26, 2022 at 14:08
  • 2
    $\begingroup$ Those are relevant: John Fultz comments. $\endgroup$
    – Kuba
    Jun 27, 2022 at 5:04

2 Answers 2

9
$\begingroup$

I don't have full insight so I am encouraging FE team to answer or update this one. Currently I can only more or less explain what is going on but not why/what was the original idea.

The rule of thumb is: CellPrint should be used to generate output-ish cells. Use NotebookWrite for a full control.

Confirmation of the rule are those comments by John Fultz


Explanation

CellsPrint adds CellAutoOverwrite and GeneratedCell options to what it creates so we can already see that those options together with Input style will be problematic.

FE actions when kernel returns an evaluated cell's expression are (based on rough experiments):

  1. Delete all subsequent cells which are CellAutoOverwrite but not Evaluatable.
  2. Insert Cell
  3. Move selection after subsequent GeneratedCells. (Notice the Output cells are GeneratedCells by default)

Sounds reasonable. Maybe you could think about something simpler. Maybe the 3rd rule should exclude Evaluatable again, I don't know, but keep in mind that it should be 30y backward compatible and it has to handle issues like the bug mentioned by JF in the linked comment.

Having those rules explains OP problem, 3 is not good enough to be deleted (has Evaluatable) but selection will move past it (GeneratedCell). It looks weird but is solved with NotebookWrite or if we only print output-ish (non Evaluatable) cells with CellPrint.

Alexey problem is explained as well: Text cell will be deleted because it has CellAutoOverwrite and does not have Evaluatable settings.

$\endgroup$
1
  • 2
    $\begingroup$ Yes, this is pretty much my view. The issue here is that we made something very general and powerful that both takes arbitrary cells without constraints, but also tries to act like Print (in the way that cells can be regenerated and replaced). Those two goals cannot be entirely resolved without conflict, and we erred toward the "arbitrary cells without constraints" side of that conflict, which gives users more power but also rope with which to hang themselves. $\endgroup$
    – John Fultz
    Jul 11, 2022 at 17:41
4
$\begingroup$

I reproduce this behavior with versions 5.2, 8.0.4, 12.3.1 and 13.0.1 on Win10 x64.

I would count this as a long-standing FrontEnd bug. An extended example:

CellPrint /@ {
   Cell["\"First output from Cell#1\"\n\"Second output from Cell#1.  Whoops! How did I get here ???\"", "Input", CellLabel -> "Cell#1"],
   Cell["I'll disappear after evaluation of the previous cell!", "Text",  CellLabel -> "Cell#2"],
   Cell["3", "Input", CellLabel -> "Cell#3"]};

After evaluation of the first printed input cell with label "Cell#1", the "Text" cell with label "Cell#2" disappears. And the second output from "Cell#1" is unexpectedly printed after "Cell#3"!

screen record

As a workaround I can suggest using NotebookWrite instead of CellPrint:

NotebookWrite[EvaluationNotebook[], #] & /@ {Cell["1\n2", "Input"], 
   Cell["I won't disappear after evaluation of the previous cell!", "Text"], 
   Cell["3", "Input"]};

screenshot


Further observations

It's also worth noting that the documentation for CellPrint contradicts its observed behavior. In particulat, it states (in the very first section under the function name):

CellPrint[expr]
inserts expr as a complete cell in the current notebook just below the cell being evaluated.

However, by default CellPrint[expr] inserts expr below the last cell generated by the cell being evaluated (and in this sense behaves exactly like Print):

"Main output"
Print["First Print"]
CellPrint[Cell["First CellPrint", "Input"]]
Print["Second Print"]
CellPrint[TextCell["Second CellPrint", "Text"]]

screenshot

Something similar to the documented behavior happens when we print cells with GeneratedCell -> False option. But as one can see, in this case CellPrint[expr] inserts expr below the last cell with GeneratedCell -> True generated by the cell being evaluated:

"Main output"
Print["First Print"]
CellPrint[TextCell["First CellPrint", "Input", GeneratedCell -> False]]
Print["Second Print"]
CellPrint[TextCell["Second CellPrint", "Text", GeneratedCell -> False]]

screenshot

Hence we also have a Documentation bug.

To summarize the above observations:

CellPrint[expr] inserts expr below the cell being evaluated after the last cell with GeneratedCell -> True above the next cell with GeneratedCell -> False, even if the latter was generated during current evaluation.

Or shorter (official documentation style):

CellPrint[expr] inserts expr just above the next cell with GeneratedCell -> False, or at the end of the evaluation notebook.

However, in order to fully understand the results of CellPrint, one must take into account the general behavior of the FrontEnd when it receives the evaluation result (described in the "Explanation" section of the answer by Kuba). In the first place, one should pay attention to the fact that as the first step the FrontEnd deletes all subsequent cells which have CellAutoOverwrite -> True but not Evaluatable -> True.

$\endgroup$
4
  • 1
    $\begingroup$ Same behavior in v4: i.stack.imgur.com/C43Al.png v3 is broken in a slightly different way: i.stack.imgur.com/wjmlk.png So, it's broken from the beginning. $\endgroup$
    – xzczd
    Jun 26, 2022 at 11:37
  • 2
    $\begingroup$ Thank you for pointing this out. I did notice that we can override GeneratedCell and CellAutoOverwrite by providing them as options in Cell. I don't have experience in this domain, but it seems giving False to both of them on all 3 cells solves the problem (for some reason it prints in reverse order, so a Reverse is also needed). $\endgroup$
    – Ben Izd
    Jul 21, 2022 at 6:36
  • $\begingroup$ @BenIzd I think you're right (main part). As for the parenthetical, when CellPrint is evaluated it "inserts expr as a complete cell in the current notebook just below the cell being evaluated" (see docs). So the last CellPrint is the first thing under the evaluated cell. $\endgroup$
    – Michael E2
    Jul 23, 2022 at 0:07
  • $\begingroup$ @MichaelE2 I added the "Further observations" sections which shows that this docs statement contradics the observed behavor of CellPrint. $\endgroup$ Jul 23, 2022 at 4:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.