Paolo Amoroso's Journal

Tech projects, hobby programming, and geeky thoughts of Paolo Amoroso

I wrote Interpinkie, a basic Finger client in Interlisp that runs on the Medley environment. This is the main window of the program:

Main window of the Interpinkie Interlisp Finger client.

It was a fun challenge considering I couldn't use Medley's TCP/IP stack.

I always wanted to do some network programming with Medley. But the bitrot of its TCP/IP stack left it in a non working state since before the Medley Interlisp project, and the revival effort hasn't got around to the stack yet. The XNS stack still mostly works with the Dodo Services XNS implementation. But, as far as I know, XNS provides LAN services and I'm not sure whether or how it allows access to the outside Internet.

So I cheated and reached for Medley's escape hatch.

As part of the Medley modernization effort, the UNIXUTILS library module provides the ShellCommand function to run a Unix program on the host operating system and send the output to a stream. Since I can run arbitrary Unix commands from Medley, it's trivial to build a client that talks the Finger protocol via Netcat.

For example, to run the Finger query amoroso@happynetbox.com I can just execute this from the Linux shell:

$ echo "amoroso" | nc -C -w 3 happynetbox.com finger

where -C sends \r\n as line-ending, -w 3 sets a timeout of 3 seconds, and finger is the Finger port number as per /etc/services.

All Interpinkie does is to build and feed a query to ShellCommand, pipe the output through tr to remove extra \rs, and redirect the output to a suitable destination.

The Interlisp function QUERY.FINGER.SERVER wraps this functionality. By default the output goes to the primary output (Interlisp jargon for stdout), or optionally to a separate window with menu options for running another Finger query or quitting the program.

Interpinkie builds upon user interface techniques I used in previous projects such as attaching a menu to a TEdit window.

TEdit, the WYSIWYG the rich text editor of Medley, can be driven by other programs that send output to the editor buffer. This is handy as the programs get an automatically repainted scrollable window for free from TEdit. In addition, Interpinkie attaches a command menu to the TEdit window and uses TEdit's prompt window (Interlisp jargon for an edit field and status area) to request input and display errors.

Unlike my previous Interlisp projects, however, Interpinkie doesn't call the TEdit API to insert text in the buffer. Instead, the program redirects the ShellCommand output to the Lisp stream associated with the TEdit window, causing the text to appear in the buffer.

By default ordinary Lisp printing functions such as PRIN1 and PRINT send the output to the REPL or optionally to another Lisp I/O stream. Along with these output destinations, some Interlisp components and programs like TEdit have an associated stream. So it's easy to send output to TEdit by just printing to the stream returned by (TEXTSTREAM Window), where Window is a TEdit window, or redirecting to that stream the output of printing functions like PRIN1. In other words, ordinary stream I/O is the API.

Since ShellCommand accepts a stream as an optional argument, QUERY.FINGER.SERVER passes TEdit's stream to ShellCommand thus causing the output to go to the editor buffer. The benefit is Interpinkie uses the same QUERY.FINGER.SERVER function to output to both the primary output and a TEdit window.

If the destination is a window Interpinkie does some additional processing before and after sending the output. For example, before doing output the program updates the window title to reflect the Finger query, and sets the TEdit buffer to read-only once the output finishes.

These days there are not many Finger servers and I was lucky to stumble upon happynetbox.com. It is managed by Happy Net Box, a nice public Finger server anyone can sign up to for for free and publish a status file. Happy Nex Box was essential for developing and testing Interpinkie, as well as fun ā€” and addictive ā€” as you can see by running the query random@happynetbox.com to look up a random user.

#Interpinkie #Interlisp #Lisp

Discuss... Email | Reply @amoroso@fosstodon.org

For Chrismtas 2024 I bought myself a lovely little Cardputer uLisp Machine, an M5Stack Cardputer that can run uLisp.

The M5Stack Cardputer is a card-sized, microcontroller-based portable system for home automation, hobby, and industrial applications. Although not designed for Lisp the Cardputer can run uLisp, an implementation optimized for microcontrollers. This is my unit:

Cardputer uLisp Machine card-sized microcontroller-based computer.

The uLisp system provides a capable Lisp implementation, a rich anvironment, debugging and editing tools, and lots of libraries and examples. It's well maintained and has an active user community.

Motivation

Like many Lispers I always wanted to play with Lisp on the bare metal and the Cardputer uLisp Machine is a simple and inexpensive solution.

uLisp runs on a wide variety of microcontrollers and boards. I picked the ESP32-S3 based Cardputer because it's compact, can run off rechargeable batteries or USB without an external power source, and comes with a graphics display. And at $29.90 it was a no brainer.

Hardware

The Cardputer is a self-contained device with a keyboard, a 240x135 color TFT display, a USB-C port, and a microSD card slot.

Despite the minuscle keyboard, if I hold the Cardputer with both hands I can accurately press any key with my thumbs. However, the keys are very sensitive to pressure and if I hit one with slightly more force than needed I end up repeatedly typing the same character. Entering code and expressions with the built-in keyboard isn't practical for anything longer than a line or two.

The stamp sized display is tiny too but my new eyes help me read the microscopic text on it.

Software

The first thing I did was to install the uLisp firmware to replace the stock system software. The installation procedure is straightforward, took a few minutes, and required only the Arduino IDE which I run on Linux.

There are two main ways of interacting with uLisp. The first is to access the REPL using the Cardputer keyboard and display, the other is to connect from a desktop computer over a USB serial line via the Arduino Serial Monitor or a terminal emulator such as GNU Screen or Minicom. There is also experimental user contributed code for accessing uLisp from Emacs via an inferior Lisp mode or Swank.

A limitation of interacting over USB is that sending code blocks longer than 256 characters overflows the serial buffer, which results in a string of error messages due to the dropped characters.

A workaround is to preceed the code with a comment line starting with a semicolon ; which temporarily turns off echo mode on the device and prevents it from being overwhelmed. Lisp mode on Emacs has no support for the workaround though. So the extra comment line needs to be manually copied from the source buffer and pasted into the inferior REPL along with the code, instead of executing commands such as eval-defun or C-M-x. This introduces friction in the rapid cycles of REPL and editor interactions Lispers are used to.

A showstopper

The limitations of interacting with the Cardputer over serial are just inconveniences that may be fixed by improving existing tools. But a showstopper forces me to set the Cardputer aside until a major Arduino core issue is resolved.

The Cardputer's ESP32-S3 native USB manages the serial port via software and currently has a nasty bug: if the receive buffer fills up too fast the ESP32-S3 will crash and disconnect. I can't do anything practical with the Cardputer without reliably sending medium or large Lisp code blocks to uLisp for evaluation.

The uLisp website does warn about the issue but I incorrectly assumed it affected the Cardputer only when connected to Macs, whereas I use Linux.

Only the Arduino team can fix this issue not caused by uLisp. But since it has been known for a couple of years Iā€™m not holding my breath.

#Lisp

Discuss... Email | Reply @amoroso@fosstodon.org

I always preferred the light theme and never figured what's the fuss with the dark theme. Until cataract came.

In May of 2024 my ophthalmologist confirmed what I surmised: both of my eyes were affected by cataract. It came earlier than my age would suggest but that's apparently not unusual.

I realized something was off when I noticed everything looked blurry, faded, and washed out as if seen through glass coated with yellowish dirt. The view was often immersed in more glare than the lighting conditions would imply. My old prescription glasses not only didn't help, they made things worse. What surprised and initially worried me were the occasional changes in the intensity of the blurriness and fading, which took place over the course of days whereas eyesight usually changes over years.

My ophthalmologist scheduled cataract operations for mid November and mid December of 2024. The only thing I could do was wait. But I faced the challenge of reading computer and mobile screens through such an unpleasant filter.

My daily driver is a Linux PC on the desktop and a Pixel 7 Pro phone on mobile. On the computer screen most text of websites or Linux programs was hardly legible with the light theme. The beautiful designs of some light theme sites featuring subtle shades, low contrast, or small fonts made reading a nightmare. Coming close to the screen and bending in search of an angle that could help make out something left my back aching in the evening.

Surprisingly to me, the dark theme improved legibility. I set the dark theme everywhere I could: in Linux programs; in Forefox; and on the websites that offered a choice.

The worst experience came from Gmail on the web. Its dark theme is a cruel joke as it doesn't affect the body of email messages, which is what I spend the most time reading. Invert Colors, an open source Firefox add-on that inverts the colors of any web page at the press of a keychord, tamed Gmail and made message bodies bearable. Thanks Max!

The legibility of text was initially less of an issue with the light theme on mobile. I still had to increase the font size one notch larger than the default in the Android system settings. And I eventually had to turn on dark mode too.

In the fall of 2024 the cataract surgeries finally came and I could see the world with new eyes, literally.

The detail, sharpness, and depth my eyes now deliver make the view almost hyperreal. For example, since the left eye gained a visual acuity of 20/20 I can read tiny text, whereas the same eye always struggled to read newspaper and magazine headlines, barely. Even my ophthalmologist couldn't believe it.

It's been a few days since the second cataract operation and I finally stowed my glasses in a drawer for good, restored the light theme on all devices, uninstalled Invert Colors, and set the font size back to the default on the phone. But I see the light about the dark theme.

