One of Those Who Can Type

<paluche> wasamasa: how many times have you done MAL?
<wasamasa> paluche: this is the fourth time
<paluche> So...
<wasamasa> so, three times so far
<paluche> you're a MAL-coholic?

I don’t even need to answer this one, do I? PR #4 is for Smalltalk, one of those languages I always wanted to try out because of their influence. What convinced me to finally do it was that I had to learn a bit of Objective-C for work and this made the second obviously Smalltalk-inspired language I’ve encountered, other than Ruby. Overall, it was a pretty nice experience, despite not using an image-based and IDE-centric workflow with GNU Smalltalk. As usual, here’s my list of random notes:

  • Smalltalk has relatively minimalistic syntax
  • My biggest stumbling points with it were sequencing syntax (semicolon and period) and precedence rules
  • It’s kind of telling that the standard all implementations go by omitted how the syntax for defining a method looks like, this makes it more difficult than it should to share self-contained code examples on the web
  • Documentation or rather, finding the right method is a big problem, the canonical solution would be to use the browser, however the search function there errors out
  • I’ve therefore resorted to searching the locally installed sources and internets for things not specific to the implementation
  • Apply (aka valueWithArguments) is supported, variadic args aren’t or rather, there is no syntax for them
  • There is no cond/case construct, instead you’re supposed to either return from every conditional, do a dictionary lookup, use polymorphism or nest boolean tests
  • There is no continue/break construct, but it can be emulated easily with the non-standard valueWithExit method
  • It’s awesome just how much of the language is implemented in itself
  • It’s interesting that there are only five keywords and no special forms, only methods that are implemented in terms of VM primitives
  • The class hierarchy makes more sense than in Java, generally this is the cleanest implementation of OO I came across (though Self dares challenging this by replacing metaclasses with a prototyping mechanism as seen in JS)
  • The debugging experience is less than stellar, I have to try out Pharo for the real deal
  • Blocks are considerably cleaner than in Ruby where you have three options for subtly different purposes with subtly different semantics
  • Block syntax however is imperfect, you cannot return from them (attempting to do so gives you a silly error message), instead the last expression is used as return value
  • This gets stranger if you consider that (non-local) returns are exclusive to methods; in other words blocks aren’t intended to be as powerful as method bodies
  • There is no stack overflow in step 5, however if you push far enough, you can reach an unrecoverable OOM condition
  • The class library is far less forgiving than in Ruby, for instance slicing/access errors out instead of returning an empty array or nil
  • String syntax is a bit weird with regards to quoting as strings are delimited with , no backslash escapes exist and escaping of is done by doubling it
  • If there’s a language that invented monkey-patching, this is the one; I’ve successfully made use of this capability to fix a runtime bug that only happens in the CI environment



My first programming experience was with VB6. I considered trying TurboPascal, but couldn’t figure out how to use it from cmd.exe on my measly Windows 98 SE machine. Many things have been said about the quality of the BASIC family of languages and the subpar programs created with VB6, but it’s easy to forget how convenient they make it for the beginner to create something workable without losing their head in irrelevant details in the windowing toolkit. The workflow looks mostly like this: Create and arrange widgets, edit their properties, double-click each widget with custom behavior and write code for the respective event handler. Needless to say that the few original programs I did write weren’t of the useful kind. Only much later after a brief encounter with C++ for game programming (which made me quit programming for a few years) I discovered scripting languages, learned to love Python and eventually spun off into the polyglossia required by modern software development jobs. reminded me of the good ol’ times, leaving me wondering just how hard it would be to recreate the irretrievably lost programs from back then. My excursions into GUI programming have taught me that GNOME offers two separate projects that connect their introspection for GTK and friends with a JavaScript interpreter, seed and gjs. Unfortunately seed is no longer in the Arch repositories, so I picked gjs, just to find out that there is no official documentation, aside from an auto-generated set of API docs provided by a user.

The good news is that with the help of #gtk+ on Freenode, I managed porting all applications in less than a day. The bad news is that I doubt I’ll use gjs again as its situation reminds me of LLVM: Lots of potential, intriguing claims (in their case, introspection giving you language bindings for free) but with outdated documentation if any (you’re better off with reading the source and experimenting a lot) and tooling being half-assed. Rewriting teapub might be possible, but for what gain? It’s no surprise Qt is eating their lunch despite being more complex and requiring you to use C++. Had I been given this environment ten years ago, I’d probably have gone for browsers instead. So, in a way it’s not surprising that environment appears to breed the new generation of programmers.

A Visit to a Sad Planet


One of the things that always irked me about my EPUB reader was that part of it is written in JavaScript, simply because that’s the only way one can script a browser view these days. I’ve always wanted to give the SPOCK compiler a try to see how well it does compared to ClojureScript, so this project gave me the perfect chance to cure me of delusions. After an evening, I got it running, it took me a few more evenings to iron out bugs introduced by the conversion and add a new bugfix. Here’s a list of observations made in that time:

  • Both versions are about the same size, with the Scheme version being a bit shorter (which is mostly closing parentheses not going on a separate line). I’d expect a greater difference in favor of the Scheme version if I had any noteworthy business logic embedded into this, but alas.
  • Debugging got significantly harder as there is no REPL, no source maps integration and no debugger for the Scheme code. I’ve had to do with classic printf-Debugging, except that it looked more like (%inline "console.log" (jstring (string-append "Foo " (number->string 42)))).
  • While there is documentation (which includes a few working examples), it isn’t clear how to use the compiler to its fullest abilities. I’ve resorted to compiling all kinds of code and staring at the compiler output to see what works and what doesn’t. This experimentation revealed that you’ll want to use %inline for most interop, with a bit of dot syntax for property access. ClojureScript beats SPOCK easily in this aspect, including its #js reader macro and conversion macros from/to JS data structures.
  • Error reporting is extremely basic, with some errors being silent and merely preventing code from executing any further.
  • The supported language is restricted to R5RS with a few useful macros and JS-specific helpers. In other words, while you might manage compiling other Scheme libraries to JavaScript, you’re better off writing your own helpers as needed.
  • Tooling is simple and quick. Recompiling code is instantaneous, it’s easy to see what part of your own code maps to the generated parts. This is the only benefit I see in SPOCK over ClojureScript.

