HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
tromp
AIT
Haskell2016–2026
tromp / AIT

AIT

Algorithmic Information Theory, using Binary Lambda Calculus

3Distinct people
27Mentions
1Explicit recommenders
217GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Algorithmic Information Theory, using Binary Lambda Calculus

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

My favorite prime number generator is ┬─┬───────────────────────────────────┬──── ────┬ │ │ ┬─┬ ────┬─┬────────────────────── ┼───┬ ┬───┼ │ │ └─┤ ────┼─┼───────────────────┬──…

tromp used a recommendation phrase. One indexed comment matches. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

No other repository is repeatedly linked in the same discussions.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:56:07 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year27 dated mentions

Observed mentions: 2016-05-04 22:25:39 UTC to 2026-09-30 07:20:15 UTC.

02462016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments20162017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments20212022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 7 mentions; 0 submissions, 7 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 5 mentions; 0 submissions, 5 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC202
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC000
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC000
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC000
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC000
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC303
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC404
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC202
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC404
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC707
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC505

What Hacker News says

27 sources
One of the smallest implementations is my heavily obfuscated https://www.ioccc.org/2012/tromp/ : Int L[A],m,b,*D=A, *c,*a=L,C,*U=L,u;s (_){u--&&s(a=*a);} char*B,I,O;S(){b=b --?b:m|read(0,&I,1 )-1;return~I>>b&1; }k(l,u){for(;l<=u; U-L<A?*U++=46^l++[ "-,&,,/.--/,:-,'/" ".-,-,,/.-,*,//..," ]:exit(5));}p(Int*m){ return!*U?*m=S()?U++,!S ()?m[1]=p(++U),2:3:1,p(U) :S()?U+=2:p(U[1]++),U-m;}x( c){k(7*!b,9);*U++=b&&S();c&&x (b);}d(Int*l){--l[1]||d(l[d(*l), *l=B,B=l,2]);}main(e){for(k(10,33 ),a[4]-=m=e-2&7,a[23]=p(U),b=0;;e-2 ?e?e-3?s(D=a),C=a [3],++1[a=a[2]],d( D)
Read the rest
:c?D=c,c=*D,*D= a,a=D:exit(L[C+1]) :C--<23?C=u+m&1?O =O+O|C&1,9:write(m ||(O=C+28),&O,1)+ 1:(S(),x(0<b++?k(0, 6),U[-5]=96:0)):( D=B?B:calloc(4,X)) ?B=*D,*D=c,c=D,D[ 2]=a,a[++D[1]]++,D [3]=++C+u:exit(6) )e=L[C++],u=L[C];} while a less obfuscated and highly performant implementation https://github.com/tromp/AIT/blob/master/uni.c based on combinatory graph reduction takes 446 lines.
In 7 lines of code, 3 minutes: Implement a programming language (2010)
> Alonzo Church developed the lambda calculus in 1929. His first publication that showed the elements of the lambda calculus was the 1932 paper "A set of postulates for the foundation of logic", as I cited in my recent paper [1]. It's quite possible he worked on it prior to 1932, but I don't know of any credible evidence on that (would be very interested to learn about any). > Wait! How the heck is this a "programming" language? > At first glance, this simple language seems to lack both recursion and iteration, not to mention numbers, booleans, conditionals, data structures and all the rest. How can this language possibly be general-purpose? What most stops lambda calculus from being a programming language is that it doesn't directly support I/O. However, one can adopt some very simple conventions for representing bits, lists of bits (byt
Read the rest
es), and lists of bytes, and for letting a lambda term operate on these [2] which make the so-called Binary Lambda Calculus (BLC) a programming language. And a very expressive language it is too: a BLC self interpreter [4] can be as small as the 170-bits 01000110100001000 00001100000010111 00110000111111100 00101110011111110 00000111100000010 11101110011011110 01111111100001111 11110000101111010 01110100101111101 00101101010011010 which encodes the term (λ11)(λ(λλλ1(λλ2(1(λ6(λ2(6(λλ3(λλ23(14))))(7(λ7(λ31(21)))))))(41(111))))(11)) in De Bruijn notatation, with lambda diagram [3] ┬─┬ ────────────────────────────────────────────┬─┬ └─┤ ──────┬───────────────┬──────────────────── ├─┘ │ ──────┼───┬───────────┼─┬─────────┬──────── │ │ ┬─────┼───┼───────────┼─┼─────────┼──────── │ │ │ ┬───┼───┼───────────┼─┼─────────┼──────── │ │ │ ┼─┬─┼───┼───────────┼─┼─────────┼─┬─┬─┬─┬ │ │ │ │ │ ┼─┬─┼───────────┼─┼──────── └─┤ └─┤ │ │ │ │ │ │ │ ┼─┼─┬─────────┼─┼─┬────── │ ├─┘ │ │ │ │ │ │ │ │ ┼───────┬ │ ┼─┼───┬── ├───┘ │ │ │ │ │ │ │ │ ┼───┬───┼ │ │ ┼─┬─┼─┬ │ │ │ │ │ │ │ │ │ │ ┬─┼───┼ │ │ └─┤ ├─┘ │ │ │ │ │ │ │ │ │ │ ┼─┼─┬─┼ │ │ ├─┘ │ │ │ │ │ │ │ │ │ │ └─┤ ├─┘ │ ├───┘ │ │ │ │ │ │ │ │ │ │ ├─┘ ├─┘ │ │ │ │ │ │ │ │ │ ├───┘ │ │ │ │ │ │ │ │ │ ├─┘ │ │ │ │ │ │ │ │ └─┤ │ │ │ │ │ │ │ │ ├───────────┘ │ │ │ │ │ │ ├───┘ │ │ │ │ │ ├─┘ │ │ │ │ └─┤ │ │ │ │ ├───────────────────────────────┘ │ │ └───┤ │ │ ├───────────────────────────────────────┘ └─────┘ 10 times smaller than the 7 lines of R5RS Scheme (define (eval e env) (cond ((symbol? e) (cadr (assq e env))) ((eq? (car e) 'λ) (cons e env)) (else (apply (eval (car e) env) (eval (cadr e) env))))) (define (apply f x) (eval (cddr (car f)) (cons (list (cadr (car f)) x) (cdr f)))) (display (eval (read) '())) (newline) > This code will read a program from stdin, parse it, evaluate it and print the result. Except that it leaves all the actual parsing to the "read" library function. In contrast, the BLC code does all parsing itself. One of the neatest tricks is how it represents the environment as a list built with cons' = \x\y\zx\zy. zx x (zy y) which allows a list of bits like "1110" (the code for de Bruijn index 3) to index the environment by simply applying it to the environment. [1] https://www.mdpi.com/1099-4300/28/5/494 "The Largest Number Representable in 64 Bits" [2] https://gist.github.com/tromp/86b3184f852f65bfb814e3ab0987d8... [3] https://tromp.github.io/cl/diagrams.html [4] https://github.com/tromp/AIT/blob/master/ait/int.lam
In 7 lines of code, 3 minutes: Implement a programming language (2010)
The closely related function Col' which also divides 3n+1 by 2 in the odd case, is concisely represented by the 65-bit lambda calculus term λ1(λλλ31(λλ2(421)))(λλ1)1(λλ1) operating on Church numerals [1]. It starts from the pair of numbers n and 0 and then performs n iterations of swapping the numbers after incrementing the first. Its lambda diagram is ┬───────────────┬── │ ┬────────── ─ │ ─ │ ┼─────┬──── ┬ │ ┬ │ ┼─┬───┼──── │ │ │ │ └─┤ ┬─┼─┬── │ │ │ │ │ ┼─┼─┼─┬ │ │ │ │ │ │ └─┤ │ │ │ │ │ │ │ ├─┘ │ │ │ │ │ ├───┘ │ │ │ │ ├─┘ │ │ │ └───┤ │ │ │ └─────────┤ │ │ └─┤ │ └─┘ [1] https://github.com/tromp/AIT/blob/master/fast_growing_and_co...
In Almost all Collatz orbits attain almost bounded values
> Christopher Wadsworth analyzed different properties of numeral systems and the requirements they have to fulfill to be useful for arithmetic. > Specifically, he calls a numeral system adequate if it allows for a successor (succ) function, predecessor (pred) function, and a zero? function yielding a true (false) encoding when a number is zero (or not). A numeral system is adequate iff it can be converted to and from Church numerals. Converting from Church numerals requires functions N0 and Nsucc so that Church2Num c = c Nsucc N0 while converting to Church numerals requires functions Nzero? and Npred so that Num2Church n = Nzero? n C0 (Csucc (Num2Church (Npred n))) with an implicit use of the fixpoint combinator. An interesting adequate numeral system is what i call the tuple numerals [1], which are simply iterates of the 1-tupl
Read the rest
e function T = λxλy.y x So N0 = id, Nsucc = λnλx.n (T x), Npred = λnλx.n x id, and Nzero? = λnλtλf. n (K t) (K f). These tuple numerals are useful in proving lower bounds on a functional busy beaver [2]. [1] https://github.com/tromp/AIT/blob/master/numerals/tuple_nume... [2] https://oeis.org/A333479 (see bms.lam link)
In De Bruijn Numerals
let A = (x) => (y) => (z) => x(z)(y((w) => z)) Just need to combine this a few times. let K = A(A(A))(A(A(A))(A)(A)(A)(A)(A); // (x) => (y) => x let S = A(A(A(A)(A(A)(A(A)))(A(A(A(A)((A(A)))))))(A)(A); // (x) => (y) => (z) => x(z)(y(z)) > “I would never be caught dead using Lambda calculus. It’s a bloated language.” Actually, combinatory logic is more bloated than lambda calculus, generally needing more bits to express the same program [1]. One can argue that lambda calculus is one of the most concise languages ever [2]. > Dana smirks. “Well, yeah. JavaScript is an eager language. Can’t use the Y combinator.” Eager languages can be made lazy by wrapping arguments in lambdas with dummy arguments, as done in the Javascript BLC interpreter [3]. [1] https://tromp.github.io/cl/LC.pdf [2] https://www.ioccc.org/2012/tromp/ [3] https:/
Read the rest
In Programming with Less Than Nothing
This is a great introduction to that most ancient and elegant model of computation. But I was a little sad to read: > One can represent natural numbers in a simple way, as follows: > Definition (ordered tuples, natural numbers) The ordered tuple ⟨a0 , … an⟩ of λ-terms is defined as λx [x a0 … an]. One then defines the λ -term ┌ n ┐ corresponding to the natural number n as: ┌ 0 ┐ = I and, for every k, ┌ k + 1 ┐ = ⟨F, ┌ k ┐⟩ which is a rather convoluted and impractical way to represent natural numbers compared to the Church numerals Cn which iterate a given function n times on a giving argument. There are cases where it makes sense to use tuples to represent natural numbers, namely to simplify the definition of predecessor, subtraction, and comparison. But that uses 1-tuples rather than 2-tuples [1]. Replacing Church numerals by tuple numer
Read the rest
als allowed a googologically VERY large number (based on the so-called Bashicu Matrix System) to be expressed in only 350 bits rather than 404 bits. [2] [1] https://github.com/tromp/AIT/blob/master/numerals/tuple_nume... [2] https://github.com/tromp/AIT/blob/master/fast_growing_and_co...
In The Lambda Calculus (2023)
It's not strange at all. I am playing with lambda calculus and combinatory logic now, as a base for mathematics (my interest is to understand rigorous thinking). You can express any computation using just S and K combinators, however, there is a price to that - the computations will be rather slow. So to make the computation faster, we can use additional combinators and rules to speed things up (good example is clapp() function in https://github.com/tromp/AIT/blob/master/uni.c). Of course, the extra rules have to be logically consistent with the base S and K combinators, otherwise you will get wrong result. But if the inconsistent rule is complicated enough to be used only infrequently, you will still get correct result most of the time. Which brings me to LLMs and transformers. I posit that transformers are essentially learned systems of
Read the rest
rules that are applied to somewhat fuzzily known set of combinators (programs), each represented by a token (the term being represented by the embedding vector). However, the rules learned are not necessarily consistent (as it happens in the source data), so you get an occasional logical error (I don't want to call it hallucination because it's a different phenomenon from nondeterminism and extrapolation of LLMs). This explains the collapse from the famous paper: https://ml-site.cdn-apple.com/papers/the-illusion-of-thinkin... One infrequent but inconsistent rule is enough to poison the well due to logical principle of explosion. It also clearly cannot be completely fixed with more training data. (There is also analogy to Terry Tao's stages of mathematical thinking: https://terrytao.wordpress.com/career-advice/theres-more-to-... Pre-rigorous corresponds to soomewhat random set of likely inconsistent logical rules, rigorous to small set of obviously consistent rules, like only S and K, and post-rigorous to a large set of rules that have been vetted for consistency.) What is the "solution" to this? Well, I think during training you somehow need to make sure that the transformer rules learned by the LLM are logically consistent for the strictly logical fragment of the human language that is relevant to logical and programming problems. Which is admittedly not an easy task (I doubt it's even possible within NN framework).
In The bitter lesson is coming for tokenization
Last year I ported Loader's construction to Haskell [2] in order to better understand it, and managed to shrink the code down to under 232 bytes [1]. That work was also featured in a video that youtuber CodeParade made about the Quest To Find The Largest Number and its followup [3]. [1] https://github.com/tromp/AIT/blob/master/fast_growing_and_co... [2] https://codegolf.stackexchange.com/questions/176966/golf-a-n... [3] https://www.youtube.com/watch?v=kQLcoSuMKHg&t=10s
In Loader's Number
AFAIK there are many variations (I think infinite, even) of "tree calculi". You can build one easily from combinatory logic by using only one universal combinator, which will be implied at the leafs of the tree. John Tromp in his repo has some research pertaining to short universal lambda expressions (each can be expressed as combinators) of this type: https://github.com/tromp/AIT/blob/master/Bases.lhs
In Tree Calculus

Showing the 15 most recent of 27 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.