Skip to content

Instantly share code, notes, and snippets.

View aykutyaman's full-sized avatar

Aykut Yaman aykutyaman

View GitHub Profile
@aykutyaman
aykutyaman / trampoline.js
Created January 24, 2020 15:07
proper tail call with trampoline in javascript
var trampoline = fn => (n) => {
// make sure we call trampoline function only once
var result = fn(n);
while (typeof result === 'function') {
result = result();
}
return result;
/*** FIX ***/
var fix = f => x => f(fix(f))(x);
/*** TRAMPOLINE ***/
const rec = (...args) => ({ rec: true, args });
const ret = x => ({ rec: false, x });
var trampoline = f => (...args) => {
const compose = (...args) => n => args.reverse().reduce((acc, f) => f(acc), n);
var mapReducer = fn => combineFn => (acc, v) => combineFn(acc, fn(v));
var filterReducer = fn => combineFn => (acc, v) => fn(v) ? combineFn(acc, v) : acc;
var add1 = n => n + 1;
var isOdd = n => n % 2 === 1;
var sum = (acc, n) => Number(acc) + n;
var list = [1, 3, 4, 6, 9, 12, 13, 16, 21];

inline strings used for app states instead of reusable constants/enums (”Idle”, “Loading”, "Act::Fetch" , etc).

strongly typed approach of the application and the usage of dicriminated union makes using constants unnecessary.

I will discuss it with three examples what I mean.

  1. We can't have silly typos and autocomplete of IDEs will predict them correctly too. So for example if we type "Load" the IDE will autocomplete as "Loading". And when we type something that is not part of the union the compiler will alert us in that spot. Screen shot
  2. If a naming change occurs we are also forced to handle the change. So, it means we don't have the possibility to skip renaming where they are used.
[
{
"dashboard_id":"1",
"items": [
{
"node_id": "x1",
"title": "Pull Requests",
"data": [{
"data": 10,
"date": "2022-01-01"