Skip to the code
cf.

Partial application

MediumFunctions

Write partial(fn, ...presetArgs). It returns a function that calls fn with the preset arguments followed by the new ones, and returns the result. The caller's this is passed on to fn.

partial.placeholder (defined in the starter) leaves a gap. Each preset that is the placeholder is filled with the next new argument, in order, and the new arguments that are left go at the end. A placeholder with no new argument left to fill it becomes undefined. The returned function can be called any number of times.

const greet = (greeting, name, mark) => greeting + ", " + name + mark;
partial(greet, "Hi")("Ada", "!"); // "Hi, Ada!"
 
const _ = partial.placeholder;
const askAda = partial(greet, _, "Ada", "?");
askAda("Hello"); // "Hello, Ada?"
askAda("Hey");   // "Hey, Ada?"

What the tests check

  1. puts the preset arguments before the new ones
    expect(partial((a, b, c) => [a, b, c], 1, 2)(3)).toEqual([1, 2, 3]);
    expect(partial((a, b, c) => [a, b, c], 1)(2, 3)).toEqual([1, 2, 3]);
    
  2. works with every argument preset, or none
    expect(partial((a, b) => a + b, 2, 3)()).toBe(5);
    expect(partial((a, b) => a + b)(2, 3)).toBe(5);
    
  3. fills placeholders with the new arguments, in order
    const _ = partial.placeholder;
    expect(partial((a, b, c) => [a, b, c], _, 2, _)(1, 3)).toEqual([1, 2, 3]);
    
  4. appends the new arguments left after filling placeholders
    const _ = partial.placeholder;
    expect(partial((...args) => args, _, "b")("a", "c", "d")).toEqual(["a", "b", "c", "d"]);
    
  5. an unfilled placeholder becomes undefined
    const _ = partial.placeholder;
    expect(partial((...args) => args, 1, _, 3)()).toEqual([1, undefined, 3]);
    
  6. keeps the caller's this
    const obj = {
      base: 10,
      add: partial(function (a, b) {
        return this.base + a + b;
      }, 1),
    };
    expect(obj.add(2)).toBe(13);
    
  7. can be called again with new arguments
    const _ = partial.placeholder;
    const greet = (greeting, name) => greeting + ", " + name;
    const greetAda = partial(greet, _, "Ada");
    expect(greetAda("Hello")).toBe("Hello, Ada");
    expect(greetAda("Hey")).toBe("Hey, Ada");
    

Learn more

solution.jsSaved in this browser

Run tests runs every test on your code, here in your browser. The problem is solved when they all pass.

Ctrl + Enter runs the tests (⌘ + Enter on a Mac).