Last active
September 28, 2017 13:10
-
-
Save kenbellows/4bdd2070622b1c7367ebb27b78c83950 to your computer and use it in GitHub Desktop.
A JavaScript implementation of Boolean logic in the Lambda calculus
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Implementing Boolean Logic in the Lambda Calculus: A JavaScript Demo | |
* | |
* (Inspiration: https://youtu.be/eis11j_iGMs) | |
* | |
* It turns out that it's entirely possible in the lambda calculus to define | |
* the Boolean values TRUE and FALSE in functional terms as lambdas, which | |
* is pretty cool. | |
* | |
* Once you've done that, it's also possible to define the Boolean operators as | |
* functions that take the Boolean lambdas and apply them to themselves, which | |
* is also pretty cool. | |
* | |
* This is a quick demo of that. Below you will find lambda definitions for | |
* TRUE and FALSE, as well as the standard Boolean operators NOT, AND, OR, | |
* XOR, NAND, and NOR. Below the definitions is some code to print out truth | |
* tables for these values to demonstrate that they work. | |
* | |
* It's lambda calculus + Boolean logic + ES6 arrow functions! What more could | |
* you ask?! | |
*/ | |
// Define the lambdas | |
const | |
// Booleans | |
TRUE = (a,b) => a, | |
FALSE = (a,b) => b, | |
// Logical operators | |
NOT = (b) => b(FALSE, TRUE), | |
AND = (a,b) => a(b(TRUE, FALSE), FALSE), | |
OR = (a,b) => a(TRUE, b(TRUE, FALSE)), | |
XOR = (a,b) => a(NOT(b), b), | |
NAND = (a,b) => NOT(AND(a,b)), | |
NOR = (a,b) => NOT(OR(a, b)) | |
; | |
/* logging utilities */ | |
// pad a string to five chars (because FALSE, the longest lambda, is 5 chars); set leftPad to true for prefix-padding instead of suffix-padding | |
const pad5 = (s, leftPad) => s.length >= 5 ? s : (leftPad ? '':s) + (Array(6-s.length).join(' ')) + (leftPad ? s:''); | |
// given a lambda, return a formatted string for logging | |
const p = (l,leftPad) => pad5(l.name,leftPad) | |
/* Generate some truth tables */ | |
// generate the truth table for NOT separately, since it's the only unary operator | |
console.log(' Input | NOT'); | |
console.log('-------|-------'); | |
console.log(' TRUE |', p(NOT(TRUE))); | |
console.log(' FALSE |', p(NOT(FALSE))); | |
console.log('\n'); | |
// list of the binary operators, for looping convenience | |
let BINARY_OPS = [AND,OR,XOR,NAND,NOR]; | |
// generate the header row | |
let headers = ' Inputs | '+BINARY_OPS.map(op=>p(op)).join(' | '); | |
console.log(headers); | |
console.log('-----------------|'+BINARY_OPS.map(()=> Array(7).join('-')).join('|')); | |
// loop over the four input cases, generating a truth table row for each one | |
[[ TRUE, TRUE ], | |
[ TRUE, FALSE ], | |
[ FALSE, TRUE ], | |
[ FALSE, FALSE ]].forEach(([a,b]) => { | |
console.log( | |
'( %s, %s )',p(a,true),p(b),'|', | |
BINARY_OPS.map(op => p(op(a,b))).join(' | ') | |
); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment