# Why do we need value-returning functions?

I'm just a beginner at C++ programming. I am currently having hard time grasping the usage of value returning function and non-value returning function. Void functions are called non-value returning function but they can return value if we assign certain parameters, compute the parameters and call them in the main function. So, doesn't this defeat the purpose? I feel like I am getting this wrong, so some explanation here would be great!

Also, I see that void functions are easier to use, since I don't need to use " cout<< 'the void function' << endl; " It seems easier and the value-returning function seems useless. I need explanation here as well as to why we need value-returning function.

Please bear with my questions and I am always ready to learn!

• It's convenient to call a simple value-returned function from an expression. The "simple" means no side effects, no error conditions etc. - like $sin(x)$ or $cos(x)$ – HEKTO Mar 19 '20 at 15:38

"Need" as such, no. There you are right, all the work can be done using void functions, by passing pointers to variables to modify instead, or changing global variables. In fact, everything is compiled down to assembly language, and no such language I know of has "functions" that return values.

On the other hand, we are accustomed (by mathematics, and by lots of it's applications in everyday life) to think in terms of functions that are applied to arguments and return a value. Think of sin x, square root, and a long list of others, like lowly strlen() in C. It is a nice simplification to be able to say:

y = abs(x) - 42 * sqrt(b);


pabs(x, &xa);
psrqrt(b, &ba);
y = xa - 42 * ba;


Come to think about it, multiplication and subtractions are functions returning values too (X& operator*(const X&, const X&) and X& operator-(const X&, const X&) in C++), and the handling of results and intermediate values soon gets unmanageable. One of the points of a programming language is to handle such bureaucratic details for you, transparently.

Consider that Prolog gets by without functions most of the time. (It does have functions, but they are mostly used for mathematical notation like sin(X).)

Rather than return a value, like f(X1,X2), you define a predicate p(X1,X2,Y) which is true if Y would be the return value from that function.

In Haskell, which is a functional language, you would typically sum a list with a function. Here, sum_list xs returns the sum of the elements of the list xs:

sum_list [] = 0
sum_list (x : xs) = x + sum xs


(In Haskell, you use the notation x : xs to denote a list with x as the first, or head, element and xs as everything but the first element, also know as its "tail".)

In Prolog, which is a logic language, you would typically define a predicate sum_list(Xs,S) which is true if and only if S is the sum of the elements of the list Xs.

sum_list([], 0).
sum_list([X | Xs], S) :- sum_list(Xs, S1), S is X + S1.


(In Prolog, [X | Xs] means a list with X as its head and Xs as its tail. Variables in Prolog start with an upper-case letter. Also note that the + operator is behaving like a function.)

A function is just a special kind of predicate, so you don't need functions to program if you have predicates. But it is very convenient notation for many circumstances.

What you describe is possible, but is considered bad programming practice for some good reasons. It does not scale to large, complex programs because it lets bugs slip easily. Using too many global variables makes it hard to control your program's behavior, because you need to be able to track which components of your program are interacting with which variables and in what order.

So, if you want to analyze a specific function somewhere in the depths of your code, and if that function uses a variable that has been declared outside the function, then you also need to know which other functions have interacted (and in what way) with that variable.

Let's call a function pure if it does not interact with its environment, i.e. it does not use variables declared outside its body, it does not use user input, it does not print output, and in general it does not do many things, but it only computes some value. Pure functions give you the safety that their result depends purely on their input. No matter in what environment you run a pure function, it will always give you the same result for the same arguments. So, with pure functions you can be sure that to analyze/understand them, you do not need to look outside their body. Pure functions correspond really well to the mathematical notion of a function, by the way.

A good programming practice is to separate the pure parts of your program from the parts that need to interact with some environment. Then use pure functions for the pure part and make organized code for the impure. In general, this gives you better control over your program and fewer bugs. Some languages take advantage of the distinction between pure and impure computations to allow for code optimizations and better performance.