1

When writing large amounts of recursive code (for valid reasons), I have come across many parameters that are not used in specific functions, but are still needed for a subset of all of the functions.
IE this situation (a, b & c are numbers):

function fun1(a, b, c) {
    if(a > b) {
        return fun2(a, b, c);
    } else if(b > c) {
        return fun3(a, b, c);
    } else {
        return a;
    }
}

function fun2(a, b, c) {
    return fun1(a + b, a - b, c);
}

function fun3(a, b, c) {
    return fun1(a * c, b, a / c);
}

(I don't actually know if this terminates)

In this example, fun2 never actually uses c, but it still has to require c as a parameter. In fun3, this is the same thing but for b, and fun1 only cares about a.

In this situation, what should be done to reduce the number of parameters down to only the parameters each function needs & not the parameters that get used in other functions?

(When I say not used, I mean passed through)

4

You're contradicting yourself:

1

fun2 never actually uses c

2

function fun2(a, b, c) {
    return fun1(a + b, a - b, c);
}

Passing a parameter counts as using it. You're thinking that it's unused because it just happens to call fun1, at a time when fun1 also happens to be the method which called fun2 in the first place.

But that's not inherently the case.

  • fun2 could be using ADifferentMethod(c) internally
  • fun2 could be called by AnotherCompletelyDifferentMethod()

In either of those cases, your assumption that c is "not used" does not stick.

In this recursive structure, the parent fun1 and the child fun1 should not be labeled as "the same function". They are not. They each have their own separate execution with their own separate scope.

Just like how two separate objects of the same class type are not labeled as "the same object"; two method calls of the same method are not labeled as "the same method" (not in this sense you're trying to use, at least).

  • I mean it fun2 never uses c in a sense that it just gets passed through. The functions I have have ~7 parameters, and 4 of them usually just gets passed through. I am wondering what I should do about that & is there any way to get rid of those 4 pass-through parameters – Yurihaia Sep 24 '18 at 13:03
  • @MrYurihiredstone: You can't, because of what I concluded the answer with: two method calls of the same method are not labeled as "the same method" (in the sense of their variable scope). When you drill down deeper into the call stack, you always have to pass your parameters along. Regardless of whether this is recursion or a deep stack of unique methods. – Flater Sep 24 '18 at 13:05
  • Right. That is what I was thinking. I really don't want to have to have 7 parameters on each method because that is far too many. But I guess I will have to work with it – Yurihaia Sep 24 '18 at 13:06
  • 1
    @MrYurihiredstone: If you're simply looking to shorten the code, how about making a DTO class that holds the needed data, and pass a single instance of that down the call stack? The methods remain functionally equivalent but the signature is shortened. – Flater Sep 24 '18 at 13:07
  • 2
    On what basis do you conclude that seven parameters is too many? If you need seven, then that's how many you have to have. – David Arno Sep 24 '18 at 13:07
1

The common scenario for improving number of parameters is to abstract a portion of them inside a class or structure that makes sense.

For example, we could imagine a, b, and c in a class in your example, and have the following methods (python code):

class MyClass:
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def fun1(self):
        if(self.a > self.b)
            return self.fun2()
        elif(self.b > self.c)
            return self.fun3()
        return self.a

    def fun2(self):
        self.a = self.a + self.b
        self.b = self.a - self.b
        return self.fun1()

    def fun3(self):
        self.a = self.a * self.c
        self.c = self.a / self.c
        return self.fun1()

The methods in themselves can use the object instance to set and pass the arguments. There is in this pattern no need to pass unmodified arguments.

  • I would only do this if it really makes sense to group the arguments together like that. If not, it might only further complicate things, as I would argue here. (Also as a small nitpick, your implementation does not actually match the OP's.) – Simply Beautiful Art Mar 13 at 2:18

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.