Wiki source code of Functions

Last modified by chrisby on 2024/01/13 18:39

Show last authors
1 #### Structure and Size
2
3 * **Functions should be small.** Maximum 20 lines. Blocks and indentation should also be short. Blocks inside if, else, or while statements should be one line. A function call should probably be included. Indentation depths should be no more than one or two levels.
4 * **Functions should do only one task.** They should do its task well. They should do only that task. All instructions within the function should be on the same abstraction level. Sub-functions perform tasks which are one abstraction-level deeper. Sections within a function are symptoms that it performs more than one task. These function should be decomposed.
5 * **One abstraction level per function.** The 'stepdown rule' states that code should be easy to read from top to bottom: Under a function, its subfunctions should go down one level of abstraction.
6 * **The flow of reading should follow the flow of control.** The flow of control is the chronological order in which code is executed. The order of the functions should be adjusted accordingly. [[Here|doc:.Function Ordering Example.WebHome]] is an example.
7 * **Separate statement and query.** Functions should either provide information about an object or do something with an object, but not both.
8 * **Exceptions are better than error codes** (with if/else statements).
9 * Error.java is a dependency magnet with its enumeration of error codes and should be replaced by exceptions and derivatives of the Exception class, which allows easy extensibility in accordance with the Open-Closed Principle.
10 * Extract try/catch blocks. Error processing is a task. So it deserves its own function.
11 * **Switch statements.** They are unfortunately large. Rule of thumb: they can be tolerated if they appear only once, are used to create polymorphic objects, and are used behind an inheritance relationship so that they are invisible to the rest of the system.
12 * **Avoid side effects.** Functions should only do what their name implies. Avoid functions with output arguments, i.e., where objects are used as input, processed, and returned. Instead, use a method of the object to make clear that the object itself is being processed.
13
14 #### Practices and Principles
15
16 * **Don't repeat yourself (DRY).** Code duplication and reuse can usually be avoided by creating abstractions that incorporate the shared code.
17 * **Structured programming.** Functions may occasionally contain return, break and continue statements. 'goto' statements would only make sense in large statements, and since the latter should be avoided, so should the former.goto statements would only make sense in large statements, and since the latter should be avoided, the former should be too.
18 * How do you write good functions?
19 1. Writing down thoughts, restructuring, etc., without worrying too much about making it pretty, but about making it work.
20 1. Refactoring until one is satisfied and the function passes all tests.
21 * The first version of new code is always dirty. Clean code isn't written out of the blue; it evolves from a dirty design through continuous refactoring. Also see Test-Driven Development.
22
23 #### Function Arguments
24
25 * **The fewer arguments, the better.** Triads should be avoided. More than three arguments are not allowed. The fewer arguments a function takes, the easier it is to understand and the less error-prone it is.
26 * There are two common types of monadic functions:
27 1. Monad that asks the argument a question or manipulates/converts it.
28 1. Events = monads with no return value. The reader should recognize that it is an event by the functions context and name→ Otherwise, do not use monadic functions.
29 * **Avoid flag arguments.** It shows that the function performs two tasks, depending on whether the flag is true or false.
30 * **Dyads should be converted to monads if possible**, but cannot always be avoided. Sometimes they are useful, e.g. when passing 2D coordinates, because the arguments are connected by a cohesion.
31 * **Argument objects:** When many arguments are to be passed to a function, it often makes sense to combine them as a separate concept in a new class/data structure.
32 * **Verbs and keywords**: Function names can form a logical combination with the arguments, such as `write(name)`, or you can include the arguments in the function name, such as `writeName(name)`, to make it more readable.