Sign in

iiinova is part of the Atmosphere — an open, public network where you own your identity.

raganwald.com

@raganwald.functional.cafe.ap.brid.gy
25 followers 2 following 144 posts

Reg "raganwald" Braithwaite's account for discussing functional programming and shamelessly plugging essays about programming. Follows are NOT endorsements. This […] 🌉 bridged from ⁂ functional.cafe/@raganwald, follow @ap.brid.gy to interact

PostsRepliesMedia
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 16/10/2026
A "construction" is how you make a new combinator out of existing combinators. This one expects two quoted values—"A" and "B"—and processes them with the commented combinators shown. The Euclidean Division combinator is provisionally named a "construction." […] [Original post on functional.cafe]
import { A } from "../combinator-tools/placeholders";
import { proper } from "../combinator-tools/propriety";

export const m = proper([ [A] ], [ [A], A ]);
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 16/10/2026
The M combinator (aka “Mockingbird”) in action: The Mockingbird and Sage Bird (Y Combinator) are Computer Science’s primordial implementations of recursion. tunes.org/~iepos/joy.html Here we are implementing Euclidean Division in concatenative […] [Original post on functional.cafe]
// n.b. returns quoted numbers, not applicable numbers,
// as it is necessary to select whether one wants the quotient, remainder, or both.
const euclideanDividedBy = construction([ [B], [A] ], [
  [zero], bury, // [quotient] [dividend] [divisor]
  [
    bury3,       // [callback] [quotient] [dividend] [divisor]
    dup,         // [callback] [quotient] [dividend] [divisor]  [divisor]
    [swap], dip, // [callback] [quotient] [divisor]  [dividend] [divisor]
    [dup], dip,  // [callback] [quotient] [divisor]  [dividend] [dividend] [divisor]
    isLessThan,  // [callback] [quotient] [divisor]  [dividend] [T/F: dividend < divisor]
    [
      // [callback] [quotient] [divisor] [dividend] 
      [[minus], cons, cons], sip, // [callback] [quotient] [dividend - divisor] [divisor]
      dig2, // [callback] [dividend - divisor] [divisor] [quotient]
      [succ], cons, // [callback] [dividend - divisor] [divisor] [quotient++]
      bury2, // [callback] [quotient++] [dividend - divisor] [divisor] 
      dig3, // [quotient++] [dividend - divisor] [divisor] [callback]
      m
    ],
    [
      // [callback] [quotient] [divisor] [dividend]
      nip, // [callback] [quotient] [dividend]
      dig2, zap // [quotient] [dividend]
    ],
    cond // [quotient] [remainder]
  ],
  m, // [quotient] [remainder]
]);
112 2
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 08/10/2026
Hand-written tests for porting boolean operators from the Lambda Calculus and/or Smullyan Forest to Concatenative Combinators. Yet another reminder to... “Beware of the Turing tar-pit in which everything is possible but nothing of interest is easy.”—Dr. Alan J. Perlis, 1982
// [B] [A] And == [B && A]
test("boolean and", () => {
  expect(display(rewrite([ [False], [False], And ]))).toEqual(display(rewrite([ [False] ])));
  expect(display(rewrite([ [False], [True],  And ]))).toEqual(display(rewrite([ [False] ])));
  expect(display(rewrite([ [True],  [False], And ]))).toEqual(display(rewrite([ [False] ])));
  expect(display(rewrite([ [True],  [True],  And ]))).toEqual(display(rewrite([ [True]  ])));
});

// [B] [A] Or == [B || A]
test("boolean or", () => {
  expect(display(rewrite([ [False], [False], Or ]))).toEqual(display(rewrite([ [False] ])));
  expect(display(rewrite([ [False], [True],  Or ]))).toEqual(display(rewrite([ [True]  ])));
  expect(display(rewrite([ [True],  [False], Or ]))).toEqual(display(rewrite([ [True]  ])));
  expect(display(rewrite([ [True],  [True],  Or ]))).toEqual(display(rewrite([ [True]  ])));
});

// [A] Not == [¬A]
test("boolean not", () => {
  expect(display(rewrite([ [False], Not ]))).toEqual(display(rewrite([ [True]  ])));
  expect(display(rewrite([ [True],  Not ]))).toEqual(display(rewrite([ [False] ])));
});

