
\documentclass[12pt]{article}
\usepackage[T2A,OT1]{fontenc}
\usepackage[default]{cantarell}
\usepackage[a4paper, top=20mm, bottom=20mm, left=20mm, right=20mm]{geometry}
\usepackage[utf8]{inputenc}
\usepackage[russian, english]{babel}
\usepackage{tabu}
\usepackage{hyperref}
\usepackage{parskip}
\usepackage{graphicx}
\usepackage{tabularx}
\usepackage{float}
\floatstyle{boxed}
\restylefloat{figure}
\usepackage{setspace}
\onehalfspacing
\author{Artyom Bologov}
\date{\today}
\title{Text UIs != Terminal UIs}
\makeatletter
\def\endenv{\expandafter\end\expandafter{\@currenvir}}
\makeatother
\begin{document}
\maketitle

\begin{figure}[h!]
\includegraphics[width=\textwidth,height=\textheight,keepaspectratio]{./assets/cowsay-tui-not-tui.png}
\caption{Listen to what the cow has to say}\end{figure}

I’m working on an audio-only Lisp cyberdeck.
A part of this project is making Lisp REPLs audio-friendly.
The trouble with most of them is that they overabuse text graphics.
And screen readers and voice synthesizers are not good at text graphics.

Debuggers are especially suffering from this pseudo-graphics frenzy.
Here’s how the debugger looks on SBCL, the most popular Lisp implementation:

\begin{figure}[h!]\begin{verbatim}
debugger invoked on a SB-INT:SIMPLE-PROGRAM-ERROR @53E0C809 in thread
#<THREAD tid=12793 "main thread" RUNNING {100AEF00A3}>:
  invalid number of arguments: 0

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [REPLACE-FUNCTION] Call a different function with the same arguments
  1: [CALL-FORM       ] Call a different form
  2: [ABORT           ] Exit debugger, returning to top level.
\end{verbatim}\caption{SBCL debugger listing}\end{figure}

\begin{itemize}\item Hash reader syntax (built into the language).
\item Opaque hexadecimal hash strings.
\item Square brackets.
\item Indentation.
\end{itemize}

All these make my setup with Espeak go mad:

\begin{figure}[h!]\begin{verbatim}
sb dash int colon simple dash program dash error
at fifty three ee zero cee eight hundred and nine
\end{verbatim}\caption{Espeak reading of text graphics in SBCL}\end{figure}

And that’s just the
\verb|SB-INT:SIMPLE-PROGRAM-ERROR @53E0C809| part!

Dashes/hyphens are a vital part of Lisp kebab-case naming.
And they are proper English too, so Espeak is alright with them.
But a lot of the other clutter SBCL produces makes Espeak die in agony.
This "clutter" is there for aesthetics and "graphicality" of the UI.
Compare SBCL example to ECL’s debugger screen:

\begin{figure}[h!]\begin{verbatim}
Condition of type: SIMPLE-PROGRAM-ERROR
Wrong number of arguments passed to function ERROR.

Available restarts:

1. (RESTART-TOPLEVEL) Go back to Top-Level REPL.

Broken at SI:BYTECODES. [Evaluation of: (ERROR)] In: #<process TOP-LEVEL 0x7f12eb4d7f00>.
\end{verbatim}\caption{Debugger screen on Embeddable Common Lisp}\end{figure}

There still are some graphics, like parentheses and braces, true.
But most of the information is expressed via text.
The most accessible communication medium.
As a side effect, Espeak reading of ECL debugger screen takes half of SBCL reading time.
The number of characters is comparable.
ECL clearly is just more productive with the air time.
And it makes me productive too, because I can take action faster.

That’s why I want to emphasize this: text interfaces are not the same as terminal interfaces.
Want audio or variety of modal interfaces?
You’d better ensure that your output is conversational.
Luckily, conversational interfaces are on the rise today, with AI chat apps.

Text is accessible and easy to process.
So ensure your text interfaces are this: text.
Prose.
Conversation.
Description.
No one needs text graphics anyway—there are Graphical (sic) User Interfaces for that.
So make your product readable first and foremost.

Disclaimer: I don’t want to impose any course of action on any product, actually.
Especially so—on Lisp implementations.
SBCL is good at what it does, deserving the status of the best FOSS implementation of Common Lisp.
It’s just that my cyberdeck will use ECL instead of SBCL for readability purposes 😛

EDIT: As a bit of constructive suggestion, here’s how an audio-friendly debugger might look.

\begin{figure}[h!]\begin{verbatim}
SB-INT:SIMPLE-PROGRAM-ERROR: invalid number of arguments: 0

Type HELP for debugger help.

Restarts (invokable by number or by possibly-abbreviated name):
0 REPLACE-FUNCTION: Call a different function with the same arguments
1 CALL-FORM:        Call a different form
2 ABORT:            Exit debugger, returning to top level.
\end{verbatim}\caption{Debugger that is both audio-friendly and easy on the eye}\end{figure}

While opinionated, it gives the necessary minimum of information to act on.
Without the visual clutter and scary hex codes.
One can further reduce the noise deleting the notes on restarts and help, like CCL does:

\begin{figure}[h!]\begin{verbatim}
Error: Too few arguments in call to #<Compiled-function PRINT #x30000017078F>:
       0 arguments provided, at least 1 required.
While executing: PRINT, in process listener(1).
Type :POP to abort, :R for a list of available restarts.
Type :? for other options.
\end{verbatim}\caption{Slightly decluttered variation of CCL debugger screen}\end{figure}

But that’s probably too opinionated for a default setup.

\par\noindent\rule{\textwidth}{0.4pt}
Copyright 2022-2025 Artyom Bologov (aartaka).
Any and all opinions listed here are my own and not representative of my employers; future, past and present.

\end{document}
