urbit / urbit

An operating function
https://urbit.org
MIT License
3.43k stars 359 forks source link

dojo: output seems to have extraneous whitespace when outputting a tang from a generator #5556

Closed ynx0 closed 2 years ago

ynx0 commented 2 years ago

Describe the bug When running a generator that outputs a tang, the output does not match the output of running the same data through slog manually.

A small test example by @philipcmonk:

::  gen/tangbug.hoon
:-  %say
|=  [* * *]
:-  %tang
[leaf+"hi\0afive" ~]

Outputs

> +tangbug
hi
  five

contrasted with

hi
five
> ((slog `tang`[leaf+"hi\0afive" ~]) ~)

This also occurs when using ['hi\0afive' ~].

System (please supply the following information, if relevant):

Notify maintainers cc @Fang- @joemfb

dnmfarrell commented 2 years ago

This can be reproduced without a %say generator:

> |pass [%d [%text "hi\0afive"]]
>=
hi
  five

from.dill receives:

[%out p=~[~-h ~-i ~-~a. ~-f ~-i ~-v ~-e]]

and term.c prints it literally, without resetting the column on encountering the newline. Should term.c break-up output into newline-separated lines?

Fang- commented 2 years ago

tldr: "you're using it wrong" (; but also things could be better.

The semantics of tank is a single line of output. As such, a tang consists of any number of lines of output. You generally shouldn't put newline characters into the lines themselves, but rather provide appropriately split lines, ie `tang`['hi' 'five' ~].

The semantics of dill's %text task are less clearly defined, but should probably be treated the same: if you want to output multiple lines, send multiple %text tasks.

It is, of course, a little bit weird that %text requires a carriage return, when slogs don't. (Also extremely weird that +tuba crashes when you include a \0d carriage return, preventing you from working around it that way...) The difference in behavior can be explained by realizing these are two different ways of outputting text, and hit different codepaths in the runtime.

Slogs are fully "fake" in that they don't formally exist in hoon/arvo. They're a nock hint, a debugging printf. At the discretion of the runtime, they will only be visible in the default dill session. We make no assumptions about other sessions, and so cannot safely inject output into the stream.

%text is also somewhat fake, but a little less so. It is a formal effect, dill explicitly requesting the specified text to be shown. But again, only in the default session: dill cannot make assumptions about what goes on in other sessions, and so cannot safely draw something to the screen by itself.

The full solution here is probably to revamp %text entirely, changing its behavior from "show this output" to "tell terminal handler for this session to show this output".

Our facilities for just showing some formal output to the user without doing a whole dang agent have been somewhat limited for a long time. I hope to tackle this as part of the ongoing terminal improvements work.