Louis Maddox's Avatar

Louis Maddox

@permutans.bsky.social

Combinatorially curious https://spin.systems

127 Followers  |  104 Following  |  2,278 Posts  |  Joined: 22.10.2024  |  1.8585

Latest posts by permutans.bsky.social on Bluesky

Concept T shirt that says โ€œDeus ex machina is all you needโ€

25.11.2025 01:55 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0
A special requiremen1was an automated indentured par1slis1that would associa1call of 1heparts necessaryto manufacture a comple11end i1em. There grew to be abou1 two million pans in 1hc Apollo spacecraft

A special requiremen1was an automated indentured par1slis1that would associa1call of 1heparts necessaryto manufacture a comple11end i1em. There grew to be abou1 two million pans in 1hc Apollo spacecraft

One thing I care about that no one else cares about is that the hierarchical, network, and relational database models were *all* explicitly developed to handle manufacturing data.

25.11.2025 00:10 โ€” ๐Ÿ‘ 19    ๐Ÿ” 4    ๐Ÿ’ฌ 2    ๐Ÿ“Œ 0
GitHub PR with 886 files changed, +5k/-45k lines

GitHub PR with 886 files changed, +5k/-45k lines

-18% ! ๐Ÿฅณ new high score

(building something neatโ€ฆ watch this space)

24.11.2025 17:09 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

Example metadata: miscellanea that you might want to bring to a repo but not check in

We donโ€™t really have any ability to โ€˜deploy againstโ€™ a repo in a โ€˜personalโ€™ capacity, be it repo tasks, or just notes/annotations like links to things weโ€™re reading, chats weโ€™re having while coding and other memos

24.11.2025 14:48 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

It also suggests a secondary purpose for syncdoc, rather than operating as a mirroring channel between two forms (in- and out-of-source), they could be additive

The migration CLI fully switches between forms but it actually already can be used this wayโ€”the md docs append to the in-source docstrings

24.11.2025 14:41 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Interesting idea: if you use syncdoc to sync docstrings to markdown (like mkdocs etc in python) then you had a comment in the markdown that got stripped before putting back into the code at docs compile timeโ€ฆ then that operates as a kind of stored metadata, could be used for internal dev annotations

24.11.2025 14:37 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Hooks overwriting data between โ€˜invisibleโ€™ comment markers (to make computations that are โ€œuseful to seeโ€ visible) make a repo โ€˜reactiveโ€™ like a spreadsheet

Besides that visible reactivity though, doing so *within* a comment, keeping computation results *in*visible, would effect reactive *meta*data

24.11.2025 14:18 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

New crate for repo decor ๐Ÿฆ€๐Ÿ–ผ๏ธ

๐Ÿ›ก๏ธ blazon crates.io/crates/blazon
๐Ÿ“œ docs.rs/blazon/lates...
๐Ÿ“‚ github.com/lmmx/blazon

โ€œblazon fastโ€ badge generator for Rust project stats (tree size, build size on disk)

Repo itself demos how to automate updating them via textum/git hook (see github.com/lmmx/blazon/...)

24.11.2025 13:29 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0
A before and after side-by-side diff of the textum CLI in use in a Justfile recipe to replace text between two HTML comments. It reduced from 20+ lines to just 5 lines

A before and after side-by-side diff of the textum CLI in use in a Justfile recipe to replace text between two HTML comments. It reduced from 20+ lines to just 5 lines

CLI greatly simplified without JSON ! ๐Ÿ˜…

24.11.2025 13:13 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

Gravitating towards โ€œanything in a repo that you want to update to โ€˜read outโ€™ the state in-place should be implemented as a hookโ€

I typically externalise readout of reposโ€™ metadata through artifacts either statically built on CI [think docs] or as live external web services [think CI status badges]

24.11.2025 13:00 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Repo CI bots are inherently limited to superficial (merely visual) activity, if they commit [for anything besides intermittent releases] theyโ€™d corrupt the VCS history with noise, and you wouldnโ€™t want them to rewrite the historyโ€ฆ

