[ mona / prog / sol ]



SchemeBBS [part 2]

1 2020-06-18 04:00

Let's keep the questions about installation and code reviews in one thread.
previous thread http://textboard.org/prog/39


Thanks a lot, I will probably add these worthwhile optimizations. I was thinking about changing the redirection to an absolute path too because, sadly, patching http-syntax.scm has been an exceedingly high barrier entry for many persons who have shown their interest. Updating that file (and the broken httpio.scm) to follow the new RFC might still be possible in future releases of MIT Scheme 10, but I have only recently tried porting SchemeBBS to the newer version. (The 10.1.10 dist you could download from the official site was broken for a year, I've just noticed it's been replaced by 10.1.11, 2020/06/04)

I have a cute idea for some really fun and unique feature that should be very easy to implement but no spoiler.


26 2020-07-19 09:42

Cool, thanks.
{french people joke goes here}

27 2020-08-01 20:31


(define (string->sxml markup s)
  (define (string->sxml-rec s res)
    (let ((match (irregex-search (regex markup) s)))
      (cond ((string-null? s)
            ((not match)
             (append-element res s))
              (let* ((start (irregex-match-start-index match))
                     (end (irregex-match-end-index match))
                     (substr (irregex-match-substring match))
                     (s1 (substring s 0 start))
                     (s2 (substring s end (string-length s))))
                (if (string-null? s1)
                      (append-element res ((transform markup) substr)))
                    (if (and (eq? (name markup) 'del) ;; exception to escape spoiler inside code
                             (between-code? s1 s2))
                        (string->sxml-rec "" (append-element res (string-append s1 substr s2)))
                          (append-element res s1 ((transform markup) substr))))))))))
  (string->sxml-rec s '()))

;; edge false positive (between-code? "==code== ==code==" "==")
;; could add another pass of spoiler, but ok good-enough
(define (between-code? s1 s2)
  (let ((m1 (irregex-search (irregex ".*==$|.*==[^ ]") s1))   ;opening code in s1
        (m2 (irregex-search (irregex ".*[^ ]==") s1))         ;closing code in s1
        (m3 (irregex-search (irregex "^==|.*?[^ ]==") s2))    ;closing code in s2
        (imei irregex-match-end-index))
    (if (and m1 m3 (or (not m2) (>= (imei m1) (imei m2))))

(define (lines->sxml markup l)
  (append-map (lambda (e) 
                (cond ((string? e)
                       (string->sxml markup e))
                      ((eq? (car e) 'del)
                       `(,(cons 'del (lines->sxml markup (cdr e)))))
                      (else `(,e))))

Besides the various types of false positives in between-code?, the "exception to escape spoiler inside code" is also broken in another way. As soon as a spoiler exception is found, all subsequent spoilers on that line are ignored, including those that are completely outside code.

~~one~~ two ~~three~~ ==ab ~~cd~~ ef== gh ~~four~~ ij

one two three ab ~~cd~~ ef gh ~~four~~ ij

This happens because of the

(string->sxml-rec "" (append-element res (string-append s1 substr s2)))

line which exempts the entire s2 from further spoiler processing. The solution is to also return the end position of the closing code tag from between-code?, and use this information to recurse on the s2 portion after that position in string->sxml-rec.

28 2020-08-01 20:42 *


29 2020-08-02 13:31


(define bold
    (irregex  "\\*\\*[^ ].*?[^ ]\\*\\*|\\*\\*[^ ]\\*\\*")
    (lambda (sub) `(b ,(substring sub 2 (- (string-length sub) 2))))))

(define italic
    (irregex  "__[^ ].*?[^ ]__|__[^ ]__")
    (lambda (sub) `(i ,(substring sub 2 (- (string-length sub) 2))))))

(define code
    (irregex  "==[^ ].*?[^ ]==|==[^ ]==")
    (lambda (sub) `(code ,(substring sub 2 (- (string-length sub) 2))))))

(define del
    (irregex "~~[^ ].*?[^ ]~~|~~[^ ]~~")
    (lambda (sub) `(del ,(substring sub 2 (- (string-length sub) 2))))))

This was obviously replicated through copypasting so the error in handling single-character content is shared by all four transform-rules:



The source of the bug is that the branch intended for at least two characters can run over a match intended for the other branch. A solution that does not depend on the order of alternation nor on irregex's mercurial leftmost longest semantics is to exclude the intersection of the two branches using negative lookahead.

$ guile --no-auto-compile -l deps/irregex.scm 
GNU Guile 2.2.3
scheme@(guile-user)> (irregex-match-substring (irregex-search "==[^ ].*?[^ ]==|==[^ ]==" "==a==b c==d=="))
$1 = "==a==b c=="
scheme@(guile-user)> (irregex-match-substring (irregex-search "==[^ ](?!==).*?[^ ]==|==[^ ]==" "==a==b c==d=="))
$2 = "==a=="

The same fix applies to all four transform-rules above.

30 2020-08-03 02:54

The comment of between-code? >>27 identifies one case that yields false positives. It relies on a closing code marker immediately followed by a spoiler, which causes both m1 and m2 to match, and the 'or' will give m1 precedence over m2 in any dispute. False positives can also be obtained by putting any non-space character, such as punctuation, after a code segment:

==one==, ~~two~~, ==three==

one, ~~two~~, three

This happens because both m1 and m2 look at the last potential marker but ignore everything before it, so they do not have enough information to decide whether what looks like an opening or closing marker actually is one. The solution is to replace m1 and m2 with a scan through s1 using irregex-search and (regex code) to skip valid code segments, then look for an opening marker after the last one.



do not edit these


Internal definitions vs letrec

1 2020-08-01 20:53

Which one do you prefer?

(define (fibonacci n)
  (define (fibi n a b)
     ((zero? n) b)
     (else (fibi (- n 1) (+ a b) a))))
  (fibi n 1 0))

(define (fibonacci n)
  (letrec ((fibi (lambda (n a b)
                    ((zero? n) b)
                    (else (fibi (- n 1) (+ a b) a))))))
    (fibi n 1 0)))

4 2020-08-01 22:08

I prefer named lets when they are applicable, and internal defines over letrec as in the following block:

(define (fibonacci n)
  (let fib-iter ((n n) (a 1) (b 0))
    (if (zero? n)
        (fib-iter (- n 1) (+ a b) a))))
5 2020-08-01 22:13

>>4 is nice when it makes sense, but generally I'd say internal definitions (but that might just be my SICP bias speaking).

6 2020-08-02 12:33

I think there are good justifications for internal definitions, it's probably the reason that SICP uses them. For example they always create less indentation, text, and parenthesis. They also allow you to more easily test your internal abstractions at the top-level and generalize these abstractions if they turn out to be generally applicable. I find it very helpful to when defining a procedure to actually start with wishful thinking and define the necessary helper functions at the top-level and then to test incrementally as I'm writing these stand alone components. Only after having something that works do I consider moving these helper procedures into the primary procedure's body. One downside they you all probably remember form SICP is it is not specified in which order internal definitions will be bound.

7 2020-08-02 13:30

With libraries in R6RS and R7RS letting you selectively export bindings, is there still any reason to embed the helper functions? Maybe if you want to capture a variable from the parent function, but in that case you surely would use letrec instead of an internal definition, right?

8 2020-08-02 20:06

Well you did mention the two primary reasons of variable capture and avoiding namespace pollution. I don't see any reason for letrec to be used over internal definitions for variable capture, and I think avoiding namespace pollution remains desirable within a package. Reducing the number of procedures you have to keep up with when reasoning about a subset of a package is useful. If you find yourself in a position where the internal definitions are making things more difficult to reason about it's probably a decent hint that you should split off another package.



do not edit these


Small programming projects ideas

1 2020-05-24 00:20

Share programming tasks that you considered doing at some point but realized you lack the time or motivation and that could be an interesting task for someone else.

Here's one: rewrite Notational Velocity for Linux. The Python clone is awful, so don't use Python or another slow scripting language. NV was the best and simplest note taking software ever made (for people too lazy to get into Org-mode)


It only works on OSX 10.4-10.7 so you'll need an old mac or a VM to run it.


114 2020-07-24 09:21

I like the idea, but playing around with this:

(defvar *function-symbols*
  (let (fns)
    (mapatoms (lambda (a)
                (when (and (functionp a)
                           (documentation a))
                  (push a fns))))

 (nth (random (length *function-symbols*))

it seems most docstrings are rather boring :/

115 2020-07-24 18:24


Maybe it would make sense to limit it to certain functions. For example, if you are reading ``An Introduction to Programming in Emacs Lisp'', you would want to be quizzed only for the functions that were mentioned in the chapters you have finished. The same could be done for the reference manual. Studying a single package from ELPA might also make sense.

As an alternative I thought that unit tests could be also used. For example, here's a snippet from rot13-tests.el:

(ert-deftest rot13-tests-rot13-string ()
  (should (equal (rot13-string "") ""))
  (should (equal (rot13-string (rot13-string "foo")) "foo"))
  (should (equal (rot13-string "Super-secret text")
                 "Fhcre-frperg grkg")))

This could easily be split into just the parts inside the should. You could randomly replace a value with a special symbol (*HIDDEN* or something), and let the user guess what was the original value. The user could supply an alternative solution, but it can be evaluated and accepted if it is equivalent. The bigger issue is that most tests are more involved, they need special buffers and variables, or mention the function tested in the example inputs, etc.

I remember there was some package that would work like Smalltalk's Finder and list you possible functions to use if you have given it the inputs and the desired output. Maybe something like that could be used to generate questions? But generating random inputs is probably a harder problem than finding the function.

116 2020-07-25 21:29


With replacing *HIDDEN* in tests it kinda becomes lisp-koans for emacs

117 2020-07-26 08:40

Apparently elisp-koans exists: https://github.com/jtmoulia/elisp-koans

118 2020-08-02 14:12

A blaseball radio. The API is undocumented but dead simple, so it shouldn't be too difficult.



do not edit these


A Lisp hacker

1 2018-10-31 18:20

You have to go deep underground to find their sites and repos, but it's worth it.



48 2020-08-01 06:53

I'm a tad disappointed at the lack of any questions. I wasn't aware anyone was aware of the Lisp General threads and didn't know I'd only recently started linking to my website instead, so that I could more easily update the resources, but suppose it's not so surprising; it predates Lainchan, yes, by a few months. I've recently finished an implementation of SHA256 in Ada, in preparation for a comprehensive SHA, as with APL and Common Lisp. I also intend to release another little CHIP-8 game to elaborate during the Octo Jam VII, in a few days. I'm in communications with the hoster, so I may finish some games ahead of time, and still get them featured anyway, in a post-session. CHIP-8 is a reasonably nice little machine code, and I've ideas for some interesting games, and how to achieve them well, but I won't drone on further for now.

49 2020-08-01 08:27 *

Anthropomorphic ssssssnakes are known for having an permanent lissssssp in their asssssssscent.

50 2020-08-01 12:26


You just can't hate the web, UNIX, and virtually all other modern computation in a community basically designed for the promotion of these things

Ultimately, you're right, but have you taken a look at HN/Lobsters recently? Every second article is about how the industry is morally bankrupt or built on complex pillars of sand. I'll admit, I used to enjoy reading those doomsday prophets too, but now it just strikes me as dishonest. It's kind of smug self-depreciation, as if the world could be saved if only the high priests of HN could save it. The really biting alternative blogs like LoperOS et al are hardly seen.

Also agree about Versimilitudes/Lisp/Prince Trippy. My impression talking to him on IRC is that he can be overly serious and unyielding in his convictions, but always presents his comments in good faith.

51 2020-08-01 15:28

I've been keeping track of your blog, have fun with your octojam submission!


Every second article is about how the industry is morally bankrupt or built on complex pillars of sand.

I think most of this is just people wishing we could return to the late-1990s and early-2000s before the dot-com bust when things were simpler and products served their users rather than the other way around. It's not a rejection of the internet and UNIX but of change, and further they seem to rarely offer anything actionable, and even less often which goes beyond just a shallow changing of consumer preferences.

52 2020-08-02 02:09 *

Wait I'm adding stomp integration.



do not edit these


Web Frameworks Benchmark

1 2019-12-26 03:18


Rust is finally nailing it.

Never heard of https://vertx.io/ before.

H2O is the fastest C project submitted : https://h2o.examp1e.net/


3 2020-07-25 09:25

Where's MIT Scheme? This site is by far the fastest I've ever visited.

4 2020-07-25 10:00 *


This site is by far the fastest I've ever visited.

Try posting in a three digit post count thread from inside the thread, not from the front page, and see how long the thread rebuild takes.

5 2020-07-25 21:27


Fastest loading because it loads two small text files per request, most "slow" pages are not because the server is slow or the implementation, but because your browser has to wait for some pictures, js, css or other assets to load before rendering the page.

I'm actually quite amazed how little this can be optimized apparently, for example GitHub which surely have a lot of resources to throw at frontend development takes a very noticeable time to load in comparison to any cgit instance.

6 2020-07-28 05:16

also jfremlin's teepeedee2, which unlike Woo doesn't rely on a C library, but is instead linux/sbcl specific. we don't have correspondingly fast SQL libraries though, which is what benchmark above is also testing.

This year's "Round 19" https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=query has some chinese C++11 framework pulling ahead by a crazy 24k margin

7 2020-08-01 08:40

How do they even achieve such differences? I would have assumed that writing webservers is a more-or-less solved problem.



do not edit these



1 2020-06-13 20:09

When I was starting to get into Lisp, the Common Lisp Hyper Spec (CLHS) was quite confusing. The formatting is off, much of the navigation is implemented using images, and despite the sites being packed, it was hard to find what one wanted to know. I have got used to it since, it is still kind of sad that one of the canonical references of the Lisp "community" is a non-free, not even any Creative Commons document, that cannot be updated or maintained by said users. It would be great if it could be redistributed as a SLIME package or as an Info document, but as it says "Copyright 1996-2005, LispWorks Ltd. All rights reserved." at the bottom of the page, it's not possible.

Sadly most alternatives I know of aren't as expansive. So has there ever been a push to get LispWorks to release the HyperSpec into some kind of a public domain/CC-BY-whatever state? If not, is it even feasible? Does anyone here know any details on it's history?


7 2020-07-30 23:27


For navigation it really helps to download [1] the hyperspec and write a script that looks up a symbol in the symbol index which is the most common use case. For example Data/Map_Sym.txt can be parsed for that purpose.

[1]: ftp://ftp.lispworks.com/pub/software_tools/reference/HyperSpec-7-0.tar.gz

8 2020-07-31 03:36

>>7 there's already hyperspec.el for emacs, that can be poached for the mapping. there's both a version for modern hyperspec (with truncated, windows friendly filenames) which is included with SLIME, and the original one that uses unix files http://naggum.no/emacs/hyperspec.el

9 2020-07-31 12:32


;; if only we had had packages or hash tables..., but let's fake it.

Didn't know that hash tables in Elisp aren't even 20-something years old.

10 2020-07-31 13:14

What's funny is how slow the hash tables still are alists with a symbol as a key still outperform them for less than two hundred elements, and the performance doesn't get much better after that. I imagine that with emacs native this would change rather dramatically however.

11 2020-07-31 16:52

They were first included in Emacs 21.1, in 2001. If you are interested in the history of Emacs Lisp, this is a pretty nice and comprehensive paper on the topic: https://dl.acm.org/doi/abs/10.1145/3386324



do not edit these



1 2020-07-01 07:48

Is there anyone here using it? What do you like and do you hate about it?


16 2020-07-28 12:35


Yeah I could setup a binary cache and maybe even Hydra to do that, might if I want it badly enough.

For now tried out Alpine Linux, but I don't really like OpenRC and their design choice of "when in doubt always install / ship less than required for stuff to work" already annoying me a lot.

17 2020-07-28 14:05

When it comes to minimalist distros, void is really nice. runit isn't a mastermind init system, but it's configuration is simple and intuitive. xbps works well and setting up a desktop is not that hard.

18 2020-07-28 14:24


when in doubt always install / ship less than required for stuff to work

i run a gentoo from 3-4 years: i feel like it's right on the edge of a lot of projects getting the xpdf treatment (xpdf used to be one simple package, now it's poppler, which in turn pulls the entire freedesktop stack with it), so i obviously have higher tolerance for pain, but what do you mean by above?

19 2020-07-30 23:29


really annoying if you do setup-xorg-base and it doesn't install mouse and keyboard drivers. like not even keyboard drivers??

20 2020-07-31 03:34

>>19 oh, that sounds like your issue is with "APK"? because OpenRC is just an init daemon



do not edit these


digital piracy and plausible deniability

1 2020-04-23 05:34

I would never download a car nor would I ever stole software, music or movies.
On the other side I have a lot of free time so I spend my days generating random binaries with a program like this:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char** argv)
    long long i, s;
    FILE* f = fopen(argv[1], "w");
    sscanf(argv[2], "%lld", &s);
    for(i=0; i<s; i++){
        fputc(rand() % 255, f);
    return 0;

I run ./libraryofbabel Serial_Experiments_Lain_01_BDRip_hi10p_1080p.mkv 1158962133 a sufficient number of times. Most of the time I get gibberish data but I eventually end up with a perfectly enjoyable anime episode. At no moment have I illegally copied a digital work without the permission of the copyright holder. I generated it myself. A court would have to refute the Infinite Monkey Theorem to prove otherwise. There are no illegal binaries stored in your hard disk if you also hold a copy of this program.


17 2020-07-30 14:06

I can say that because although I'm a nerd, I'm also not so autistic that I don't realize it. The way courts "prove" things has nothing to do with proofs in mathematics. Dumb hacks like "prove the file isn't randomly generated" don't impress courts.

18 2020-07-30 20:12

I dunno, I think you could use probability to say that given the anime existed before your version, and given how unlikely it is that your program produced that version, it is beyond a reasonable doubt that you pirated it. But that's just my non-legal opinion.

19 2020-07-30 22:06 *

You don't sound like your a MIT lisp nerd.

20 2020-08-01 22:16 *


21 2020-08-04 01:10 *

No possession indeed.



do not edit these



1 2020-07-25 19:15

What's up folks,
I've compiled a list of textboard sites in a .json format.
Am I missing any?



9 2020-07-28 14:28

They justify it by invoking free speech and public information. The guy who made that list of imageboards ended up really regretting it on 4-ch.

10 2020-07-30 06:00 *

Was this before or after ccd0 was used for cp spam? Can't check the dates right now.

11 2020-07-30 14:24


Why not s-expressions?

12 2020-07-30 17:10 *

because the guy is not one of ours, he's just spamming all the boards with his "project". more importantly why not just text? i just dumped his json in >>7, and it's not like it requires some complicated knowledge management taxonomy.

13 2020-08-01 22:17 *

Way before. I think.



do not edit these


Everything Emacsen

1 2020-04-18 11:53

Let's talk about Emacsen: GNU Emacs, Guile Emacs, edwim, mg, etc. Do you use them? Do you like them? Do you extend them? Any tips to share? Any questions to ask?


12 2020-07-10 19:11

I thought this was an interesting challenge and gave it a go. It was surprisingly easy to achieve using Guile's compiler infrastructure and flymake. If you actually end up using it, you might want to add every other already existing analysis to the list. It should be easy to figure out how to do it.

https://paste.textboard.org/e6c6dca0 -- guile-shadow.scm
https://paste.textboard.org/97a74add -- guile-shadow.el

For the Scheme code you will need a recent Guile, I think 3.0.3 should work but I used 3.0.4 from Guix. For the Emacs part you might want to modify at least the variables. I am not very confident in my elisp, it probably needs some improvement.

Happy hacking!

13 2020-07-11 13:02

This is wild, I had no idea that you could just poke around at guile's internal representation of a program. Thanks so much for this helpful tool!

14 2020-07-19 20:18

Why are info manuals not more widespread? They are by far the most convenient documentation to browse.

15 2020-07-21 18:02

The main reason is probably the issue of embedding images/tables. Consider




But the again, the 'i' command super-useful.

16 2020-07-21 21:10


The format supports both tables and images, although I have to admit that I've never seen either in use:



do not edit these

New Thread

do not edit these