views:

51

answers:

6

This is a very general programming question that I just want to put out there and see if anyone has any thoughts on it. It shows up time and time again: I have a function somefunction() which is called a lot, but the very first time its called I want it to behave just a bit differently. Here's an example:

first_time = true;
somefunction(){
  // bunch of code...
  if (first_time)
  {
    first_time = false;
    // do it this way...
  }
  else
  {
    // do it that way...
  }
  // bunch of code...
}

3 approaches come to mind:

  • you can do as in the example above where you the notion of "first time" is explicit. Usually the "first time" check is just a boolean check hence its very cheap - but still, when you are doing this in a timer that fires off every few hundred milliseconds, it feels hack-ish.

  • You duplicate the function and just change the few lines of code that need to be changed when its called the first time and call one function at the start and the other function every other time. Especially if the function is big this looks really ugly IMO.

  • You break up somefunction() and create separate functions for where the code is exactly the same. You then create wrapper functions for the first time and everytime else that utilize these smaller functions. I think this approach is best and is what I'm going to use in my situation involving a timer.

Thoughts? Its my first time asking a general question like this and I hope it creates some interesting discussion :)

A: 

Too general; I think the first and the third approach are okay in an appropriate situation (#2 isn't - violates DRY). Also, it does not show time and time again for me; the most common I can think of is the singleton pattern. Can you give a specific example?

Amadan
A: 

The first approach seems just fine. The second approach is a maintenance nightmare. The third approach seems like it will become far more complicated than it needs to be from your description. Unless breaking up the functions at those specific points provides a logical grouping, you will just be creating a workaround which might be even messier than two.

Another way I can think of is to use a callback function to run the "first time" code for languages that do support functions as first-class objects. Here's an example in JavaScript.

function makeSpecialFunction = function(runOnlyFirstTime) {
    return function() {
        // code before

        if(runOnlyFirstTime) {
            runOnlyFirstTime();
            runOnlyFirstTime = null;
        }

        // code after
    };
};

Not a huge improvement I know, but if the only thing keeping your someFunction from being reusable, then this is your solution.

Now someFunction can be used twice with different initialization codes.

var init = function() {
    alert("first:init");
};

var init2 = function() {
    alert("first:init2");
};

var someFunction = makeSpecialFunction(init);
var otherFunction = makeSpecialFunction(init2);

someFunction(); // alerts first:init
someFunction(); // doesn't alert anything
Anurag
A: 

In languages like C# you could use delegates like so (Function is the public callable method):

public delegate void FunctionSignature();

class FunctionContainer
{
  public FunctionSignature Function;

  public FunctionContainer()
  {
    Function = FirstTimeFunction;
  }

  private void FirstTimeFunction() 
  { 
    ...
    Function = FollowingTimesFunction; 
  }

  private void FollowingTimesFunction()
  {
    ...
  }
}

Just an idea, a curiosity if you like, but it may work for you :-)

Edgar Sánchez
A: 

The easiest and most maintainable general scenario, IMO, is option 1.
I'd pass a first parameter to the function that defaults to false:

function(first = false)
  if first
    ... do something special
  else
    ... optionally do something else special (if you want)
  ... do main stuff

I agree with others' opinions that #2 is inherently a bad idea, and #3 may be overkill.

This is generally what parameters to functions are for-- to act on them and alter behavior based on them. first could just as easily be last, is_weekday, am_i_feeling_lucky, etc.

ma3
A: 

C has static local variables whose values persist from invocation to invocation. You could declare first_time to be a static variable. Its value will be initialized on the first call only. Subsequent calls will be use the previous value. Thus it becomes a flag to indicate whether this is the first invocation or not.

void some_function()
{
    static int first_time = 1;

    if (first_time) {
        // do stuff for first call only
        first_time = 0;
    }

    // do stuff for every call
}
Barry Brown
A: 

In some situations you may be able to use a Sentinel Value, but in reverse: that is, pass a special value in to initialize the function. I think these situations are rare.

Better is probably a variant of your option 3: put the function into its own class, and make the initialization steps not a part of the function, but rather a part of the class constructor. There remain some situations that this doesn't cover - where the actual initial value is needed for initialization, for instance, but I think this covers most cases and is the cleanest option. Even when that initial value is needed, you may be able to pass it into the constructor, however then your conditional logic moves out to the caller, and that's probably a bad idea.

Carl Manaster