// [B] [A] Xor == [(B || A) && ¬(B && A)]
test("boolean or", () => {
  expect(display(rewrite([ [False], [False], Xor ]))).toEqual(display(rewrite([ [False] ])));
  expect(display(rewrite([ [False], [True],  Xor ]))).toEqual(display(rewrite([ [True]  ])));
  expect(display(rewrite([ [True],  [False], Xor ]))).toEqual(display(rewrite([ [True]  ])));
  expect(display(rewrite([ [True],  [True],  Xor ]))).toEqual(display(rewrite([ [False]  ])));
});
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 30/09/2026
A naïve first working predecessor for the applicative Church numerals in concatenative combinators:
export const times = b;
export const plus = construction([ [cons, b], cons, s ]);
export const exponent = i;

export const succ = construction([ [z1], plus ]);
export const pred = construction([
  // initialization
  [[z0], [z0]],
  // [[__], [Zn]] => [Zn], [++Zn]
  [i, nip, dup, [succ], cons],
  // dig the quoted parameter up: [C] [B] [A] => [B] [A] [C]
  dig,
  // apply it, counting up: [z0], [z0] => [z0], [z1] => [z1], [z2] => [z2], [z3], ...
  i,
  // discard the rightmost quoted number, revealing the quoted predecessor
  zap,
  // apply it
  i
]);

test("pred", () => {
  expect((rewrite([[[]], [unit], [z0], pred]))).toEqual(rewrite([[[]], [unit], z0]));
  expect((rewrite([[[]], [unit], [z1], pred]))).toEqual(rewrite([[[]], [unit], z0]));
  expect((rewrite([[[]], [unit], [z2], pred]))).toEqual(rewrite([[[]], [unit], z1]));
  expect((rewrite([[[]], [unit], [z3], pred]))).toEqual(rewrite([[[]], [unit], z2]));
  expect((rewrite([[[]], [unit], [z4], pred]))).toEqual(rewrite([[[]], [unit], z3]));
});
001 1
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 29/09/2026
CoffeeScript Ristretto is a short book about a programming language that is intentionally small. It was inspired by "The Little Lisper" and "SICP," books that could not be written about Java, JavaScript, or TypeScript. raganwald.com/assets/books/coffeesc…
A book cover. At the top are the words: CoffeeScript Ristretto. Below on the left is a chrome coffee implement with a handle and wood accents. Below on the right, in a thought bubble, are the words: brought to you by Reg "Raganwald" Braithwaite.
042 4
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 19/09/2026
Practical Use Cases of the K-combinator (Kestrel) in JavaScript: Real-World Examples and Implementation www.xjavascript.com/blog/practical-…
001 1
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 18/09/2026
The “Church of Z” now supports product, sum, and exponentiation combinators. en.wikipedia.org/wiki/Church_encodi…
test("product", () => {
  expect(rewrite([ [], [unit], [z0], [z3], product ])).toEqual(rewrite([ [], [unit], z0 ]));
  expect(rewrite([ [], [unit], [z3], [z0], product ])).toEqual(rewrite([ [], [unit], z0 ]));
  expect(rewrite([ [], [unit], [z1], [z5], product ])).toEqual(rewrite([ [], [unit], z5 ]));
  expect(rewrite([ [], [unit], [z5], [z1], product ])).toEqual(rewrite([ [], [unit], z5 ]));
  expect(rewrite([ [], [unit], [z2], [z3], product ])).toEqual(rewrite([ [], [unit], z6 ]));
  expect(rewrite([ [], [unit], [z3], [z2], product ])).toEqual(rewrite([ [], [unit], z6 ]));
});

test("sum", () => {
  expect(rewrite([ [], [unit], [z0], [z3], sum ])).toEqual(rewrite([ [], [unit], z3 ]));
  expect(rewrite([ [], [unit], [z3], [z0], sum ])).toEqual(rewrite([ [], [unit], z3 ]));
  expect(rewrite([ [], [unit], [z1], [z5], sum ])).toEqual(rewrite([ [], [unit], z6 ]));
  expect(rewrite([ [], [unit], [z5], [z1], sum ])).toEqual(rewrite([ [], [unit], z6 ]));
  expect(rewrite([ [], [unit], [z2], [z3], sum ])).toEqual(rewrite([ [], [unit], z5 ]));
  expect(rewrite([ [], [unit], [z3], [z2], sum ])).toEqual(rewrite([ [], [unit], z5 ]));
});

