Sign in

Alexis King

@lexi-lambda.bsky.social
1.7K followers 8 following 70 posts

computers can be understood • she/her, ⚢ • Chicago

PostsRepliesMedia
Alexis King @lexi-lambda.bsky.social · 02/04/2026
racket-nonogram can now show you any mistakes you’ve made, in case you can’t figure out what the issue was and don’t want to have to completely start over
0101
Alexis King @lexi-lambda.bsky.social · 15/03/2026
racket-nonogram now supports automatically generating “mega nonogram” puzzles from standard puzzles
0152
Alexis King @lexi-lambda.bsky.social · 13/03/2026
while working on this I have begun to understand why there are no mega picross implementations on the internet
;; fill-forced-tiles-in-mega-span!
;;   : mega-tiles/c mega-placement-bound? mega-placement-bound?
;;     #:set-full! (-> mega-index? any)
;;  -> (values natural? line-affinity? line-affinity?)
;;
;; Given two mega placement bounds, fills any tiles forced by crosses along the
;; path bridging the two bounds. For example, suppose we have the following row:
;;   ☒☐☐☐☐☐☐☒☐■
;;   ■☐☐☒☐☐☐☐☐☐
;; This function will fill any tiles that must be filled to connect the two
;; filled boxes:
;;   ☒☐■■■☐☐☒☐■
;;   ■■☐☒☐☐■■■☐
;;
;; Along the way, it also calculates and returns the minimum number of tiles
;; that must be filled within the span, taking existing filled tiles into
;; account. It also returns two line affinities that can be used to calculate
;; the minimum cost of extending a placement with the given bounds backwards or
;; forwards, respectively. For example, given the row
;;   ☐☐■☐☒☐☐☐
;;   ☐☐☐☐☐■☐☐
;; then the results of this function applied with bounds (mega-placement-bound 0 2)
;; and (mega-placement-bound 1 5) will be as follows:
;;
;;   1. The returned minimum size will be 5, as at least 5 tiles must be filled
;;      to bridge the two bounds.
;;
;;   2. The first line affinity will be #f, as one possible way to bridge the
;;      two bounds is
;;        ☐☐■☐☒☐☐☐
;;        ☐☐■■■■☐☐
;;      which fills both tiles in the first column. Therefore, it is possible to
;;      extend the filled region backwards to either line at equal cost.
;;
;;   3. The second line affinity will be 1, as filling the tile in the first
;;      line above the end bound would require filling 6 tiles, not five.
;;      Therefore, extending the filled region forwards is biased towards the
;;      second line.
;;
;; Note that the way this function interprets bounds with line 'both or 'either
;; can be somewhat counterintuitive; see Note [Filling forced tiles between
;; placement bounds] for an explanation.This function is used in two different ways:

  1. It is used to bridge the first and last filled tiles in a mega clue.
     When used in this way, the bounds always refer to a specific line,
     never 'both or 'either. This is the mode in which the return values
     are utilized.

  2. It is used to fill tiles forced by the intersection of the earliest
     and latest tightest placements for a clue (or the intersection of one
     such placement and a filled-in tile). This mode is called purely for
     its side effects.

The interpretation of bounds supplied in the second case can be somewhat
counterintuitive, as they represent the greatest lower bound and least
upper bound for a clue’s placement, not tiles that must necessarily be
filled by the placement. For example, suppose we have the following empty
row for a mega 6 clue:
  ☐☐☐☐
  ☐☐☐☐
When we calculate the earliest and latest placements for this clue, we will
get the following two results:
  ▧▧▧☐  ☐▧▧▧
  ▧▧▧☐  ☐▧▧▧
