How to Decide What Code to Put into a Function

coding-stylefunctional programmingfunctions

I started out with a script that was a few hundred lines. Later, I realized I wanted another script that would require much of the same code. I decided to wrap certain areas of the original script that would be shared, into definitions. When I was deciding exactly what should be in a function, I came across various things to consider:

  1. What should I set as its input parameters? If anything was needed in the function, I should probably require it as a parameter, right? Or should I declare it within the function itself?

  2. If function x always requires the output of function y, but function y sometimes is needed alone, should function X include the code of function y or simply call function y?

  3. Imagine a case where I have 5 functions that all call a function 'sub' (sub is essential for these 5 functions to complete their work). If 'sub' always is supposed to return the same result, then wouldn't multiple calls from these parent functions duplicate the same work? If I move the call to 'sub' outside of the 5 functions, how can I be sure that 'sub' is called before the first call to any of the 5 functions?

  4. If I have a segment of code that always produces the same result, and isn't required more than once in the same application, I normally wouldn't put it in a function. However, if it is not a function, but is later required in another application, then should it become a function?

Sorry if these questions are too vague, but I feel there should be some general guidelines. I haven't programmed for very long, and bounced around between OOP and functional, but I've never remembered reading anything that explained this. Could it simply be a matter of personal preference?

Best Answer

  1. there are 2 ways to pass data into a function: parameters or globals, in small scripts globals are acceptable but really try to avoid them

  2. it's easier to simply extract y this is also better when you need to change y later

  3. you can use lazy initialization here:

    var subresult=undefined
    
    function sub(){
        if(subresult===undefined){
            subresult=//calculate...
        }
        return subresult;
    }
    
  4. there are 2 competing principles here SRP and YAGNI:

    A. Single Responsibility Principle means essentially that each function should do a single thing and do it correctly

    B. You Aren't Going to Need It: don't waste time on stuff that may or may not be needed in the future, focus on what you need now