โ€ฆSo to intensify automation in a repo in-place requires commit hooks

24.11.2025 12:53 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Build a Compiler in Five Projects Class website here: https://kmicinski.com/cis531-f25

My five-project (along with slides, video lectures, etc.) compilers course has all projects now available online free: kmicinski.com/functional-p.... Five projects have you incrementally build a compiler for a substantial language, including functions, mutation, loops, vectors, etc.

24.11.2025 03:26 โ€” ๐Ÿ‘ 24    ๐Ÿ” 10    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 1

Chicken soup sour?

24.11.2025 02:16 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0
A print out of `textum -h` (the help text for textum)

โ€”

Usage: textum <COMMAND> [OPTIONS]

A syntactic patching tool with char-level granularity.

Commands:
  replace <TARGET> <REPLACEMENT> <FILES>...  Replace text in files
  delete <TARGET> <FILES>...                 Delete text from files
  apply [PATCH_FILE]                         Apply JSON patches

Replace/Delete Options:
  --pattern              Use regex pattern matching
  --lines START:END      Operate on line range
  --until END_MARKER     Operate between TARGET and END_MARKER
  --include-markers      Include boundary markers (default: exclude)
  -n, --dry-run          Preview changes
  -d, --diff             Show diff
  -v, --verbose          Verbose output

Examples:
  # Simple replacement
  textum replace 'old' 'new' file.txt

  # Between markers
  textum replace '<!-- start -->' 'content' --until '<!-- end -->' README.md

  # Delete lines
  textum delete --lines 5:10 file.txt

  # JSON mode
  textum apply patches.json

A print out of `textum -h` (the help text for textum) โ€” Usage: textum <COMMAND> [OPTIONS] A syntactic patching tool with char-level granularity. Commands: replace <TARGET> <REPLACEMENT> <FILES>... Replace text in files delete <TARGET> <FILES>... Delete text from files apply [PATCH_FILE] Apply JSON patches Replace/Delete Options: --pattern Use regex pattern matching --lines START:END Operate on line range --until END_MARKER Operate between TARGET and END_MARKER --include-markers Include boundary markers (default: exclude) -n, --dry-run Preview changes -d, --diff Show diff -v, --verbose Verbose output Examples: # Simple replacement textum replace 'old' 'new' file.txt # Between markers textum replace '<!-- start -->' 'content' --until '<!-- end -->' README.md # Delete lines textum delete --lines 5:10 file.txt # JSON mode textum apply patches.json

textum v0.4.0 now has multiple CLI subcommands ! ๐Ÿคฉ

JSON patches can still be used for programmatic CLI usage but this should be more human-friendly

24.11.2025 01:21 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Single module of CLI integration tests factored out into groups in subdir test module files. Cargo nextest list shows the files within the subdir files

Single module of CLI integration tests factored out into groups in subdir test module files. Cargo nextest list shows the files within the subdir files

Had not thought of this one before ๐Ÿค”

Since a test module acts as if a crate unto itself, rather than use main.rs to spread em horizontally you can drop down into a submodule by reusing the โ€˜crateโ€™ (module) name as an inline mod and listing subdir filenames in it, whose path thus resolves underneath

24.11.2025 00:02 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0
v0.3 docs for textum

โ€”

String-Based API (No Rope Required)

For convenience, patches can be applied directly to strings without needing to import or work with Rope types. Use Patch::in_memory() for patches that donโ€™t need a file path:

```
use textum::{Patch, Snippet, Boundary, BoundaryMode, Target};

let content = "hello world";

let snippet = Snippet::At(Boundary::new(
    Target::Literal("world".to_string()),
    BoundaryMode::Include,
));

let patch = Patch::in_memory(snippet, "rust");
let result = patch.apply_to_string(content).unwrap();
assert_eq!(result, "hello rust");
```

Apply Single Patch to File

Apply a patch to a file from disk, with options to inspect or write results:

```
use textum::{Patch, BoundaryMode};

let patch = Patch::from_literal_target(
    "tests/fixtures/sample.txt".to_string(),
    "world",
    BoundaryMode::Include,
    "rust",
);

// Get the result without writing
let result = patch.apply_to_file().unwrap();
println!("Would change to: {}", result);

// Or write directly to disk
patch.write_to_file().unwrap();
```

Composing Multiple Patches

For applying multiple patches to one or more files, use PatchSet. Use apply_to_files() to get results in memory for inspection, or write_to_files() to apply and write directly to disk:

```
use textum::{Patch, PatchSet, BoundaryMode};

let mut set = PatchSet::new();

set.add(Patch::from_literal_target(
    "tests/fixtures/sample.txt".to_string(),
    "hello",
    BoundaryMode::Include,
    "goodbye",
));

set.add(Patch::from_literal_target(
    "tests/fixtures/sample.txt".to_string(),
    "world",
    BoundaryMode::Include,
    "rust",
));

// Get results in memory for inspection
let results = set.apply_to_files().unwrap();
assert_eq!(results.get("tests/fixtures/sample.txt").unwrap(), "goodbye rust\n");

// Or write directly to disk
// set.write_to_files().unwrap();
```

v0.3 docs for textum โ€” String-Based API (No Rope Required) For convenience, patches can be applied directly to strings without needing to import or work with Rope types. Use Patch::in_memory() for patches that donโ€™t need a file path: ``` use textum::{Patch, Snippet, Boundary, BoundaryMode, Target}; let content = "hello world"; let snippet = Snippet::At(Boundary::new( Target::Literal("world".to_string()), BoundaryMode::Include, )); let patch = Patch::in_memory(snippet, "rust"); let result = patch.apply_to_string(content).unwrap(); assert_eq!(result, "hello rust"); ``` Apply Single Patch to File Apply a patch to a file from disk, with options to inspect or write results: ``` use textum::{Patch, BoundaryMode}; let patch = Patch::from_literal_target( "tests/fixtures/sample.txt".to_string(), "world", BoundaryMode::Include, "rust", ); // Get the result without writing let result = patch.apply_to_file().unwrap(); println!("Would change to: {}", result); // Or write directly to disk patch.write_to_file().unwrap(); ``` Composing Multiple Patches For applying multiple patches to one or more files, use PatchSet. Use apply_to_files() to get results in memory for inspection, or write_to_files() to apply and write directly to disk: ``` use textum::{Patch, PatchSet, BoundaryMode}; let mut set = PatchSet::new(); set.add(Patch::from_literal_target( "tests/fixtures/sample.txt".to_string(), "hello", BoundaryMode::Include, "goodbye", )); set.add(Patch::from_literal_target( "tests/fixtures/sample.txt".to_string(), "world", BoundaryMode::Include, "rust", )); // Get results in memory for inspection let results = set.apply_to_files().unwrap(); assert_eq!(results.get("tests/fixtures/sample.txt").unwrap(), "goodbye rust\n"); // Or write directly to disk // set.write_to_files().unwrap(); ```

textum v0.3

๐Ÿชข re-exports Rope to avoid consumers having to depend on the ropey crate too
๐Ÿ’ญ Patch can now be in-memory
๐Ÿ“ adds new write_to_file(s) methods for Patch/PatchSet and uses this in the CLI
๐Ÿงฎ adds a -d/--diff flag to show what a patch would change (a more useful alternative to -n/--dry-run)

23.11.2025 22:28 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Been listening to the song Colliding Walls on repeat for maybe 3 days and just twigged thatโ€™s why Iโ€™m back on my text boundary snippet targetting API library hype

23.11.2025 17:49 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0
Etymology redit 1
The word blazon is derived from French blason, 'shield'. It is found in English by the end of the 14th century. [1]

Formerly, heraldic authorities believed that the word was related to the German verb blasen 'to blow (a horn). [2][3] Present-day lexicographers reject this theory as conjectural and disproved.[1]

Grammar

Blazon is generally designed to eliminate ambiguity of interpretation, to be as concise as possible, and to avoid repetition and extraneous punctuation. 