test("exponent", () => {
  expect(rewrite([ [], [unit], [z2], [z0], exponent ])).toEqual(rewrite([ [], [unit], z1 ]));
  expect(rewrite([ [], [unit], [z2], [z1], exponent ])).toEqual(rewrite([ [], [unit], z2 ]));
  expect(rewrite([ [], [unit], [z2], [z2], exponent ])).toEqual(rewrite([ [], [unit], z4 ]));
  expect(rewrite([ [], [unit], [z2], [z3], exponent ])).toEqual(rewrite([ [], [unit], z8 ]));
  expect(rewrite([ [], [unit], [z3], [z2], exponent ])).toEqual(rewrite([ [], [unit], z9 ]));
});
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 18/09/2026
As delightfully shown in Raymond Smullyan’s classic “To Mock a Mockingbird,” if a combinatorial forest has both a starling and a kestrel, it also has every other combinatorial bird: archive.org/details/tomockmockingbi… And as go […] [Original post on functional.cafe]
// [C] [B] [A] s == [[C] B] [C] A
export const s = combinator((C: Quotation, B: Quotation, A: Quotation) => [ [C, ...B], C, ...A ]);
export const starling = s;

//     [B] [A] k == A
export const k = combinator((B: Quotation, A: Quotation) => [ ...A ]);
export const kestrel = k;
201 2
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 18/09/2026
This is, of course, a game in the same game theory family as “The Prisoner’s Dilemma.” North American roads are the board for an n-player “Arms Race.” archive.org/details/prisonersdilemm…
011 1
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 16/09/2026
Church numerals in concatenative combinators have begun to manifest themselves.
test("zn", () => {
  expect(z0([ [z0], [z1] ])).toEqual([ z0 ]);
  expect(z1([ [z0], [z1] ])).toEqual([ [ z0 ], z1 ]);
  expect(z2([ [z0], [z1] ])).toEqual([ [ [ z0 ], z1 ], z1 ]);
  expect(z3([ [z0], [z1] ])).toEqual([ [ [ [ z0 ], z1 ], z1 ], z1 ]);
  expect(z4([ [z0], [z1] ])).toEqual([ [ [ [ [ z0 ], z1 ], z1 ], z1 ], z1 ]);
  expect(z5([ [z0], [z1] ])).toEqual([ [ [ [ [ [ z0 ], z1 ], z1 ], z1 ], z1 ], z1 ]);
  expect(z6([ [z0], [z1] ])).toEqual([ [ [ [ [ [ [ z0 ], z1 ], z1 ], z1 ], z1 ], z1 ], z1 ]);
  expect(z7([ [z0], [z1] ])).toEqual([ [ [ [ [ [ [ [ z0 ], z1 ], z1 ], z1 ], z1 ], z1 ], z1 ], z1 ]);
  expect(z8([ [z0], [z1] ])).toEqual([ [ [ [ [ [ [ [ [ z0 ], z1 ], z1 ], z1 ], z1 ], z1 ], z1 ], z1 ], z1 ]);
  expect(z9([ [z0], [z1] ])).toEqual([ [ [ [ [ [ [ [ [ [ z0 ], z1 ], z1 ], z1 ], z1 ], z1 ], z1 ], z1 ], z1 ], z1 ]);
});
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 14/09/2026
The inner implementation of a base concatenative combinator, `cons`:
//     [B] [A] cons == [[B] A]
export const cons = combinator((B: Parameter, A: Parameter) => {
  if (!isProgram(A)) return Fail;
  if (!isProgram(B)) return Fail;
  if (A.length === 0) return Fail;
  if (B.length === 0) return Fail;

  return [ [B, ...A] ];
});
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 03/09/2026
“The string is a stark data structure and everywhere it is passed there is much duplication of process. It is a perfect vehicle for hiding information.” —Epigrams in Programming by Dr. Alan J. Perlis (1982) www.cs.yale.edu/homes/perlis-alan/q…
120 2
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 08/07/2026
Exploring Regular Expressions and Finite-State Recognizers… By implementing constructive proofs in code. Part I: raganwald.com/2019/09/21/regular-ex… Part II: raganwald.com/2019/12/17/regular-ex…
A visual depiction of the "Shunting Yard" algorithm converting an infix expression into a postfix expression that can be evaluated with a stack.
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 28/06/2026
I'm busy with Balanced Parentheses, but just as APL was opinionated about using characters that weren't available on every English language keyboard, is there an esolang the depends upon Susan Kare's “Cairo” font from 1984?
A grid of "dingbats" from Apple Computer’s “Cairo” font that shipped with Macintosh in 1984. Cairo was designed by Susan Kare, the artist who also designed the original Macintosh OS’ iconography.
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 16/06/2026
"This esolang of yours, I presume you brought your favourite JavaScript features over?" Well, I dunno about ✌🏽favourite✌🏽, but yeah, its lists can and often do have holes in them.
### the list interpretation of balanced parentheses