To summarize, if you want maximum comfort and features, go for ClojureScript. The price you pay for it is significant friction while developing, but other than that it’s pretty advanced. Personally I think I’ll stay with vanilla JavaScript for my other toy projects to keep things as simple and painless as possible.

I predict that Guile Emacs won’t lead to a significant increase in packages written in Scheme for similar reasons. Much like in browsers, the majority of Emacs Lisp usage doesn’t have complex business logic and follows the principle of practicality over purity. Perhaps it’s different for big projects like Magit or Evil, but even these cases are doubtful to me, simply because they have higher priorities than speculative rewrites that might as well kill the project. I could keep rambling about my reasons for this assessment, but that is better left for a separate blog post…

Making Emacs More Presentable


I do occasionally hold talks, mostly about Lisp-related topics. My medium of choice is PDF, as generated by Org’s export with the Beamer backend. When it’s demonstration time, Emacs isn’t nearly as simple to adjust for comfortable viewing as a browser or terminal. My first instinct was to look for a function that allows increasing the font size, similar to C-+. It turns out that C-x C-+ is a thing, however it’s not ideal as it only increases the font size of the current buffer. A quick look at the sources reveals why:

(define-minor-mode text-scale-mode
  :lighter (" " text-scale-mode-lighter)
  (when text-scale-mode-remapping
    (face-remap-remove-relative text-scale-mode-remapping))
  (setq text-scale-mode-lighter
        (format (if (>= text-scale-mode-amount 0) "+%d" "%d")
  (setq text-scale-mode-remapping
        (and text-scale-mode
             (face-remap-add-relative 'default
                                          (expt text-scale-mode-step
  (force-window-update (current-buffer)))

text-scale-mode is implemented in terms of face-remap-add-relative, a function describing itself as “Add a face remapping entry of FACE to SPECS in the current buffer.”. Funnily enough, both live in face-remap.el, probably because scaling text is merely a demonstration of the buffer-local face remapping capabilities of Emacs. While it’s a cute demo, it’s clearly not what I’d want from a C-+ replacement, so I wrote an alternative solution operating on the frame:

(defun my-alter-frame-font-size (fn)
  (let* ((current-font-name (frame-parameter nil 'font))
         (decomposed-font-name (x-decompose-font-name current-font-name))
         (font-size (string-to-int (aref decomposed-font-name 5))))
    (aset decomposed-font-name 5 (int-to-string (funcall fn font-size)))
    (set-frame-font (x-compose-font-name decomposed-font-name))))

(defun my-inc-frame-font-size ()
  (my-alter-frame-font-size '1+))

(defun my-dec-frame-font-size ()
  (my-alter-frame-font-size '1-))

(global-set-key (kbd "C-+") 'my-inc-frame-font-size)
(global-set-key (kbd "C-=") 'my-inc-frame-font-size)
(global-set-key (kbd "C--") 'my-dec-frame-font-size)

This is a bit less hacky, but still disgusting. The code fetches the font name (which curiously comes in the XLFD notation) from the frame, converts it into an array, extracts the font size, manipulates it, puts it back into the array, converts it to a font name and sets the frame’s font to it. You can find this snippet and many more in my, so if you haven’t already, give it a look to find more goodies!

Trapping Attackers With Nyan Cat


Update: Fixed some things that kept this from working.

In case you haven’t done it yet, I strongly recommend you to give telnet a try. If you don’t have a telnet client ready, head over to instead and enjoy the pretty pictures.

I’ve wondered for quite some time whether it would be possible to run the same thing on a SSH server. It turns out that it’s not too hard to do as not only Kevin Lange’s creation can be run in a TTY, but OpenSSH allows you to do something else than giving you a shell after a successful authentication attempt.

First of all you’ll need to install and test the nyancat program:

% pacman -S nyancat
$ nyancat

To restrict the impact of the public-facing service, I decided to create a new user for it and run a separate SSH daemon with its own config and service file:

% useradd -m -s /bin/sh anonymous
% passwd anonymous
% cp /usr/lib/systemd/system/sshd.service /etc/systemd/system/nyanpot.service
% cp /etc/ssh/sshd_config /etc/ssh/nyanpot_sshd_config

Relevant changed bits in the service file:

Description=OpenSSH Honeypot
ExecStart=/usr/bin/sshd -D -f /etc/ssh/nyanpot_sshd_config

The SSH config is a bit special as it locks out everyone who isn’t the anonymous user:

Port 22
PermitRootLogin no
PermitTTY no
PasswordAuthentication no
X11Forwarding no
AllowTcpForwarding no
Match User anonymous
    PasswordAuthentication yes
    PermitTTY yes
    ForceCommand nyancat

You can test the service with systemctl start nyanpot.service and logging in (ideally from a different system) as the anonymous user. If everything works fine, enable the service permanently with systemctl enable nyanpot.service. My honeypot is available via ssh (PW: anonymous). Enjoy!