The earliest placement has an end bound of (mega-placement-bound 'both 2)
and the latest placement has a start bound of (mega-placement-bound 'both 1).
The intersection of these bounds yields the following span:
  ☐▧▧☐
  ☐▧▧☐
This function will be called to fill any tiles forced within that span.
Given the fact that the bounds specify 'both lines, it would be easy to
mistakenly believe that all four tiles should be filled. However, that
would be completely wrong in this case, as the bounds do not specify which
tiles are (or should be) filled, they simply define the region inside which
forced tiles *may* be filled. In this example, there are no forced tiles,
so the proper behavior is to do nothing at all.

A natural followup question is to ask what the difference is between a
bound using 'both and a bound using 'either, or indeed what the difference
is between such a bound and one using a specific line. The answer lies in
what we consider to be “forced” at the span endpoints.  ;; Note [Forced mega span endpoints]
  ;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ;; Endpoints of the span must be handled specially. Normally, we fill tiles
  ;; in one of the following shapes:
  ;;   ■■■  ☐☒☐
  ;;   ☐☒☐  ■■■
  ;; This corresponds to the span having to snake around a cross. However, at
  ;; consider the following row:
  ;;   ☒☐☒☐☐☐☒
  ;;   ☒☐☐☐☒☐☒
  ;; Suppose the span starts at the top left empty tile and ends at the bottom
  ;; right empty tile. If we only fill tiles in the above patterns, we’ll end up
  ;; with the following:
  ;;   ☒☐☒■■■☒
  ;;   ☒■■■☒☐☒
  ;; But this is missing the tiles at the ends! However, we don’t want to fill
  ;; the bounds unconditionally. Suppose instead we have the following row:
  ;;   ☐☐☒☐☐☐☐
  ;;   ☐☐☐☐☒☐☐
  ;; If the start and end locations are still the same, the tiles at the ends
  ;; are no longer forced. On the other hand, if we have the row
  ;;   ☐☐☒☐☐☐☒
  ;;   ☒☐☐☐☒☐☐
  ;; they *are* forced. Programmatically, the necessary conditions are:
  ;;
  ;;   1. The bound must cover 'both lines.
  ;;   2. The opposite tile must be bounded behind or afront.
  ;;
  ;; Somewhat counterintuitively, the second condition is all that matters, and
  ;; it holds regardless of whether the bound is the start bound or the end
  ;; bound. To illustrate, consider the following examples:
  ;;   ☐☐▧☐☐  ☐☐▧☐☐
  ;;   ☐☒☐☐☐  ☐☐☐☒☐
  ;; In both examples, ▧ represents a tile in one of the bound columns.
  ;; Regardless of whether we are filling from the left or the right, if the
  ;; bound’s line is 'both, the ▧ tile must be filled.;; It is time to try to fill in boxes using the usual left/right
;; solve strategy. However, for mega clues, this is substantially
;; more complicated. We have to consider two cases separately:
;;
;;   1. If the earliest/latest placement overlaps with an existing
;;      filled-in tile, we want to “extend” the filled region to the
;;      placement’s bound. For example, suppose we have a mega 5
;;      clue in the following row:
;;        ☒☒☒☐☐
;;        ☐■☐☐☐
;;      Since the earliest placement’s end bound is larger than the
;;      filled tile, we want to fill any tiles forced by crosses
;;      from the tile to the bound:
;;        ☒☒☒☐☐
;;        ☐■■■☐
;;
;;   2. If the earliest/latest bounds overlap, we want to fill any
;;      tiles forced by crosses between them. For example, suppose we
;;      have a mega 5 clue in the following row:
;;        ☒☐☐☐☐ ⇒ ☒■■■☐
;;        ☐☐☒☒☐ ⇒ ☐☐☒☒☐
;;
;; It might seem as though tiles filled by the second rule would
;; always include those filled by the first, as long as we’ve placed
;; crosses appropriately to limit the size of the hole. Unfortunately,
;; this is not always true, at least with our current algorithm for
;; selecting an earliest/latest placement. For example, suppose we
;; modify the first example slightly:
;;   ☒☒☐☐☐
;;   ☐■☐☐☐
;; Here, there is no overlap guaranteed by the bounds alone, so if
;; we didn’t have any filled-in tiles, we wouldn’t be able to gain
;; any information.
192
Alexis King @lexi-lambda.bsky.social · 12/03/2026
racket-nonogram now supports networked co-op multiplayer (and has a README) github.com/lexi-lambda/...
1122
Alexis King @lexi-lambda.bsky.social · 08/03/2026
it also supports mega picross-style puzzles now (I have not seen any other implementation of this in existence outside of the switch picross games)
0110
Alexis King @lexi-lambda.bsky.social · 22/02/2026
working on a nonograms implementation in racket based on the switch picross games github.com/lexi-lambda/...
0275
Alexis King @lexi-lambda.bsky.social · 20/02/2026
mflatt: let’s ditch s-exps to make our language more accessible :) also mflatt: rhombus defines eight different ways an identifier can have a binding in the core language and the standard library adds several more. here is the documentation for how to define a basic datatype. do you like this
BNF from https://docs.racket-lang.org/rhombus-reference/class.html#%28def._%28%28submod._%28lib._rhombus%2Fprivate%2Famalgam..rkt%29._core%29._class._rhombus%2Fdefn%29%29Body text from https://docs.racket-lang.org/rhombus-reference/class.html#%28def._%28%28submod._%28lib._rhombus%2Fprivate%2Famalgam..rkt%29._core%29._class._rhombus%2Fdefn%29%29
0131
Alexis King @lexi-lambda.bsky.social · 06/02/2026
who else up experiencing some sort of "new-year" mind vacancy
Screenshot from langdev stack exchange chat that reads: “DannyNiu: Hi all, apologies for 2 poorly-received Q in a row. I'm experiencing some sort of "new-year" mind vacancy, and couldn't think straight.”
0160
Alexis King @lexi-lambda.bsky.social · 02/06/2025
jesus christ
Threads of tweets by @Ngnghm.

Lexi also complains about lack of female Haskellers. But Haskell recruits at the higher end of the IQ spectrum, and especially the math part of it. Between extra variance and skew towards shape rotators vs wordcels, males vastly dominate this population.

Extra variance means that males dominate both ends of the Bell curve for a lot of traits, from intelligent vs stupid to heroes vs criminals.

Unsurprisingly, a lot of the few women we find in these circles have obviously been exposed to a lot of testosterone during their development.

The human sexual dimorphism in cognitive abilities, behavior and preferences is obvious and ubiquitous despite the egalitarian religion destroying the West currently making its mention taboo.

Expecting equality or making it a goal is absurd, self-defeating, and, frankly, evil.

Instead, outliers should enjoy their status as such.

“One good Husband is worth two good Wives; for the scarcer things are, the more they're valued.” — Benjamin Franklin

Moreover, as a programmer, you're already an outlier in abilities and interests. And if you read this post, you're an outlier among these outliers. If you're female, even more so.
1710512
Alexis King @lexi-lambda.bsky.social · 05/01/2025
got to write this extremely fun answer on langdev stack exchange this evening and man I love Daan Leijen so much langdev.stackexchange.com/a/4242/861
[excerpt from the linked answer that starts partway through]

When this function is called, result_location will record the address of wherever result happens to be stored on the stack. Control then yields to the enclosing continuation prompt, and some time later, the continuation is restored. Unless the stack frame for foo happens to be restored to precisely the same location, the write to *result_location will fail to update the new location of result and will instead clobber whatever now happens to be at that address.

Given this fundamental issue, most programming language implementors consider implementing delimited continuations that capture the C stack to be a complete non-starter.
Doing it anyway

Fortunately, Daan Leijen is not most programming language implementors. His audaciously-named 2017 publication Implementing Algebraic Effects in C describes an implementation strategy for delimited continuations that really do capture and restore C stack frames.

How does he do it? By simply always restoring the continuation to exactly the place it was captured from, of course! In § 4.3 Resuming, Leijen describes his implementation strategy:
1425
Alexis King @lexi-lambda.bsky.social · 02/11/2024
I guess I will try posting here: I’ve finally given in and published a small mountain of random bits of racket code I’ve had sitting on my hard drive for ages but haven’t had a good place to put it (and this is not even all of it, as I’m documenting it as I go) github.com/lexi-lambda/...
Toolbox: Miscellaneous Utilities

This library provides a collection of miscellaneous Racket utilities that I use in my personal projects but I have not felt warrant being published as a separate package. Note that this library is intentionally not published on the Racket package server, as everything in this library should be considered unstable. In projects that use it, I include this repository as a Git submodule, pinning to a specific version.

[table of contents]
0187