Now/log (2021-02)

Newest entries.

Previous month.


Ate the last piece of banana bread. Although it seemed like too much at first, I am glad I made two loafs. That’s three people SLAUGTHERING bread in 4 days.

Today’s reading is Partial Evaluation and Automatic Program Generation (N. Jones, G. K. Gomard, P. Sestoft).

the trick

I started sitting at a desk again, with a big external monitor in portrait mode. Don’t know whether I’m not used to this, or something being wrong, but my shoulder and neck seem to be constantly in stress with this setup.


Not much, just boring full time job, mostly.

Lost the charger for electric razor, repurposed/soldered one myself and got it charged. Note: it’s not my head that got a full shave. Don’t think I’m going to do that on myself at any point whatsoever, I really like long hair (the longer the better) and bangs so far.


Rewrote tokenizer in plain C by hand. Was very easy, took way less time than with Ragel, and it works with Unicode properly with char* :)


No computers. Only plants. Lemon trees. Clementine trees. Avocado.

Btw the banana bread is amazing.


Tada (CW: instagram, a photo of banana bread). Cooling down for the night.


Making banana bread with walnuts, almonds and rum! Gonna taste it tomorrow.

Apart from having trouble with unicode in identifiers, tokenizer seems to work great now. I hope to fix issues with unicode later. It’s time to start on the parser!

; echo 'y = zzzz+₂101010/x*(i+₁₆ff), zzzz=3, x=9, i=13;'|./6.out -dt
⟨i value=y⟩ ⟨o =⟩ ⟨i value=zzzz⟩ ⟨o +⟩
⟨n base=2 width=8 signif=6 value=101010 unsigned=42 binary=2A⟩
⟨o /⟩ ⟨i value=x⟩ ⟨o *⟩ ⟨o (⟩ ⟨i value=i⟩ ⟨o +⟩
⟨n base=16 width=8 signif=8 value=ff unsigned=255 binary=FF⟩
⟨o )⟩ ⟨o ,⟩ ⟨i value=zzzz⟩ ⟨o =⟩
⟨n base=10 width=8 signif=2 value=3 unsigned=3 binary=03⟩ ⟨o ,⟩
⟨i value=x⟩ ⟨o =⟩
⟨n base=10 width=8 signif=4 value=9 unsigned=9 binary=09⟩ ⟨o ,⟩
⟨i value=i⟩ ⟨o =⟩
⟨n base=10 width=8 signif=4 value=13 unsigned=13 binary=0D⟩ ⟨o ;⟩


Adding more stuff to my programming language x₀. Making comments valid tokens so they can be used for documentation later. Added strings, escape codes, lots of operators. Note this is just the tokenizer for now, I’m still largely figuring out how I want the language to look like.

Anyway, a sneak peek at the “operator” section:

   '_' # any
 | '@' # address of
 | '=' # assign
 | '$' # expand
 | '+' | '-' | '/' | '*' | '%' # arithmetic stuff
 | '!' # force evaluation
 | '?' # if true then
 | ':' # else
 | '#'             # length
 | '&' | '|' | '^' # bitwise
 | '.'       # index
 | ',' | ';' # separation
 | '(' | ')'
 | '[' | ']'
 | '{' | '}'
 | 0xe2 0x9f 0xa8 %{ f->op.r = '('; } # ⟨, for easier grouping
 | 0xe2 0x9f 0xa9 %{ f->op.r = ')'; } # ⟩, for easier grouping
 | "and"  %{ f->op.r = L'∧'; }
 | "or"   %{ f->op.r = L'∨'; }
 | "nand" %{ f->op.r = L'↑'; }
 | "nor"  %{ f->op.r = L'↓'; }
 | "not"  %{ f->op.r = L'¬'; }
 | 0xc2 0xab %{ f->op.r = L'«'; } # shift left
 | 0xc2 0xbb %{ f->op.r = L'»'; } # shift right
 | 0xe2 0x80 0xa5 %{ f->op.r = L'‥'; } # 1‥3
 | 0xe2 0x80 0xa6 %{ f->op.r = L'…'; } # {1,3,…} or [1,…] or `blah`…
 | 0xe2 0x86 0x90 %{ f->op.r = L'←'; }
 | 0xe2 0x86 0x92 %{ f->op.r = L'→'; }
 | 0xe2 0x87 0x92 %{ f->op.r = L'⇒'; } # implies
 | 0xe2 0x88 0x80 %{ f->op.r = L'∀'; } # for all
 | 0xe2 0x88 0x83 %{ f->op.r = L'∃'; } # there exists
 | 0xe2 0x88 0x88 %{ f->op.r = L'∈'; } # element of
 | 0xe2 0x88 0x89 %{ f->op.r = L'∉'; } # not element of
 | 0xe2 0x88 0x8b %{ f->op.r = L'∋'; } # contains as member
 | 0xe2 0x88 0x8c %{ f->op.r = L'∌'; } # does not contain as member
 | 0xe2 0x88 0x98 %{ f->op.r = L'∘'; } # composition
 | 0xe2 0x88 0xa9 %{ f->op.r = L'∩'; } # intersection
 | 0xe2 0x88 0xaa %{ f->op.r = L'∪'; } # union
 | 0xe2 0x89 0xa0 %{ f->op.r = L'≠'; } # not equal
 | 0xe2 0x89 0xa1 %{ f->op.r = L'≡'; } # equal
 | 0xe2 0x89 0xa4 %{ f->op.r = L'≤'; } # less or equal
 | 0xe2 0x89 0xa5 %{ f->op.r = L'≥'; } # greater or equal
 | 0xe2 0x8a 0x82 %{ f->op.r = L'⊂'; } # subset of
 | 0xe2 0x8a 0x83 %{ f->op.r = L'⊃'; } # superset of
 | 0xe2 0x8a 0x84 %{ f->op.r = L'⊄'; } # not subset of
 | 0xe2 0x8a 0x85 %{ f->op.r = L'⊅'; } # not superset of
 | 0xe2 0x8a 0x86 %{ f->op.r = L'⊆'; } # subset of or equal to
 | 0xe2 0x8a 0x87 %{ f->op.r = L'⊇'; } # superset of or equal to


