Open AntoinePrv opened 1 year ago
I don't really understand what is the problem here, executing 1+1
in a cell produces the expression ans = 2
which does not end in a semicolon, so is correctly displayed...
See this screenshot of the kernel spy:
This may be something that is different between Octave and Python.
Notice the [2]: 2
in the Python output? This is because in Pyhon 1+1
does not print anything, it's IPython that decide to print the last value in a different channel from what Python would print (in print(1+1)
).
Similarily, when doing a = 2
, Python does not print anything, but Octave does.
I wonder if we can get Octave to run in "script" mode, where it would print only explicit calls to stdout/stderr, and control the cell output from xoctave
.
Or perhaps that is not what user except?
Ok thank you, I understand now.
So all this is happening because when the interpreter executes a line without the semicolon it will always call display (indipendently of xoctave), which in this case is defined inside display.m
and calls display_data.
If you wanted something like ipython, you would need to prevent octave from calling display
either by adding manually the semicolons or automatically by editing the code before execution (or by changing the parse tree) or by clearing the display
function. Then after the execution the xinterpreter should check if the ans
symbol is defined and send the execute_result
response (I think you're referring to that, right?). I don't know about a "script mode" (it would probably be called silent mode in octave), it might exist actually.
However in my opinion this is far from what the Octave user expects, as we're used to being able to show variables just by removing the semicolon. I think if this behaved as ipython, any experienced octave user would think that it's not working.
For me, for example, this is a major point, and one of the reasons I still won't use ipython: I often need to see what the content of a variable is and it would be cumbersome to write a printf call any time I need to do that.
If you really think this is important, maybe it could be a configurable behaviour, but I think we should be keeping the current one at least as a possibility (if not the default).
execute_result response (I think you're referring to that, right?
Yes.
However in my opinion this is far from what the Octave user expects, as we're used to being able to show variables just by removing the semicolon. I think if this behaved as ipython, any experienced octave user would think that it's not working.
I also think we should stick to Octave behavior as much as possible.
I wonder then if we should ever send something in the execute_result response
. For instance should xoctave print anything if there is a;
at the end of a cell? If yes then would should print a
at the end of cell, octave or xoctave?
Another thing with Ipython (and the execute_result response
) is that it set a variable _2
(or whichever the count is) with that value. A bit like ans
but more general.
I wonder then if we should ever send something in the
execute_result response
.
At the moment no execute_result
is sent. In the past I purposefully chose not to use it because I couldn't display more than one output and so display_data
became my primary choice.
In my opinion we could keep this behaviour, as inside JupyterLab there is no visual difference (besides the little [1]
to the left of the output) between the two methods, unless such answer is needed in other cases (e.g. if the kernel were used to do some kind of scripting via the jupyter protocol) and the single result per cell actually made more sense.
If this were the case, maybe it could be made optional, and the result could be sent anyway independently of the semicolon, whenever the ans
symbol has been set after a cell execution. We would then possibly have two identical outputs, like this (but it would be after the user decided to do so):
In [0]: enable_execute_result
In [1]: 2 + 2
ans = 4 <= this would be from the display call
Out [1]: 4 <= this would be from the execute_result message
Another thing with Ipython (and the execute_result response) is that it set a variable _2 (or whichever the count is) with that value. A bit like ans but more general.
Totally possible and I quite like the idea. It would be enough to assign to a new variable the ans
value after every cell execution
I've been doing some research on this, related to the _jupyter_repr_
proposal.
The idea would be that _jupyter_repr_
would be called for the last statement in each cell, as it is done in ipython (in addition to native octave display called for each statement not ending in semicolon).
As a reference, octave displays an output value when a statement without semicolon is:
expression -> identifier
(but only a variable not a function, only known at evaluation time)expression -> assignment
In addition it will also assign and print the ans
variable when an expression has a return value, to which we don't have access (unless we execute the parse tree manually)
This has turned out to be quite difficult and I have not found a decent solution yet.
The main reason is that I haven't found a way to reliably decide if a statement is a function or a variable and if it returns a value or not (the two things buried in the octave code). For example the expressions:
x
(where x
is a previously defined variable)sombrero
(where sombrero
is a function, without parentheses, which is a valid syntax)Have the same parse tree:
graph TD;
statement --> expression
expression --> identifier
Yet one has a meaningful value, the other one shall not return anything, in fact the following expressions are and behave differently:
sombrero
does not return anything and displays a plotret = sombrero
returns the plot contents and does not display anythingThis is what I tried:
__xoctave_display_execution_result__
. Like the following
From:
code
code
x = 2
To:
code
code
__xoctave_display_execution_result__(x = 2)
Doesn't work: if the statement is a function, it forces a return value, potentially altering the code flow.
ans
variable, if the value has changed call __xoctave_display_execution_result__
on it.
Doesn't work: not all expressions set a ans
variable, and there is no easy way to know it a priori. Also two different cells might set exactly the same ans value and no change would be detected
Executing
1+1
does not output but only prints tostdout
.jupyter_kernel_test
activation