Chaining cons cells together by the `cdr` pointer creates a list. For example, this is a list of five holes —`()()()()()`—diagrammed to show the links:

```mermaid
graph LR
	EmptyPair@{ shape: dbl-circ, label: "()" }
	Five(["()()()()()"]) --> Four(["()()()()"])
	Four --> Three(["()()()"])
	Three --> Two(["()()"])
	Two --> EmptyPair
```
We don't call it a list of empty pairs. The pairs we write in text notation are containers, and if the pairs contain empty, than we say this is a list of five holes. 

A list of five empty pairs looks like this:

```mermaid
graph TD
	EmptyPair@{ shape: dbl-circ, label: "()" }
	Five(["(())(())(())(())(())"]) --o EmptyPair
	Five --> Four(["(())(())(())(())"])
	Four --o EmptyPair
	Four --> Three(["(())(())(())"])
	Three --o EmptyPair
	Three --> Two(["(())(())"])
	Two --o EmptyPair
	Two --> One(["(())"])
	One --o EmptyPair
```
050 5
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 13/06/2026
No good can come of slouching towards an esolang with cons cell semantics and lots of idiotic silly parentheses that aren't actual S-expressions.
### the cons cell interpretation of balanced parentheses

An empty pair of parentheses is a cons cell with both its `car` and `cdr` pointing to the empty string (`ε`). The `car` pointer terminates in a circle, the `cdr` pointer terminates in an arrow.

```mermaid
graph LR
	A(["()"]) -- car --o E:::transparent@{ shape: circ, label: "ε" }
	A -- cdr --> E
	classDef transparent stroke:#ffffff, fill: #ffffff
```

Either or both can point to another cons cell:

```mermaid
graph LR
	B(["(())"]) -- car --o A
	B(["(())"]) -- cdr --> E
	A(["()"]) -- car --o E:::transparent@{ shape: circ, label: "ε" }
	A -- cdr --> E
	classDef transparent stroke:#ffffff, fill: #ffffff
```
```mermaid
graph LR
	C(["()()"]) -- car --o E
	C(["()()"]) -- cdr --> A
	A(["()"]) -- car --o E:::transparent@{ shape: circ, label: "ε" }
	A -- cdr --> E
	classDef transparent stroke:#ffffff, fill: #ffffff
```
```mermaid
graph LR
	D(["(())()"]) -- car --o A
	D(["(())()"]) -- cdr --> A
	A(["()"]) -- car --o E:::transparent@{ shape: circ, label: "ε" }
	A -- cdr --> E
	classDef transparent stroke:#ffffff, fill: #ffffff
```
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 09/06/2026
TFW the least authoritative person you know is cited as a source by AI.
Search Assist

OOP (Object-Oriented Programming) is often humorously referred to as POO
(Programming Out Of Order) in some discussions, highlighting the idea that it can be misapplied or overused. This playful term suggests that while OOP is a valuableprogramming paradigm, it can sometimes lead to unnecessary complexity in code.

Wikipedia raganwald.com

