2025-09-04 15:06:29
Back in 2002/2003, Ian Piumarta wrote an “essentially complete” VT102 terminal emulator for Squeak Smalltalk.1
Here are his unmodified original changesets, encoded using the MacRoman character set; these do not load directly into current Squeak images as-is:
The problem is not just that they’re encoded using MacRoman—Squeak still has support for that—but that there are punning uses of strings to represent bytewise mappings, rather than characterwise mappings.
The first step to getting them loadable is to convert them to UTF-8. I did this using
emacs2 because both Squeak itself and iconv(1)
choked on some of the
tricky encodings going on in the files. A subsequent step will be to repair the tricky parts,
re-writing them to hopefully use in-image Unicode support.
The Squeak Smalltalk language has also changed a little since 2003: assignment is no longer ←
(written using an underscore, _
), but is instead the digraph :=
; it is no longer permitted
to store into method or block arguments; and so on. Fixing these issues yields the following:
Now, filing in telnet.301.cs
yields an error in TeletypeMorph class »
initializeCharacterClasses. This is the main (?) place involving 8-bit character set
assumptions that will have to be revisited. Changing that method temporarily to delete its
actual body, replacing it with the commented-out table taken directly from xterm, allows the
fileIn to complete.
Filing in PseudoTTY-3.2-4.st
appears to succeed without problems.
Next steps will be seeing if all this code actually runs!
2025-06-25 17:07:48
Smalltalk programs strictly alternate between data and behaviour. Messages (the only kind of data in Smalltalk) are implicit, constructed fresh at each point in the program method call syntax is used, and are shallow, meaning that the slots in each message object always contain references to objects, never other messages.1
This is in contrast to most other languages with true data, where (for example) lists may contain other data, and are not constrained to containing only object references / function values.
So, what would a Smalltalk be like without this strict alternation, where messages could appear as values? Suddenly the universe of Smalltalk values grows larger: previously, everything was an object, but now some things are data!
Of course, objects acting as reified messages may appear! ↩
2025-06-25 17:04:57
Usually, method lookup results in a single body to execute. This is analogous to the way pattern matching usually tries patterns in order, selecting just one continuation to execute.
What if, instead, we allowed all matching patterns from a bunch of alternatives to execute? (Or, in object-oriented terms: executed all methods potentially matching a given method call.)
Pattern alternatives do not become a kind of superposition, because there’s no notion of mutual exclusion; instead, they become a way of creating multiple concurrent branches of execution, somehow. (Not to say there’s any particular kind of interleaving or parallel execution of these branches that makes any sense! One could well limit consideration to sequential execution of each matching method, to start with.)
Can we recover true alternatives from this kind of every-match construct (it needs a name!)? One approach is to follow the idea from Alex’s, Mahdi’s and my PEG paper,1 treating alternation (/
) as a kind of parallel match construct and using negative lookahead to cause a later branch to fail if some earlier branch succeeds.
T. Garnock-Jones, M. Eslamimehr, and A. Warth, “Recognising and Generating Terms using Derivatives of Parsing Expression Grammars,” Jan. 2018. https://arxiv.org/abs/1801.10490 ↩
2025-06-17 15:26:53
A fantasy abstract is a short piece of writing in the style of the abstract of an academic paper presenting the outline of a piece of research that has not (yet) been done. It acts as inspiration, as a means of communicating an idea, and as a place to nucleate further thinking on the topic, perhaps eventually kicking off the desired research.
It’s something I started doing during my PhD studies to help record and structure the relationships among ideas. I record a little bit of metadata about each abstract: not much more than the names of one or more broad research “themes” or threads that the idea might fit into.
For example, here’s one from January 2011, shortly after I started experimenting with the form. Fourteen years later it remains fantastic and unexplored (by me at least!):
Contracts for Protocols
Created: 2011-01-10
Thread
Network Languages
Abstract
Existing messaging middleware systems provide very low-level facilities to application developers, ranging from simple point-to-point datagram transfer up through simple stereotypical interaction patterns such as (optionally transacted) request-reply or publish-subscribe. These low-level facilities are then composed by the application developer into higher-level interactions, but without the benefit of any formal way of describing the higher-level interactions. This paper introduces contracts for messaging protocols implemented using messaging middleware, describes a prototype implementation, and discusses lessons learned.
Some things to note:
Citations are useful if you have them, but the main point is to capture the idea, not do an exhaustive background literature survey. In the example above there’s the ludicrous omission of any mention of session types, for example; what I had in mind was something akin to what, these days, are called “dynamic monitors” in the session types literature. Perhaps if I’d expanded this abstract into an actual paper at the time it’d have been a timely contribution :-) It’s a bit stale now…
It can be an absolute fantasy. Feel free to refer to nonexistent (but plausible?) research results. If you ever pick up the idea or gift it to someone else, it’ll be made rigorous and realistic then. Use the fantasy abstract to get the feeling of your idea.
2025-05-01 03:27:54
I always forget how to do this, so I’m writing it here in part as a reminder for myself next time I need to do this.
These instructions are for using daemontools
and daemontools-run
packages on Debian.
/etc/service/tonyg-services
Create a file /etc/service/tonyg-services/run
containing
#!/bin/sh
exec setuidgid tonyg svscan /home/tonyg/services
Replace setuidgid
with sudo -u
if you want to preserve supplemental groups.
chmod a+x /etc/service/tonyg-services/run
/home/tonyg/services
2025-03-06 14:42:25
Small experiments in the use of libliftoff to try out the modern Linux graphics stack drove home quite how slow DRM “dumb buffers” can be, but also that it’s reading that’s slow, not writing.
Reading from a “dumb buffer” on my AMD GPU is orders of magnitude slower than reading from RAM. It can take seconds to read out a full 4k frame. It’s roughly a thousand times slower than reading RAM.12
Writing, by contrast, is quick.
While it is folklore that “dumb buffers are slow”, I found it challenging to find any
authoritative source on the matter. However, I did find something. In
/usr/include/drm/drm.h
, we see the following comment, which sort of hints at the wider
situation:
/**
* DRM_CAP_DUMB_PREFER_SHADOW
*
* If set to 1, the driver prefers userspace to render to a shadow buffer
* instead of directly rendering to a dumb buffer. For best speed, userspace
* should do streaming ordered memory copies into the dumb buffer and never
* read from it.
*
* Note that this preference only applies to dumb buffers, it's irrelevant for
* other types of buffers.
*/
#define DRM_CAP_DUMB_PREFER_SHADOW 0x4
Indeed, “for best speed […] never read from it.”
Update: Subsequent experimentation using gbm
to allocate buffer objects shows that it
doesn’t help if you need to read or write pixel data to them (as opposed to, presumably, using
the GPU to render into them). Setting the GBM_BO_USE_WRITE
flag when allocating a buffer
object, to allow subsequent writing of pixel data, causes the dri
backend of
gbm
to simply allocate a “dumb buffer”!
Quick-and-dirty C experimentation shows speeds of ~2ms to read a full 3840×2160×32bit frame out of normal RAM. That’s about 16GB/s. Eyeballing the slow “dumb buffer” read times suggests then perhaps about 16MB/s for that! ↩
As a corollary to this realisation, I learned that attempting to use surfaces backed solely by “dumb buffers” to do fallback software composition is a losing proposition. Hence the whole idea of “shadow” buffers, presumably! ↩