1

In Javascript, I have seen a code like:

const getSomeMapper = (param1, param2, param3)
    (param4, param5, param6) => {
        // uses all these params and returns a promise
    }

interface MainParamInterface {
    param1: string;
    param2: string;
    param3: string;
}


function entryPoint({param1, param2, param3}: MainParamInterface)
{
    const mapper = getSomeMapper(param1, param2, param3);

    return {
        doSomething: (param4) => {
            return mapper(param4, 'foo', 'bar');
        },
        doSomethingElse: (param4) => {
            return mapper(param4, 'hello', 'world');
        }
    }
}

The main point point for this approach is that, so you only need to define and pass param1, param2, param3 once.

Then after that, you can just worry about param4, example

const magicalObject = entryPoint('hat', 'bunny', 'wand');

magicalObject.doSomething('disappear');
magicalObject.doSomethingElse('light show');

My first concern is that the name of the function getSomeMapper is confusing for me; basically wrong. It makes sense if you use the function the way it was shown in the example, but if you use it this way

getSomeMapper(param1, param2, param3)('disappear')

Already does not look right. So do we have some rule of thumb in regards to naming for this kind of "pattern"? Or maybe some best practice or convention?

Second, is there really a need for this type of higher-order-function? Can't we, and is it better to define each function separately, still call one another in this sequence but atleast easier to follow/understand?

function mapper(mainParams: MainParamInterface, param4, param5, param6)
{
    // or just one function?
}

Please share your opinion/ideas/thoughts.

3

So if we take a step back from JS and look at these types of patterns in other languages (like Java), it would probably be like a Factory that returns an implementation of a specific interface.

interface Mapper {
    void apply(Object param4, Object param5, Object param6);
}

class MapperFactory {

    Mapper createMapper(Object param1, Object param2, Object param3) {
        return new Mapper() {
            @Override
            public void apply(Object param4, Object param5, Object param6) {
                // Your action
            }
        };
    }
}

I like to think about the Java and the JS as the same pattern, with of course the JS version being shorter.

My first concern is that the name of the function getSomeMapper is confusing for me; basically wrong. It makes sense if you use the function the way it was shown in the example, but if you use it this way

Well, yes technically that is more difficult to read, that is why it is advised to assign that function to an intermediate variable.

Second, is there really a need for this type of higher-order-function? Can't we, and is it better to define each function separately, still call one another in this sequence but atleast easier to follow/understand?

It depends. In JS, I think the preferred way might be to use all the params in a single function and then use a library like Ramda for currying the function into separate parts as you wish, unless:

1) You want to calculate an intermediate value once:

const getSomeMapper = (param1, param2, param3) =>
  // Calculate something _once_ ...
  const value = someHeavyCalculation(param1, param3);
(param4, param5, param6) => {
  // ... and use multiple times
  return value + param4 + param5 + param6;
}

2) The returned functions makes sense in itself as an 'interface' (as shown in the earlier Java example).

const isEqual = (comparison: "day" | "month" | "year") => (a: Moment, b: Moment) => {...}
  • Your first JAVA example, I can agree with that. They are technically separate and defined separately themselves. That is what I was referring to (or similar) Can't we, and is it better to define each function separately, still call one another in this sequence but atleast easier to follow/understand? Probably had word it wrongly. Point is that each function/classes are defined elsewhere and we nested it this way. On the other hand, they are all anonymous function. How would I know just by looking. Have to spent a bit of time to fully understand. – Craftein May 8 at 13:39
  • Your first numbered example, I understand if there are in between logic, but that person's reasoning is, as I've mentioned, just so you don't need to keep passing the first 3 params, and no in between logic. Making interface a lot cleaner, less code, etc. – Craftein May 8 at 13:40
  • 1
    If you want to do it just for the sake of cleanness, then you probably need to use them as objects and named parameters. – andras May 8 at 13:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.