Christmas is days away and this is the best present I could ever hope for. Cataract surgery is an underrated miracle of medicine.

#personal

Discuss... Email | Reply @amoroso@fosstodon.org

Ten years ago today my astronaut friend Samantha Cristoforetti began her first space flight. On November 23, 2014 she was launched aboard the Soyuz TMA-15M spacecraft for a mission to the International Space Station.

I had the privilege of helping Samantha with a public outreach project to share this adventure.

Shortly after the announcement of her mission in early July of 2013, Samantha decided on a way to tell the experience as it happened and engage the public. She wrote the Logbook, a diary to document the last 500 days of the mission training and her stay on the ISS. From July 19, 2013 to September 10, 2015 Samantha posted to Google+ more or less daily entries from the ground and in space. These long form entries in English reported on her training and life aborad the ISS and often attached some photos.

Since the beginning I provided the official Italian translation of the Logbook published on AstronautiNEWS, the news site of the space outreach organization I'm a member of.

The Italian news outlets and media that covered the mission soon began quoting or referencing my translations to inform the public of Samantha's home country. ESA later republished the translations to Avamposto42, the official website of the mission. Other space enthusiasts eventually translated the English entries into French, Spanish, German, and Russian.

Contributing to the project was an adventure for me too.

My daily routine involved waiting for Samantha to post to Google+, translating, and publishing a new entry to AstronautiNEWS as soon as possible for dissemination to the press and public. Translating rocket science terms was mostly easy, the hard part was conveying words and expressions from domains unfamiliar to me such as physical exercise and equipment.

The Logbook is a unique resource. It's the most extensive series of candid written thoughts on preparing for and carrying out a space flight, published as the events unfolded. As far as I know the L-0 entry, posted less than a day from launch, is the only written account of the thoughts and emotions of an astronaut published just hours from launch.

Google+ was shut down in 2019 but the Logbook is not lost.

Carlo Gandolfi archived the text and photos of all the original Google+ posts and published the Logbook as a free ebook. Another free ebook collects my Italian translation of the Logbook.

#space

Discuss... Email | Reply @amoroso@fosstodon.org

The end of the work on WebCard marked the completion of my RetroChallenge 2024 project, in time as hoped.

I accomplished the initial goal of extending NoteCards to visit websites. This is my Linux desktop after traversing a NoteCards link to a Web card which opened the associated URL in Firefox:

A website opened in Firefox by traversing a Web card link with WebCard.

As the RetroChallenge encourages to do I learned a lot, shared my experience, and had lots of fun with retro stuff.

WebCard is not my first NoteCards project but helped me explore other features of the system, particularly the definition of new types of cards. Most of the work on WebCard involved researching the NoteCards API and writing code.

Once I understood the relevant API calls, implementing the planned features took relatively little code. NoteCards comes with an extensive, well designed and documented API that enables to add a lot of functionality by mostly plugging into the public hooks.

The NoteCards manual has nearly all the information I needed. However, to understand some features or subtle points of the API I had to study some of the NoteCards code, particularly the source that defines the File card type because of the similarities with what WebCard does. Some throwaway code and experimentation with the interactive Lisp environment plugged the last information gaps.

The project generated a flow of material for my blog and Mastodon profile. I posted frequent short updates on Mastodon and longer reports on the blog. This drained time and focus too.

The main takeaway of the project is that Medley Interlisp is a rich toolbox with which new programs can be developed by combining other programs as building blocks. NoteCards itself builds upon the TEdit text editor, the Sketch line drawaing program, the File Browser, and other tools.

As my first RetroChallenge I was lucky to complete the project. I set a goal reasonably achievable in one month but the actual work faced some unexpected detours that didn't impact the deadline.

What else to say? Mission accomplished.

#WebCard #Interlisp #Lisp

Discuss... Email | Reply @amoroso@fosstodon.org

To complete WebCard for my RetroChallenge 2024 project I created a demo notefile, a file that stores the data of a NoteCards hypertext.

The notefile WCDEMO.NOTEFILE contains exmples of Web cards filed into various types of containers and cards such as fileboxes and Text cards. It provides some ready made Web cards for exploring WebCard.

This screenshot shows the main cards of the demo notefile:

The cards of a WebCard notefile open in NoteCards.

The link icons with the globe bitmap at the left of the outlined text are links to Web cards. Clicking such a link in NoteCards opens the associated URL in a web browser, which is the main feature of WebCard.

#WebCard #Interlisp #Lisp

Discuss... Email | Reply @amoroso@fosstodon.org

With the last feature of WebCard behind me I proceeded with the next task to wrap up my RetroChallenge 2024 project: documenting the system.

