💾 Archived View for michal_atlas.srht.site › posts › bencode-in-10.gmi captured on 2024-02-05 at 09:28:59. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
I was walking along with a dear friend of mine, debating about the universe and everything. And he mentioned a school project he did, a bencode parser written in Haskell.
If you like me, are unsure what Bencode[a] is
In general, I don’t agree that shorter is always better, however in general, it is often the trend that elegant algorithms produce shorter code, and short code is usually easier to understand. So, I was quite intrigued when he mentioned that the code had “maybe 10 lines”. We didn’t speak of it more, but I went home with this feeling, that I had to know if it was possible.
In the end, the Haskell code was a bit of an overexaggeration, the friend used the Parsec library, and even with that ended up with 20 lines. Luckily, not knowing something is impossible helps with doing it and so I dove into learning common lisp that evening and produced this:
(defun main () (with-input-from-string (s (read-line)) ;; START (defun load-num (&optional (end #\e)) (parse-integer (coerce (loop while (not (equal (peek-char nil s) end)) collect (read-char s) finally (read-char s)) 'string))) (defun load-list () (loop while (not (equal (peek-char nil s) #\e)) collect (benpar) finally (read-char s))) (defun benpar () (if (digit-char-p (peek-char nil s)) (coerce (loop repeat (load-num #\:) collect (read-char s)) 'string) (case (read-char s) ((#\i) (load-num)) ((#\l) (load-list)) ((#\d) (loop for (a b) on (load-list) by #'cddr collect (cons a b)))))) ;; END (print (benpar))))
This successfully parses bencode into an internal representation of the language, beautifully straightforward. There are sadly no safeguards against incorrect input, but my goal was to see if the basic algorithm does fit in about 10 lines, and I’d say it does and there isn’t really much cheating going on, as of course you could just remove whitespace and have a one-line program. But I play fair, and I’d leave it basically the way it is for personal use.