English antiquarian Charles Boutell stated in 1864:

Heraldic language is most concise, and it is always minutely exact, definite, and explicit; all unnecessary words are omitted, and all repetitions are carefully avoided; and, at the same time, every detail is specified with absolute precision.
The nomenclature is equally significant, and its aim is to combine definitive exactness with a brevity that is indeed laconic. [4]

Etymology redit 1 The word blazon is derived from French blason, 'shield'. It is found in English by the end of the 14th century. [1] Formerly, heraldic authorities believed that the word was related to the German verb blasen 'to blow (a horn). [2][3] Present-day lexicographers reject this theory as conjectural and disproved.[1] Grammar Blazon is generally designed to eliminate ambiguity of interpretation, to be as concise as possible, and to avoid repetition and extraneous punctuation. English antiquarian Charles Boutell stated in 1864: Heraldic language is most concise, and it is always minutely exact, definite, and explicit; all unnecessary words are omitted, and all repetitions are carefully avoided; and, at the same time, every detail is specified with absolute precision. The nomenclature is equally significant, and its aim is to combine definitive exactness with a brevity that is indeed laconic. [4]

mot du jour ๐Ÿ›ก๏ธ๐Ÿ—ก๏ธ๐Ÿ‘€ en.wikipedia.org/wiki/Blazon#...

23.11.2025 15:52 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

Itโ€™ll vary by hardware but I saw the parser crate build 6x faster and -75% the build size (45 MB down to 12 MB), just from removing unused transitive deps!

23.11.2025 15:02 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0
Before and after the `ra_ap_parser` and `ra_ap_syntax` crates were pruned of unnecessary syn transitive dependencies (via default tracing โ€œattributesโ€ feature)

Before and after the `ra_ap_parser` and `ra_ap_syntax` crates were pruned of unnecessary syn transitive dependencies (via default tracing โ€œattributesโ€ feature)

The rust-analyzer syntax and parse crates are now free of syn ! ๐Ÿ˜‡ github.com/rust-lang/ru...

Expect itโ€™ll be released tomorrow

The reason was tracing crateโ€™s default features are โ€œstdโ€ and โ€œattributesโ€, the latter is only needed if you are using the `#[instrument]` attribute macro, these were not!

23.11.2025 14:56 โ€” ๐Ÿ‘ 4    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Top down view of Kirby hovering

Top down view of Kirby hovering

13.10.2025 23:46 โ€” ๐Ÿ‘ 4    ๐Ÿ” 3    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

rust-analyzer first time contrib auto-merge in 3... 2...

23.11.2025 13:44 โ€” ๐Ÿ‘ 3    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

meh, this doesnโ€™t save you any chars and is actually less legible because it implies the reader must know what -X does (batch execute on results list)โ€ฆ

23.11.2025 12:32 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

๐Ÿ’ก

`rg foo $(fd -e ext) -l`

is just

`fd -e ext -X rg foo -l`

23.11.2025 12:13 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Very important that children learn how to swim so that when they grow up they are well-trained to hold their breath for minutes at a time while refactoring complex crate workspace dependencies

23.11.2025 12:02 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

Itโ€™d become a badge of honour to have single digit crate treesโ€ฆ or better still have the badge link to a fresh cargo tree list so they can see for themselves and not have to go TOML chasing thru transitive deps

23.11.2025 02:12 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

Occurs to me I could set this up to generate an inline SVG badge with a commit hook that stores some metadata in there, e.g. hash of the Cargo.toml, so you only recompute [i.e. build release mode target/calculate cargo tree size] if that changedโ€ฆ

23.11.2025 02:08 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Would it not be helpful to show crate tree size and built target size for the default features for crates? Seems obviously missing

23.11.2025 00:12 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 1

Some filmic entrepreneur has set up a ring light and camera on a turntable blasting Mariah in the central embankment on Oxford Circus and presumably charging tourists

22.11.2025 19:26 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

Area man overly excited by 0.4% improvement on arcane north star metric

22.11.2025 17:14 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

@permutans is following 20 prominent accounts