Subject: Re: bug#44155: Print integers as characters

From: Mattias Engdegård <[email-masked]>
Date: Sun, 1 Nov 2020 21:52:13 +0100

1 nov. 2020 kl. 19.35 skrev Juri Linkov <[email-masked]>:

> Thanks for bringing a fresh perspective to this feature request.

You are very graceful. The devil is in the details, as always!

> (prin1-char 10) ?\C-j
> (prin1-char 127) ?\C-?
> 
> Or should 10 be printed as '?\n'?

Yes, I think ?\n is more useful. As a character, 10 is more commonly thought of as newline than as control-j.

>> What to use for the rest depends on the user's preference really --
>> for example, 31 might be printed as 31, ?\037, #o37 or #x1f.
> 
> Maybe more user choices should be supported by the variable?

Maybe, but only if we can identify sensible such choices. Otherwise we should just try to pick the best representation in each case. Giving users too much choice isn't necessarily making them a favour!

I'd suggest plain number syntax for control characters without named escapes, for several reasons:

* Such numbers are less likely to represent characters and more likely to be, well, numbers.
* It would allow a separate radix control to govern their output format.
* Writing ?\x1f is no clearer than #x1f, and sometimes more confusing: \xff is a raw byte in a string, but ?\xff is always 255.

Thus we would have 10 -> ?\n, 13 -> ?\r, 127 -> ?\d, 65 -> ?A, 255 -> ?ÿ, but 31 -> 31, 129 -> 129, 4194303 -> 4194303.

>> Whether to print 32 as ?‹SPACE› or ?\s is a matter of taste.
> 
> ?\s is less error-prone.

Yes, I agree. (I prefer ?\s or 32 as characters, but " " in strings.)

>> For that matter, the variable name should perhaps start with 'print-'
>> like other variables that control printing.  Maybe we should separate
>> the default radix and print integers as characters?  Thus, we'd have:
> 
> The variable name was modeled after the similar variable float-output-format.

I see, interesting! One possibility would be to use a string in the same way, thus "%x", "%c" etc, but it makes less sense for integers than floating-point: no precision field, and many format alternatives such as %#x do not produce valid Lisp read syntax. Better keep it simple.

>> print-integer-radix -- 2, 8, 16, 10 or nil (which means 10)
>> 
>> print-integers-as-characters -- nil or t
> 
> What should be printed when both variables are bound to non-default values,
> e.g. print-integers-as-characters to t, and print-integer-radix to 16?
> Maybe to print with character syntax and the given radix, e.g. '?\x1f'.

Well, it should clearly use character syntax for printable characters and the given radix for non-characters. As you correctly point out, what to use for non-printable characters (C0 and C1 controls, raw bytes) is less obvious. I'd probably just use the given radix; I see no readability advantage in printing ?\x1f to #x1f.

Since your original motivation was to print characters in pretty-printed nested Lisp expressions, perhaps we should just define print-integers-as-characters as a Boolean and skip the radix for the time being? We could add a print radix control later on if desired. (That would save us the hassle to deal with bignums, for that matter.)