Open samth opened 3 days ago
Thanks for the report.
Although I'm 99% sure configure-runtime
is being called, I'll double check.
The bug seems to require that the Emacs customization variable racket-pretty-print
is the default t
, which causes the back end to use pretty-print
. I can reproduce with that, but not with plain print
, which IIUC is what command-line racket
would do.
Although that narrows it down a little, I'm not yet sure exactly where/what the problem is, and who needs to solve it, how. But I'll look...
What I've been able to figure out so far:
rhombus' configure-runtime sets a special value for global-port-print-handler
procedure. This is happening in Racket Mode. (Amusingly I can see it affecting log-debug
~v
values, from Racket code.)
However that's N/A -- the current-print
parameter is what is used by (a) REPL printing and (b) #%module-begin
. The latter is applicable when you run your example program.
In addition to struct props for individual values, there is a small zoo of print-ish handlers:
current-print
per-thread parameterport-{print display write}-hander
per-port functionsglobal-port-print-handler
global functionI am not 100% confident which are intended to be used by (a) end user programs, (b) languages, and (c) tools.
I do know that Racket mode (re)sets these before each run, but doesn't touch values changed by the language, libs, and/or end user program (which AFAICT is the right thing to do?).
I am not sure but maybe rhombus ought to set current-print
and perhaps pretty-print-{print size}-hook
functions? Or at least change its #%module-begin
not to use current-print
?? Again I'm not 100% clear what's intended.
Just calling Racket's pretty-print
in Rhombus results in the same printing as I see in racket-mode:
#lang rhombus
import lib("racket/main.rkt") as r:
expose #{pretty-print} as pretty_print
class M(x)
pretty_print(M(1))
I'm not sure what exactly the right configuration should be here, maybe @mflatt would have a suggestion. Alternatively, maybe just drop automatic pretty-print for rhombus files?
Alternatively, maybe just drop automatic pretty-print for rhombus files?
Yes. In fact it occurs to me now that racket/pretty
is thoroughly s-expression oriented. I recall seeing code in rhombus suggesting it has its own concept of pretty printing, which makes sense.
I'd love that to be lang
-driven not ad hoc, if possible. That is, some way for a lang to say, "If a user prefers pretty-printing for module-begin and REPL, my global print handler already does that by default, just use that." For example.
p.s. I think it's also possible that racket/pretty
might have a bug where it's not using the global print handler, somehow? But that might be moot, here.
Thinking about this a little bit more, maybe I should use pretty-print
only if the user prefers that, and default-global-port-print-handler
is in effect:
(define (make-racket-mode-print-handler pretty? columns pixels/char)
(define (racket-mode-print-handler v)
(unless (void? v)
(define-values (in out) (make-value-pipe))
(parameterize ([current-output-port out]
[print-syntax-width +inf.0])
(cond
- [pretty?
+ [(and pretty?
+ (equal? (global-port-print-handler)
+ default-global-port-print-handler))
(parameterize ([pretty-print-columns columns]
[pretty-print-size-hook (make-pp-size-hook pixels/char)]
[pretty-print-print-hook (make-pp-print-hook)])
(pretty-print v))]
[else
(match (convert-image v)
[(cons path-name _pixel-width)
(write-special (cons 'image path-name))]
[_
(print v)])
(newline)]))
(drain-value-pipe in out)))
racket-mode-print-handler)
In a quick test, this solves the immediate issue.
The rationale seems... plausible? "If a language has changed the default global port print handler, we can't assume it's an s-expression language and pretty-print
is appropriate. In fact it's best not to assume anything at all -- just use print
and let the handler do its thing."
Anyway that's my least-worst idea, so far. I'll ponder it a bit more. Of course I'm also open to better ideas or advice.
Although I might hold off in case anyone has better ideas, I might go ahead and merge commit bceac44.
It does help with the reported problem.
Admittedly pretty printing would be disabled if something changed the global port print handler, for any reason -- even if the values could still be pretty-printed as s-expressions. So that's a downside. But the values would still be printed.
[I could also enhance the racket-pretty-print
variable from a boolean, to something more complicated, such as three values (always, never, only if default global print handler), or even a dictionary from module language names to such settings. But... I'd prefer to do that with a real-world use-case and user to confirm it works for them, as opposed to proactively.]
Just as an additional note, the racket repl uses pretty-print
and has this problem as well.
Just as an additional note, the racket repl uses
pretty-print
and has this problem as well.
Interesting. It looks like:
The default value of current-print
where it's defined in racket/src/io/run/main.rkt
is just print
+ newline
. And if you $ racket -l racket/base -i
, current-print
in the REPL is that plain, non-pretty print.
However racket/collects/racket/init.rkt
sets current-print
to a pretty-printer
procedure that calls pretty-print
. Which is what you get from the REPL for $ racket
, which opens in the full racket
lang.
I suppose one could say, "Well, you should use $ racket -l rhombus -i
".
On the other hand people do things like run $ racket
, then use xrepl's ,enter
command one or more times during a session, which could be a program using any module language. I think the expectation is this just "just work". (And that's closer to the model for things like Racket Mode, DrRacket, and other such tools.)
So it seems current-print
needs to be lang-driven, somehow. Or pretty-print
needs to be lang-driven. Or there's some new current-pretty-printer
parameter, which can be racket/pretty
's pretty-print
, or whatever else the lang decides. Or... something...
On the other hand people do things like run
$ racket
, then use xrepl's,enter
command one or more times during a session, which could be a program using any module language.
Well. You might use ,enter
to run a #lang rhombus
program... once. Thereafter, you're stuck. AFAICT. The xrepl command trick ("we can use ,
because a stand-alone quasiunquote
isn't legal") doesn't work anymore, understandably for rhombus syntax.
p.s. Also I couldn't ,exit
. (Not even C-c worked. I had to kill the terminal shell window.)
No real answers, but some possibly relevant information.
The Racket REPL uses pretty-print
because the default -I
is -I racket/init
, and it's racket/init
that installs the pretty printer. To work in Rhombus mode, I use -I rhombus
, which does not install the racket/pretty
printer, but does install a Rhombus pretty printer via configure-runtime
. Note that -I racket
would not set the printer, because its configure-runtime
doesn't do that.
DrRacket injects pretty printing by setting global-port-print-handler
, as opposed to current-print
. The rhombus
configure-runtime
submodule replaces that global port print handler with one that uses Rhombus printing. Meanwhile, note that racket/init
sets current-print
, but rhombus
(via configure-runtime
) sets global-port-print-handler
.
XREPL recognizes ,exit
and similar even when starting with -I rhombus
. That's because XREPL checks an input string for whitespace followed by ,
. The shrubbery syntax and reader cooperate slightly by agreeing that something like ,exit
is ready to evaluate (as opposed to ,(
, for example), even though it would read as an error.
Using ,enter
in XREPL uses enter!
, which does not attempt to load configure-runtime
or similar, and the configure-runtime
protocol is not really set up for going into different modules. The configure-expand
protocol is more set up for that with enter-parameterization
and exit-parameterization
, which is more compatible with the idea of switching contexts. But the protocol does that by swapping whole parameterizations; I'm not sure that's the right idea for run-time swapping, but maybe it would work. In short, to make a REPL adapt to different contexts, probably we'd want.a new submodule with a enter—exit protocol, and maybe the configure-expand
approach would be good for that.
Please copy all of the following lines and paste them into your bug report at https://github.com/greghendershott/racket-mode/issues/.
Package
System values
Buffer values
Racket Mode values
Minor modes
Disabled minor modes
Steps to reproduce:
Write a rhombus file like this:
Run it in racket-mode.
It prints like this:
Run the file with racket at the command line.
It prints like this:
My theory is that racket-mode is not calling
configure-runtime
correctly but I have not investigated this at all.