Exercise about closures and function composition

Hello.

After a while I managed to make the function composition work for task 3 of Coordinate Transformation in JavaScript on Exercism

But for some reason my program doesn’t pass tests 10 and 11:
composeTransform > should compose in the correct order: g(f(x))
composeTransform > should compose in the opposite order: f(g(x))

But I have no idea why because my function seems to work when I try it manually, regardless of the order of the composition.
Maybe there’s something I’m not understanding.

Could anybody help me?
Thanks.

The following is my code with my three functions in it:

export function translate2d(dx, dy) {
  let translate = [dx,dy];
  function updateTranslate(a, b) {
    translate[0] = translate[0] + a;
    translate[1] = translate[1] + b;
    return translate;
  }
  return updateTranslate;  
}

/**
 * Create a function that returns a function making use of a closure to
 * perform a repeatable 2d scale of a coordinate pair.
 *
 * @param {number} sx the amount to scale the x component
 * @param {number} sy the amount to scale the y component
 *
 * @returns {function} a function which takes an x, y parameter, returns the
 *  scaled coordinate pair in the form [x, y]
 */
export function scale2d(sx, sy) {
  let scale = [sx, sy];

  function updateScale(a, b) {
    scale[0] = scale[0] * a;
    scale[1] = scale[1] * b;
    return scale;
  }
  return updateScale;
}

/**
 * Create a composition function that returns a function that combines two
 * functions to perform a repeatable transformation
 *
 * @param {function} f the first function to apply
 * @param {function} g the second function to apply
 *
 * @returns {function} a function which takes an x, y parameter, returns the
 *  transformed coordinate pair in the form [x, y]
 */
export function composeTransform(f, g) {
  /**let firstTransform = f;
  let secondTransform = g;**/
  
  function performComposition(a, b) {
    /**let firstStep = f(a,b);
    let result = g(f(a,b)[0], f(a,b)[1])**/
    return g(f(a,b)[0], f(a,b)[1]);
  }
  return performComposition;
}

Did you try two different functions, so that their combined output is different depending on the composition order?

When stuck, it often helps to look at the tests’ code: javascript/exercises/concept/coordinate-transformation/coordinate-transformation.spec.js at main · exercism/javascript · GitHub.

1 Like

In function translate2d there’s a translate variable that points to an array. The updateTranslate changes the array. What does this mean about the results if you call the closure A) 1 time B) >1 times.

1 Like

Thank you very much.

I had a similar issue with an array in a different exercise.

I change the code so the original array isn’t modified and now it passed the tests.

I think I misunderstood what the function should do because I thought the scaling and translating effects should be composable, that is, if I apply one of them, it should be applied on the already existing transformation (the one that came before), but apparently that’s not what it’s supposed to do.

I edit again because after a second reading I realized the pair of arguments that are passed to the closure are the coordinates you want to transform while I understood they should be a new transformation that would transform the previous transformation.
Now everything makes sense.

Thanks.

This will be useful for me in case I want to try some inputs manually in the future.