Posted on Sep 23 Propositions as types correspondance (PAT) (or Types as Propositions) is one of the most intriguing discoveries of Computer Science. The gist of it is:The correspondance is basically saying Logic and Programming are two sides of the same coin:It's as if we were writing let x: P = proof; in TypeScript. And it's not just some quirky coincidence. If we restrict ourself to a pure subset TypeScript, you'll see you can write logical proofs using code.First let's review quickly the key concepts in Logic, they work pretty much like the booleans we use in programming:There's also A B. It's essentially stating that A implies B and B implies A. In other words, (A -> B) ∧ (B -> A). Now for each one of the above constructs we have an equivalent type in Typescript.True corresponds to any inhabitated typeWe could use a singleton type like null or undefined. But with the unknown type, we can assign any value to it.False translates to an uninhabited type in TypeScript. This mirrors the fact that there's no proof for a false proposition in Logic:A ∨ B corresponds to a discriminated union type in TypeScript.We'll also write two constructor functions:And a helper for case analysis:A ∧ B corresponds to a pair of types:Logical implications translate to Function types:Finally, The equivalence A B corresponds to a pair of 2 functions. It's a sort of 2-way conversion between A and BSo far, everything's been kinda familiar, right? But with negation, things are getting a bit wild.Let's start by unpacking the meaning of False/never. The never type acts as a universal subtype, as it can be assigned to any other type.You might wonder about the meaning of any here. Intriguingly, any stands as a proposition that is both True and False at once. This duality allows any value to be assigned to it, making it akin to unknown or True. On the flip side, it can fit into any type (except never), reflecting the nature of never or False.In logical discourse, a proposition that holds as true and false simultaneously is labeled a contradiction. If one can prove a contradiction, the whole logic system just falls apart. In a parallel sense, being able to produce terms of type any compromises the soundness of the type system. As highlighted in the TypeScript documentation, the flexibility of any sacrifices type safety. This brings us to the concept of Proof by contradiction: To disprove a proposition A (or to assert !A), one assumes A is true and then demonstrates that this assumption leads to a contradiction.. In essence, !A equates to A -> False.Hence, negating a type A in TypeScript translates to the function (x: A) => never.Constructing a term of type A -> never poses challenges though. How can we return a never value when, by definition, never lacks any values?One way to produce a negative type in Typescript is by writing a non terminating function. For example:Typesript detects that the function never terminates and assigns to it a type of (a: A) => never. (There are alternative methods to create functions that don't return, but remember we're operating within a limited TypeScript subset here).Is this type designation genuinely accurate from a logical standpoint?Consider the following functionA closer look at the type reveals it corresponds to Not