Taking care of my plants. There is more and more of them with each week.


Plan 9, 1st edition ISO

Plan 9, 2nd edition ISO

Plan 9, 3rd edition ISO

Plan 9, 4th edition ISO

Plan 9, 4th edition (Final Release) ISO

Today’s listen - Oroboro.

I can’t fall asleep so here goes a brain dump.

With a fast enough compiler of a hypothetical language that generates bytecode/AST that can be JITed with partial evaluation, and an OS based on this language, I wonder if apps could be optimized by knowing their arguments, and “piped” together as well in code with JIT, so that:

{cat file | tr -d '[^0-9\n]' | tr '\n' +; echo 0} | pc -n

Becomes a single “program”, with one address space, without context switches on pipe reading/writing, but instead passing memory pointers from one app (tr, echo, cat, pc) to another because in reality they are native functions.

fold (+) (
  map atoi
	split '\n' (
		(c -> c >= '0' and c =< '9' or c == '\n') (readFile

Partial evaluation combined with memoization?

Now take that, and combine with a hypothetical OS/PL scheduler that can make decisions based on data locality (cat file), available resources (cpu, memory), amount of data passed between these “programs”, and decide whether it makes sense to run some of these functions in separate threads that do not even have to run on the same machine! If file is located on a remote machine B, the code (binary AST) can be sent over by machine A to machine B for execution to avoid unnecessary latencies and traffic. Same with situations where machine A is overloaded, or has no memory left, etc etc.

Process migration? More like computers working together in tandem, as a single, dynamic, breathing organism that adapts to the situation. What else are computers for?

If code transfer isn’t possible, maybe OS/PL runtime can predict when more data is needed by the program, and ask B to send it over sooner, to avoid network latency. Analogy would be tossing wood into a fire to keep it going. You kinda know when it’s the time. You don’t wait until the flame dies out before tossing in more.

Wood is your data, fire is your program. Why do computers wait?

Maybe an OS where the line between programs and functions does not exist. Where any program is a function (argc and argv turns into named arguments):

myapp --some-arg 1 --boop beep file.txt
myapp (f : Input) (someArg : Num) (boop : string) -> Output

And the other way around is what it should be: a developer writes a function, and a hypothetical “shell” transforms the command line to real function calls. With JIT. With distribution. With partial evaluation. And so on…

These are ideas I want to work on with my PL. I have a lot to learn.

Everything is a function. Even files are. They are either typed in by a human being, or generated/processed by a progr^WFUNCTION. Data is just an argument. Output is application of a function on that data. Instead of storing (or transfering) a file, store (transfer) instructions on how to get “recreate” it. Lazy evaluation, no need to do things unless required - no disk wasted, nor cpu cycles, until the output is required or forced to be provided as some kind of “finalization” of a state. Skipping parts of computation if only a chunk of output is required. Now imagine if things are like that, could we also achieve going back in time? Undo/revert the changes made (or at least not yet made).

Another bullshit(1) worthy thing: neuron-network-driven JIT. If a JIT can produce multitudes of different “ways” (cpu instructions) to run the same calculation, it could be “taught” to choose a good enough (optimized) solution fast. If you consider that many programs have a lot of logic in common (hello, that’s why we have libraries with all these APIs), perhaps some frequently taken paths (profiling could tell) may be optimized further.

That is precisely what compilers developers are doing, except I have hope it’s possible to give that task to computers, so they can start mashing these random keys^Wcpu instructions and comparing the outcomes. Mashing very fast.

Computers are NOT “friends”. They are here to do the work for us.

I assume these things were already considered by some, probably even tried out in practice. Wish I worked in research…


Today I have Karjalan Sissit on repeat.

Changed things up in my PL a bit on request of lovely people of 9gridchan:



Decided to jump on write-your-own PL bandwagon, writing tokenizer so far.



I hate computers…


Added pthreads (and other things) to npe.

Having vdir like this is very helpful:


Too many files in the sam’s menu is not easy to handle and vdir saves the day: I just need to right-click on a file, the lists are always visible.


Fixes and clean up in npe. Audio logic has been overhauled with different formats support and capturing. FastTracker II can now switch audio parameters on the fly and record new samples from audio input. I need to add USB devices support later.

Fixed a bug with renaming in ext4srv.


2013 was the last year I bought a computer worth more than 100$.

More work on npe.

Hiversaires mostly builds on Plan 9 after some heavy fixing of “bad” C. Still missing SDL_mixer.h and SDL_image.h, which I will need to reimplement in npe.

ProTracker 2 builds and runs, but npe needs more work on SDL2 audio subsystem to make the sound work properly. 9front only supports 44.1kHz stereo 16bit samples on /dev/audio so I’ll need to use audio/pcmconv to allow other formats and sampling rates.

Updated Porting post a bit.


Minted potato??? I should totally try that.

Started reading Introduction to Compilers and Language Design. The end goal is to play with some PL ideas that have been cooking in my head for a very long time.

More fixes for npe so that Uxn works correctly.

Yes it does work, no Plan 9 specific patches on uxn required.


With the SDL2 cut-down reimplementation for Plan 9, I can now build and use eg Dotgrid and Nasu on 9front, completely unchanged:



No APE involved either, everything is 100% native.


No computers.


Rum and LEC. No computers.


Small fixes to Plan 9 port of Netsurf.


$ iconv -l
US_ASCII, ISO8859-1, ISO8859-2, ISO8859-3, ISO8859-4, ISO8859-5,
ISO8859-6, ISO8859-7, ...

Yes, it writes .... I can’t get the full list.

Added very dumb reading of S3M title to libtags and zuke.


FastTracker II port for Plan 9 can now loads modules, they can be played (keeps breaking all the time) and edited. With a few more fixes later I will start writing music again, hopefully.


Who cares about 9front, just throw some money at Plan 9 GSOC ideas. The “official” Plan 9 Foundation is ready to hear your ideas!

Porting FastTracker II clone to Plan 9.

Social media is where mental energy is converted into pure electronic garbage with real CO2 impact.

missing log2 and exp2 in Plan 9.

Easy-peasy, define in terms of natural:

#define ln2o1 1.4426950408889634073599

log2(double x)
	return log(x)*ln2o1;

exp2(double x)
	return exp(x/ln2o1);

Of course, it’s not REALLY conformant (left as an exercise for the reader), but you get the idea.


Didn’t do anything spectacular. Just work.


Playing with FT2 clone. Many years ago, Impulse Tracker was my go to. Need to port ft2 to 9 so I’m not stuck at the gaming desktop.


2 avocado, 2 lemon, 5 apple, 1 clementine. These are the new young plants I added to my growing (pun intended) collection this year. I still have a bunch to plant (mostly avocados). Dunno how well any of them are going to grow, my two old avocados aren’t super happy about living in Sweden, but they are still alive, which is great.


Fixed a bug in audio/moddec, it’s supposed to play all mods correctly now.




Wrote a small post about porting alien software to Plan 9 without using APE. Also a script that generates basic headers and a mkfile.


Added unfinished ASS subtitles extraction to mcfs. Setting proper start and end timestamps requires parsing, which requires more time invested.

Theora remuxing was added to mcfs. The decoder is still missing in treason.

Added d command to mothra(1). It searches for specified text on DDG.

Added a simplistic parsing of XM) mod title to libtags. The proper decoder is still missing for those to be playable in zuke, perhaps DUMB is something to try out to cover most of the formats at once.


Added SRT subtitles support to treason. YES THEY LOOK GOOD WITH VGA FONT WHY DO YOU ASK.

VGA #1.

Debugging and fixing more stuff in ext4srv.

Older entries



Last update: April 06, 2021 10:12AM