How to simulate let expressions in JavaScript?

后端 未结 2 837
感动是毒
感动是毒 2020-12-21 17:06

Consider the following implementation of take:

相关标签:
2条回答
  • 2020-12-21 17:38

    Instead of using an IIFE just use a normal function with a proper name to make things more explicit:

    const _let = f =>
      f();
    
    const collateBy = f => xs =>
      xs.reduce((m, x) =>
        _let((r = f(x), ys = m.get(r) || []) =>
          m.set(r, (ys.push(x), ys))), new Map());
    
    const includes = t => s =>
      s.includes(t);
    
    xs = ["Dev", "Jeff", "Kalib", "Amy", "Gemma"];
    
    const collation = collateBy(includes("e")) (xs);
    
    console.log(collation.get(true));
    console.log(collation.get(false));

    0 讨论(0)
  • 2020-12-21 17:41

    In Lisp, a let expression is just syntactic sugar for a left-left lambda (i.e. an immediately-invoked function expression). For example, consider:

    (let ([x 1]
          [y 2])
      (+ x y))
    
    ; This is syntactic sugar for:
    
    ((lambda (x y)
        (+ x y))
      1 2)
    

    In ES6, we can use arrow functions and default parameters to create an IIFE that looks like a let expression as follows:

    const z = ((x = 1, y = 2) => x + y)();
    
    console.log(z);

    Using this hack, we can define take as follows:

    const take = (n, xxs) =>
        n === 0 || xxs.length === 0 ?
        [] : (([x, ...xs] = xxs) => [x, ...take(n - 1, xs)])();
    
    console.log(take(7, [1, 2, 3, 4, 5])); // [1, 2, 3, 4, 5]
    console.log(take(3, [1, 2, 3, 4, 5])); // [1, 2, 3]
    console.log(take(1, [undefined, 1]));  // [undefined]

    Hope that helps.

    0 讨论(0)
提交回复
热议问题