Since WebCard enhances NoteCards with only a few simple but significant features a full manual would be overkill. So I added to the README file of the project repo some new sections on the requirements and dependencies, the installation, and the usage of WebCard.

The documentation assumes familiarity with NoteCards and Medley Interlisp, large systems in themselves, and describes only what WebCard adds to NoteCards. It explains how to create and manage Web cards and traverse links to them.

In addition the README file now has a screenshot that shows a website opened by WebCard in NoteCards.

#WebCard #Interlisp #Lisp

Discuss... Email | Reply @amoroso@fosstodon.org

NoteCards link icons leading to cards of a certain type can and typically do have a custom bitmap associated with the type.

WebCard cards of type Web initially inherited the bitmap of the parent type Text, a stylized NoteCards blank card frame. To visually differentiate links to Web cards I added a new bitmap, here open in the bitmap editor of Medley Interlisp:

The bitmap of WebCard cards of type Web in the bitmap editor of Medley Interlisp.

The bitmap at its actual size of 21x18 pixels is near the top left corner of the window. It represents a blank card frame with at the center a globe crossed by meridians and parallels, a common symbol of web links.

Aside from some misunderstandings on defining Interlisp bitmaps, adding a bitmap to WebCard was easy.

Once designed and defined the bitmap itself I passed it as the value of the LinkIconAttachedBitMap property along wiht the other arguments of NCP.CreateCardType, the NoteCards API function that defines new card types.

The hard part was coming up with a suitable bitmap, which kept me busy on and off for a couple of weeks.

As an artistically clueless geek my original plan was to pick a public domain icon, scale it to the required size, and import it in Medley Interlisp. Although this Lisp environment predates most modern image file formats, Andrew Sengul wrote a Lisp tool that can convert from PBM to the native Interlisp bitmap format.

I soon found a nice globe icon. Then I was unwillingly thrown into a rabbit hole of NetPBM, Gimp, and ImageMagick tools and options, struggling to produce the right format Andrew's tool could process.

I learned the hard way that if an image contains only black and white pixels, and no other colors, it's unnecessarily difficult to obtain a black and white, 1-bit depth file. Most tools save to 8-bit grayscale despite claiming to do 1-bit black and white.

When I finally imported the rescaled, converted PNG into Medley I realized it was an unlegible tiny blob.

Link icon bitmaps have a size of 21x18 pixels and, aside from the stylized card that makes up the frame of the bitmap, the usable area is only a dozen pixels across. In desperation I fired up the Medley Interlisp bitmap editor and designed the bitmap myself from scratch. It took just a few minutes and was unexpectedly easy.

I'm pleased with the result, but stunned at how long such a seemingly simple task dragged me.

#WebCard #Interlisp #Lisp

Discuss... Email | Reply @amoroso@fosstodon.org

Over the past days I ran WebCard a bit, reviewed the code, and checked my notes and I'm satisfied with what the system does. Since WebCard is nearly feature complete it's a good time to chart the next steps for wrapping up my RetroChallenge 2024 project.

Aside from some tweaks or cleanups, the only other code to write will set a bitmap for the link icon of Web cards. This is useful to further visually distinguish them from other types of cards such as Text.

WebCard also needs some documentation. I'll expand the README file to explain how to install and use WebCard. A demo notefile with examples of Web cards in a NoteCards hypertext is also useful to show what WebCard does.

#WebCard #Interlisp #Lisp

Discuss... Email | Reply @amoroso@fosstodon.org

WebCard has very limited control over the web browser of the host operating system.

It can only command the browser to visit a URL when the user traverses a Web link or executes the Visit URL menu command. But with no precautions the browser would open a new tab for every visit of the same URL.

To reduce clutter I tweaked WebCard to keep track of visited URLs. The URLVisitedP boolean property of a Web card window indicates whether the associated URL was already visited. The function WCD.TraverseWebLink checks URLVisitedP and visits the URL only if the property is NIL, then sets it to T if it does visit the URL. URLVisitedP is a property of the window rather than the card because, as part of the dynamic session state, NoteCards shouldn't save it in notefiles.

The overall behavior of Web cards and URL visits appears as follows.

Traversing the link of a closed Web card unconditionally visits the URL. Once the card is open, traversing the link again flashes the card to call attention to it but doesn't visit the URL. The Visit URL menu command can force the visit though. Closing a card sets URLVisitedP to NIL, so the next time link traversal reopens the card it triggers a visit.

This should take care of the most common cases of unintentional link traversal, reduce tab clutter, and prepare WebCard for actual usage.

#WebCard #Interlisp #Lisp

Discuss... Email | Reply @amoroso@fosstodon.org

Enter your email to subscribe to updates.