Skip to content

Instantly share code, notes, and snippets.

View peter-leonov's full-sized avatar

Peter Leonov peter-leonov

View GitHub Profile
@peter-leonov
peter-leonov / promise_monad.md
Created January 14, 2018 19:52 — forked from VictorTaelin/promise_monad.md
async/await is just the do-notation of the Promise monad

async/await is just the do-notation of the Promise monad

CertSimple just wrote a blog post arguing ES2017's async/await was the best thing to happen with JavaScript. I wholeheartedly agree.

In short, one of the (few?) good things about JavaScript used to be how well it handled asynchronous requests. This was mostly thanks to its Scheme-inherited implementation of functions and closures. That, though, was also one of its worst faults, because it led to the "callback hell", an seemingly unavoidable pattern that made highly asynchronous JS code almost unreadable. Many solutions attempted to solve that, but most failed. Promises almost did it, but failed too. Finally, async/await is here and, combined with Promises, it solves the problem for good. On this post, I'll explain why that is the case and trace a link between promises, async/await, the do-notation and monads.

First, let's illustrate the 3 styles by implementing

@peter-leonov
peter-leonov / lazy-list.js
Created May 21, 2017 21:07 — forked from gvergnaud/lazy-list.js
Lazy List, implemented with es6 generators
/* ----------------------------------------- *
Lazy List Implementation
* ----------------------------------------- */
// Haskell-like infinite List, implemented with es6 generators
// Lazyness lets you do crazy stuff like
List.range(0, Infinity)
.drop(1000)
.map(n => -n)
@peter-leonov
peter-leonov / base64.js
Created July 26, 2020 13:45
Simple not-byte-precise base64 encoder
const CODE_A = "A".charCodeAt(0);
const CODE_a = "a".charCodeAt(0);
const CODE_0 = "0".charCodeAt(0);
const CODE_p = "+".charCodeAt(0);
const CODE_s = "/".charCodeAt(0);
// Dear v8, inline this please
const toA = (n) =>
n === 63
? CODE_s
@peter-leonov
peter-leonov / ast.js
Last active April 29, 2020 21:54
Naive micro JS parser (with parser <-> lexer connection)
foo / 1 + 2 * 3 + 4 ; bar = /rex1/ /* bla-bla */ / /rex2/
// gives this naive AST
({
type: 'program',
body: [
{
type: 'statement',
body: {
type: 'expression',
@peter-leonov
peter-leonov / closure.js
Created April 20, 2020 18:18
Primitive closure implementation in JS to illustrate that closure is "just" an object
class RootScope {
constructor() {
this.map = new Map();
}
add(name, value) {
return this.map.set(name, value);
}
set(name, value) {
@peter-leonov
peter-leonov / stream.js
Last active April 13, 2020 08:39
Array<Promise<T>> -> AsyncIterator<T>
async function main() {
async function f1() {
return new Promise((res) => {
setTimeout(() => {
res("1.1");
}, 1000);
});
}
async function f2() {
@peter-leonov
peter-leonov / naive-event-loop.js
Last active April 6, 2020 18:25
Pure JS event loop implementation with only timers working
// timer.js
function main(global) {
global.mySetTimeout(function () {
console.log("500ms");
}, 500);
global.mySetTimeout(function () {
console.log("100ms");
}, 100);
const { openSync, readSync } = require('fs')
const DEV_RANDOM = openSync('/dev/random')
function getVeryRandomString(length) {
const buf = Buffer.alloc(length)
readSync(DEV_RANDOM, buf, 0, length)
return buf.toString()
}
@peter-leonov
peter-leonov / async.js
Created February 16, 2020 21:49
Re-implementing a simple (but with a whole for loop!) async function as a generator and as a co-routine for fun
// lib
const sleep = t => new Promise(res => setTimeout(res, t));
const getRandom = () => sleep(100).then(() => Math.random());
// native solution
async function getRandomsNative(count) {
await sleep(100);
const randoms = [];
@peter-leonov
peter-leonov / bomb.sh
Last active November 22, 2019 03:46
docker fork bomb
docker run ruby ruby -e 'loop { fork { fork { sleep 0.1 } } }'