Skip to content

Instantly share code, notes, and snippets.

View lqt0223's full-sized avatar

lqt0223 lqt0223

  • Shanghai, China
View GitHub Profile
@lqt0223
lqt0223 / promise.js
Last active April 12, 2024 12:23
42. A promise implementation that is A+ conformant
// (Tested on Node.js 18.15.0) A promise implementation that is A+ conformant
// To implement something promise-ish (ignoring all edge-cases from A+ spec), there are some guidelines below:
// - manage the state of promise object, to avoid transition between two settled state
// - use 'then' method to store callbacks for resolving / rejecting the promise.
// - implement 3 kinds of chaining behaviors of a promise
// - when resolving a promise, recursively unwrap until a non-thenable value is found
// - a promise can invoke then (to add callbacks) multiple times. When the promise is settled, all cbs should be invoked sequentially
// - the propagation of promise chain
// warn: this does not check if val.then is a function
@lqt0223
lqt0223 / co.js
Created November 18, 2023 09:36
41 async-await style in generator
function apiReq(result, delay) {
return new Promise(resolve => {
setTimeout(() => {
resolve(result)
}, delay*1000)
})
}
// the generator function version of async-await programming scheme
// function* -> async
@lqt0223
lqt0223 / parse.js
Created November 16, 2023 06:38
40 parsing LISP like expression
/*
* a function that parses LISP like expression into AST
* the CFG will be like
* C = ( op args ) --- an expression is enclosed in a parenthesis, with 'op' as head, and 'args' as tail
* args = arg* --- an args (argument list) contains zero or variadic-length arguments
* arg => num | C --- an arg is either a num or an expression
* op = +|-|*|/
* num = [0-9]*
*/
const parse = function(s) {
@lqt0223
lqt0223 / curry.js
Created July 7, 2023 12:18
39 currying
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.call(this, ...args)
} else {
return curried.bind(this, ...args)
}
}
}
@lqt0223
lqt0223 / co.js
Created July 7, 2023 12:16
38 a simple co(async generator function runner)
function sleep(ms, message) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(message)
}, ms)
})
}
function co(fn) {
const generator = fn()
@lqt0223
lqt0223 / matrix.vert
Created June 13, 2019 03:37
37 perspective, view matrix derivation in vertex shader program
uniform mat4 u_modelMatrix;
uniform vec2 u_resolution;
uniform vec3 u_camera;
attribute vec4 a_position;
varying vec4 v_position;
attribute vec4 a_color;
varying vec4 v_color;
attribute vec3 a_normal;
varying vec3 v_normal;
@lqt0223
lqt0223 / latlon.md
Last active May 10, 2018 01:14
36 the haversine function and distance between locations

Deriving the Haversine Formula

The haversine formula is useful in calculating the distance between two locations on the Earth, when the latitudes & longitudes of the two locations are provided.

An implementation of calcDistance function based on haversine formula in JavaScript is as follows: (the degToRad function is solely a unit converter)

function degToRad(degrees) {
  return degrees * Math.PI / 180;
}
@lqt0223
lqt0223 / adder.js
Created April 28, 2018 10:02
35 binary adder
// a half-adder takes 2 binary bits as input, and return as result the sum and carry flag
function halfAdder(a, b) {
// the sum is 0 when two bits are the same (1 + 1 or 0 + 0)
var s = a ^ b
// the carry flag is set when 1 + 1
// the bitwise expression !(a ^ b) is for testing equality between a and b
var c = !(a ^ 1) && (!a ^ b)
return [c, s]
}
@lqt0223
lqt0223 / p&c.js
Last active April 19, 2018 16:10
34 a more declarative permutation & combination
// a more declarative algorithm for finding permutations & combinations of a sequence
// first, we introduce a higher-order fuction: flat-map
// it works like map, but will flatten the result by one level (only one level, not recursive)
// ex.
// - map the procedure (x) => [x, 2 * x] onto array [1, 2, 3] will produce
// a 2-dimensional array [[1, 2], [2, 4], [3, 6]]
// - instead, flat-map the procedure (x) => [x, 2 * x] onto array [1, 2, 3] will produce
// a flattened 1-dimensional array [1, 2, 2, 4, 3, 6]
function flatMap(arr, proc) {
@lqt0223
lqt0223 / pm.js
Last active April 8, 2018 11:05
33 pattern matching in a recursive style
/*
pattern matching
- a pattern is an expression with variables
- a datum is another expression to be tested if it matches the provided pattern
- a dictionary is a data-structure used to record and test bindings between
variables in pattern and values in datum
a pattern matching procedure takes a pattern, a datum for testing and a dictionary as input
- if the datum matches the pattern, the procedure will output an extended dictionary with
the new bindings