Auto-generated based on listed sources. May contain inaccuracies. Was this helpful?
110 1
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 23/02/2026
Espresso Ristretto. I miss CoffeeScript, I was very fond of that language and the lovely experience of working with CoffeeScript, Backbone, and even jQuery during a time when interfaces were considerably more CRUD-forward. raganwald.com/assets/books/coffeesc…
An espresso ristretto in a Mondrian-themed cup and saucer sits in front of a MacBook on a glass table.
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 12/02/2026
A very famous cover illustrated by Robert Frank Tinney (1947 - 2026). The mass adoption of OOP was the result of many interlocking changes, but this cover of this issue of Byte Did a great deal to popularize Smalltalk and contemporaneous OO languages. Not […] [Original post on functional.cafe]
A cover of Byte Magazine featuring a colourful balloon labeled "Smalltalk" over a castle on a mountain
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 16/01/2026
JavaScript Allongé was written in this converted semi-detached cottage.
The living area of a small cottage that is heated by a stove.
010 1
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 16/01/2026
Life, coffee, and blueberry pie. conwaylife.com/book
A book about Conway's Game of Life open to a new chapter about spaceships, a Mondrian cup of espresso, and a mostly eaten blueberry pie in a foil baking pan.
020 2
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 05/12/2025
Although many people say that JavaScript Allongé is a book about functional programming, it’s actually a book about how functions as first-class entities facilitate composition. So... Although Kleisli arrows allow for the composition of functions that work […] [Original post on functional.cafe]
A man draws a green compound bow, overlaid with the question “Allonge?” (sic).
010 1
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 03/12/2025
A personal favourite. And yes there *is* a Mister Braithwaite in “Enter the Dragon!” raganwald.com/2011/11/01/williams-m…
A light-skinned black man with a full afro and mutton chops loos to our left, his right
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 24/11/2025
At the turn of the century, OG blogger Joel Spolsky posited the "Joel Test," twelve simple yes/no questions that defined a reasonable-by-the-standards-of-the-day local optimum for shipping software. Some seem ridiculously obvious today, but weren't standard […] [Original post on functional.cafe]
Do you use source control?
Can you make a build in one step?
Do you make daily builds?
Do you have a bug database?
Do you fix bugs before writing new code?
Do you have an up-to-date schedule?
Do you have a spec?
Do programmers have quiet working conditions?
Do you use the best tools money can buy?
Do you have testers?
Do new candidates write code during their interview?
Do you do hallway usability testing?
110 1
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 15/11/2025
source: @RandomHourlyDuckBot
A duckling in mid-squawk is overlaid with the words, "A either end of the strong typing scale, there lies a hacker class."
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 09/11/2025
A duck-shaped novelty bottle of whiskey is overlaid with the words, "When you're days into refactoring a duck-typed codebase"
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 08/11/2025
A Brutal Look at Balanced Parentheses, Computing Machines, and Pushdown Automata raganwald.com/2019/02/14/i-love-pro…
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 08/11/2025
Forget algebraic types, the Type Lords use Gallifrean types.
A young woman looks at words written underneath old, peeling wallpaper. Overlaid are the words "Blink, and the weeping angels of strong typing will feed on your time. Ok, and duck type! Really duck type!"
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 06/11/2025
There are two ways to write production #TypeScript. One is to use such advanced type features that if it compiles at all, you can be sure there are no obvious bugs. The other is to write such straightforward, extremely simple types that there are obviously no bugs. Only a third method works.
221 2
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 05/11/2025
Source: @RandomHourlyDuckBot
A pile of yellow and brown ducklings, overlaid with:

There is no one right kind of duck-typed programming language.

postscript: If concatinative languages Factor into your choice, then go FORTH and seek Joy.
011 1
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 04/11/2025
Since 1951.
A cartoon rabbit and a cartoon duck stand on either side of a tree trunk. A sign says that it is DUCK SEASON, and someone has pasted the word "typing" between the two words.
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 03/11/2025
Source: @RandomHourlyDuckBot
A duck stands on a city sidewalk wearing a green vest and a cardboard sign that says FREE HGS. Arrows point to the duck's spread wings. Overlaid are the words, "When you want to Keep It Simple & Ship, duck typing feels like a free hug."
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 27/10/2025
JavaScript Allongé follows this pattern: raganwald.com/assets/books/javascri… The very first version was written before ES2015. Its purpose was to discuss programming with first-class functions and composition. To do that, it had to […] [Original post on functional.cafe]
Cover of "JavaScript Allongé" featuring a small white dairy jug, a white espresso cup on a black saucer, and a spoon.Cover of "JavaScript Allongé, The Six Edition" featuring a small white dairy jug, a white espresso cup on a black saucer, and a spoon.
100 1
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 13/08/2025
A long time ago, in a ruby-encrusted galaxy far, far away... raganwald.com/assets/books/kestrels…
A brass-toned mechanism featuring concentric gears is overlaid with the words "Kestrels, Quirky Birds, & Hopeless Egocentricity"
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 04/08/2025
My first type-level TypeScript Y Combinator good enough to criticize: gist.github.com/raganwald/6558ddfd7…
// ---------- The Why Bird as an HKT ----------
//
// This is a nearly direct translation of a JS
// implementation from "Why Y? Deriving the
// Y Combinator in JavaScript:"
//
// https://raganwald.com/2018/09/10/why-y.html
//
// const Y =
//   fn =>
//     M(m => a => fn(m(m))(a));

