I just talking with a colleague (University instructor) who teaches C (Fundamental of programming Course). He said I won't give score to a student, if he uses I/O (scanf
or printf
or cin
count
) in a function (it shows he hasn't understood it well) or if he writes a function which does two things (for example to return the maximum of an array, he shouldn't sort the array and return the first element, however he can use two functions, one for sorting and another for returning the first element ...)...
I thought these are related to his teaching method but he claimed they are the principles of functions in structured programming.
Are there really such constraints and definitions for functions? What are those? If yes, in which topic are they discussed? Should they be discussed in a C or C++ teaching course?
-
Did he really say "structural programming" and not "functional programming"? Structural programming is about subroutines, loops and stuff, not about best practices of writing clean code. (But I agree with answers below.)scriptin– scriptin2015年05月10日 12:20:34 +00:00Commented May 10, 2015 at 12:20
-
1My guess is that the instructor said Structured programming.coredump– coredump2015年05月10日 16:11:42 +00:00Commented May 10, 2015 at 16:11
-
@scriptin the subject was C++ which I think is a normal structured programming language. then structured programming.Ahmad– Ahmad2015年05月11日 05:34:33 +00:00Commented May 11, 2015 at 5:34
2 Answers 2
scanf
and printf
use stdin
and stdout
, which means several things:
They have side effects. This means that they are not appropriate for functional programming and for parallel computing. Imagine two threads which read
stdin
. What could be the possible consequences of running those threads side by side? How easy or difficult would it be to debug the issues which will appear only sometimes and so are difficult to reproduce?They create dependencies. If a library relies on
stdin
andstdout
, is it straightforward to use in a desktop application where the user expects the data to be shown through GUI instead of a console? What about web applications? To remedy to this problem, dependency injection can be used, determining how the library is interacting with the outside world instead of relying onstdin
andstdout
.What if the program is running unattended (outside interactive command prompt)? This is often an issue with some Linux command-line scripts which assume that there would always be a user who can type Y or N to answer specific questions. It works well for very basic scenarios, and then miserably fail when someone needs to use them in an automated fashion (it remains technically possible, just unnecessarily complicated).
They make unit testing more difficult than it should be.
They assume that input and output forms should and will never be configured. For instance, a method can
printf
information about its execution in order to be monitored, which may be what you need for a basic scenario. Now, what if application grows and the same information should be sent to syslog? What if it needs to be filtered?
As for the function which does two things, this is just plainly wrong. A function should do one and one thing, in the same way as the class should have responsibility over a single part of the functionality only (SRP).
Letting the method to do multiple things leads has several effects:
It's very difficult to find a concise, clear name for the function.
CreateProductAndRefreshCache
is an ugly name.It usually leads to long methods. Splitting such method into two short ones often leads to a better readability and maintainability.
Unit testing is not straightforward.
-
Thank you for your complete answer but what about a function/procedure which prints a line of star symbols (e.g 70 *) and can be called whenever a line is needed, or to get/print a tree in recursive manner via a recursive function with I/O commands?Ahmad– Ahmad2015年05月11日 05:31:21 +00:00Commented May 11, 2015 at 5:31
-
@Ahmad The "only do one thing" rule is obviously a bit open to interpretation, but I would consider both of those examples to be doing only one thing. Though the tree walker should definitely take an ostream& argument so it can "print" to whatever the caller wants.Ixrec– Ixrec2015年05月11日 07:27:48 +00:00Commented May 11, 2015 at 7:27
There are 2 things he's probably referring to: side effects and composability.
scanf
and printf
do IO, which is a side effect. Side effects (input, output, and mutation of variables) don't really fit well with the mathematical definition of a function, and can make programs harder to reason about, so there's a paradigm of programming called 'functional' that tries to avoid such things as much as possible. C++ isn't really a functional language, though, so if he's strict about it, that probably doesn't quite make sense.
If a function does 2 things, then it can be broken into 2 functions which do the separate things separately and then be combined. This is good for a number of reasons: each individual function is smaller (making it easier to reason about), can be understood separately, and, most importantly, can be more easily combined with other functions to do new things.
-
1Or maybe he doesn't want student to use
printf
/scanf
because he expects them to useC++
constructs:count
,cin
?coredump– coredump2015年05月10日 16:13:16 +00:00Commented May 10, 2015 at 16:13 -
@coredump: good pointMichael Shaw– Michael Shaw2015年05月10日 17:48:34 +00:00Commented May 10, 2015 at 17:48
-
@coredump No, totally any I/OAhmad– Ahmad2015年05月11日 05:36:00 +00:00Commented May 11, 2015 at 5:36