4-ch over Gopher
_ _ _
| | | ___ __ | |_
|_ _| |___| / _| | ' \
|_| \__| |_||_|
___ __ __ ___ _ _
/ _ \ \ V / / -_) | '_|
\___/ \_/ \___| |_|
___ _
/ __| ___ _ __ | |_ ___ _ _
| (_ | / _ \ | '_ \ | ' \ / -_) | '_|
\___| \___/ | .__/ |_||_| \___| |_|
|_|
╔─*──*──*──*──*──*──*──*──*──*──*──*──*──*──*──*──*──*──*╗
║1 ................................................ 1║
║2* ................................................ *2║
║3 ................................................ 3║
║1 ...............Posted: 2026-01-25............... 1║
║2* Tags: gopher haskell smallnet my_warez my_servs *2║
║3 ................................................ 3║
║1 ................................................ 1║
╚────────────────────────────────────────────────────────╝
I wrote a tiny open source **4-ch.net viewer** that runs over **Gopher**.
The interesting part is the format.
It uses my *gopher applet* style: a **README that is also a literate Haskell
script**. You run it directly:
```
./4_ch.md
```
No build system. No framework. Just `runghc`.
Writing it this way felt like a strange inversion of TDD. Instead of tests, the
README comes first. The code exists to obey the explanation.
"README-driven design."
This works especially well for:
- small scripts
- teaching Haskell
- self-documenting infrastructure
It breaks down for large systems. That is a feature.
The applet plugs straight into **Venusia**, speaks RFC 1436 natively, and keeps
dependencies close to zero.
A 2000s textboard, viewed like its the 90s, implemented like a literate essay.
Live here: gopher://gopher.someodd.zip:70/1/gateway/4_ch
Source: https://github.com/someodd/small-gopher-applets/blob/master/4_ch.md