// A kind that encapsulates the "maker" function within the Why Brd
type _$Maker<FN extends HigherOrderKind, M extends HigherOrderKind, A> =
  $< FN,_$cast<_$M<M>, _$inputOf<FN>> > extends infer InnerMaker extends Kind.Kind
    ? $< InnerMaker, _$cast<A, _$inputOf<InnerMaker>> >
    : never;

interface Maker_T<FN extends HigherOrderKind, M extends HigherOrderKind> extends Kind.Kind {
  f(
    a: this[Kind._]
  ): _$Maker<FN, M, typeof a>
}

interface Maker<FN extends HigherOrderKind> extends Kind.Kind {
  f(
    m: _$cast<this[Kind._], HigherOrderKind>
  ): Maker_T<FN, typeof m>
}

// The Why Bird composes a decoupled recursive kind with itself,
// converting a decoupled recursive kind to a recurive kind
interface Y extends Kind.Kind {
  f(
    fn: _$cast<this[Kind._], Kind.Kind>
  ): _$M<Maker<typeof fn>>
}
001 1
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 04/08/2025
For the tenth time: en.wikipedia.org/wiki/Greenspun%27s…
A man with a coffee cup sits at a table with a banner reading, "All programming is either Lisp or Greenspunning, change my mind."
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 30/07/2025
A type-level TypeScript implementation of the Mockingbird. The Why Bird and Jackson’s Widowbird are next...
  type M<K extends Kind.Kind> = $<K, Type._$cast<K, _$inputOf<K>>>;

  type LastButLast<S extends string, AccumulatedButLast extends string> =
    $N<M<LastButLastKind>, [S, AccumulatedButLast, NewCounter]> extends infer Result
      ? Result extends { type: ContinuationType, parameters: [infer NewS extends string, infer NewAccumulatedButLast extends string] }
        ? LastButLast<NewS, NewAccumulatedButLast>
        : Result
      : never;

  type _$LastButLast<K extends LastButLastKind, S extends string, AccumulatedButLast extends string, RecursionCount extends Counter> =
    S extends `${infer Head}${infer ButHead}`
      ? ButHead extends ""
        ? [Head, AccumulatedButLast]
        : Count<RecursionCount> extends RecursionLimit
          ? ContinueWith<[S, AccumulatedButLast]>
          : $N<M<LastButLastKind>, [ButHead, `${AccumulatedButLast}${Head}`, Increment<RecursionCount>]>
      : ["", ""]
012 2
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 26/07/2025
“[Structure and Interpretation of Computer Programs] wasn't really about Scheme; I think a lot of the point of using Scheme (as I understood it) is that the language is so minimalist and so beautiful that even this first intro course can be about fundamental […] [Original post on functional.cafe]
Detail from the cover of "Structure and Interpretation of Computer Programs" by Abelson and Sussman
001 1
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 15/07/2025
The SNOBOL4 Programming Language, also known by its fans as “The Green Book:” raganwald.com/assets/books/snobol-g…
The cover of “The SNOBOL4 Programming Language, second edition.”  It is green, and there are no illustrations.
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 23/06/2025
“...We’re done. And this is a win over the typical recursive or even iterative solution for large numbers, because while each operation is more expensive, we only perform log2n operations.” —An ES6 function to compute the nth Fibonacci number (2015) […] [Original post on functional.cafe]
A nautalis-type spiral created with "whirling squares" of sizes equal to the fibonacci sequence
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 19/06/2025
In 1972, John Horton Conway invented the FRACTRAN programming language to show that a generalization of the Collatz problem is algorithmically undecidable. He showed that this generalized form is equivalent to FRACTRAN programs, and also that FRACTRAN […] [Original post on functional.cafe]
The fractions (7/3, 99,98, 13/49, 36/91, 10/143, 49/13, 7/11, 1/2, 91/1) are displayed as a comma-separated list in parentheses.
010 1
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 09/06/2025
The SNOBOL4 Programming Language, also known by its fans as, “The Green Book:” raganwald.com/assets/books/snobol-g…
The cover of “The SNOBOL4 Programming Language, second edition.”

It is green, and there are no illustrations.
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 06/06/2025
In 2004, Matthew Cook proved that the Rule 110 elementary cellular automaton is universal. His construction began with the existing proof that Post Tag Systems are universal, then introduced a variation, the Cyclic Tag System, which he showed is equivalent to […] [Original post on functional.cafe]
Figure 2 from Cook's paper shows a diagram of a glider system in Rule 110 emulating a cyclic tag system which has a list of two appendants: YYY and N.
001 1
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 31/05/2025
“DNA does not have one strand for animals, another for cats, and a third for jaguars. It does not compose these specializations together to produce the final specimen individual. DNA is a chaotic, unstructured mess. Einstein once said that “God does not play […] [Original post on functional.cafe]
another way forward

There is another way forward. What if objects exist as encapsulations, and the communicate via messages? What if code re-use has nothing to do with inheritance, but uses composition, delegation, even old-fashioned helper objects or any technique the programmer deems fit? The ontology does not go away, but it is decoupled from the implementation. Here’s how.
010 1
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 29/05/2025
👆🏽 “A “purely functional” approach to composing functionality is appropriate when we wish to compose behaviour with classes, but do not wish to mutate a class that is used elsewhere. One approach is to extend the class into a subclass, and mix behaviour into […] [Original post on functional.cafe]
Four coffee cups, each with  different fancy coffee drink
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 29/05/2025
👆🏽 “As a general rule, it’s best to have things behave as similarly as possible in the domain code, and this sometimes does involve some extra complexity in the infrastructure code. But that is more of a guideline than a hard-and-fast rule, and for this […] [Original post on functional.cafe]
A black and white picture of milk being frothed in a metal jug by an espresso machine's steam wand
101 1
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 29/05/2025
“Prototypes in JavaScript are “just objects,” and since they are “just objects,” we can add, remove, or modify methods of the prototype by adding, removing, or modifying the functions bound to properties of the prototype.” —Prototypes are Objects (and why […] [Original post on functional.cafe]
const BookCollector = {
  addToCollection (name) {
    this.collection().push(name);
    return this;
  },
  collection () {
    return this._collected_books || (this._collected_books = []);
  }
};

class Person {
  constructor (first, last) {
    this.rename(first, last);
  }
  fullName () {
    return this.firstName + " " + this.lastName;
  }
  rename (first, last) {
    this.firstName = first;
    this.lastName = last;
    return this;
  }
};

Object.assign(Person.prototype, BookCollector);
100 1
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 28/05/2025
“CoffeeScript Ristretto (2014) is a book about programming with functions that uses the CoffeeScript programming language for the examples and exercises. “CoffeeScript Ristretto's primary focus is functions as first-class values and advanced topics built on […] [Original post on functional.cafe]
cover of CoffeeScript Ristretto featuring a piston actuated espresso machine
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 25/05/2025
“The command pattern was popularized by the 1994 book Design Patterns: Elements of Reusable Object-Oriented Software. But it’s 2016. Why do we care? Why is it worth another look?” —The annotated presentation of “First-Class Commands, an unexpectedly fertile […] [Original post on functional.cafe]
Portraits of Alice B. Toklas, Bob Fosse, and Carol O’Connor appear under the words “alice, bob, and carol” and over the words “Alice, Bob, and Carol are writing a screenplay.”
000 0
raganwald.com @raganwald.functional.cafe.ap.brid.gy · 20/05/2025
Why Y? Deriving the Y Combinator in JavaScript (2018) “After a brief review of the work we’ve already done on the Mockingbird, we’ll derive the Why Bird, known most famously as the Y Combinator. The why bird provides all the benefits of the mockingbird, but […] [Original post on functional.cafe]
A long-tailed widow bird rests on a bush in long grass. It is mostly black, but has  red and white shoulder flashes, and as named, long tail feathers.
000 0