I wanted them every time I accidentally evaluated huge data
structure on REPL and just waited Emacs to finish showing it
until the end (Ctrl-C can stop Gauche printing it, but it's
mostly Emacs that's taking time to fill the buffer, especially
when font-lock mode is on.)

By the way, print-base comes handy as desktop calculator
for base conversion:

The global nature of those controls is the problem. I'd like to
limit print-length on REPL output to avoid excessive output.
But doing so globally affects every operation, such as
serialization to file or network connection, which is almost certainly
undesirable. I can create a custom printer for REPL that changes
the controls only when it prints the result, but then I need
another set of API to set those values REPL would use.

Worse, now every routine that writes out values expecting it to
be read back must be wrapped with parameterize to ensure
those control variables are in the default value, otherwise it
can be broken accidentally when called with print-level set to 5.

The more I think, the more dubious I became about the CL's choice
of making them dynamic variables.

Another idea I had before is to have a "context" object that packages
those controls, and you can set it to a parameter, instead of
parameterizing individual controls (the name ScmWriteContext in the
source was somewhat intended for that, but ended up for different
purpose.) With that, the REPL can have just one
repl-default-context and use that for just printing.

Recently I got yet another idea; let a port have those controls.
We already have port-attributes to associate key-value pairs to
ports. For serialization you'll usually create a fresh ports
so the chance of inadvertent interference is very low.
For REPL output, we can create a wrapper port connected to stdout
so that it can have separate attributes, and use it for
printing the results.