liveBook · Manning

Pure function

As explained in Modern C

A mathematical function is a C library function that computes a numerical or mathematical result.

Returning a rational value

A function such as `rat_get_normal(rat x)` computes a normalized rational value by changing its local copy of `x` and returning that value. It does not modify a global object, perform I/O, or retain state between calls. section 10.2.2

A pure function has no effects other than returning a value, and its return value depends only on its parameters. Its interface is therefore the only way it interacts with the rest of the program. section 10.2 section 10.2.2

TAKEAWAY: A function is not pure when it:

  • Reads changeable program state outside its arguments. section 10.2.2
  • Modifies a global object. section 10.2.2
  • Keeps persistent internal state between calls, such as through a local static variable. section 10.2.2
  • Performs input or output, for example by calling `printf`. section 10.2.2

Pure functions are easy to understand and optimize: once their parameters are available, execution can be moved, delayed, or performed in parallel, provided the result is ready before use. They suit small tasks but become limited for more complex operations. section 10.2.2

Listing 10.1. A type for computation with rational numbers.
 1   #ifndef RATIONALS_H
 2   # define RATIONALS_H 1
 3   # include <stdbool.h>
 4   # include "euclid.h"
 5
 6   typedef struct rat rat;
 7
 8   struct rat {
 9     bool sign;
10     size_t num;
11     size_t denom;
12   };
13
14   /* Functions that return a value of type rat. */
15   rat rat_get(long long num, unsigned long long denom);
16   rat rat_get_normal(rat x);
17   rat rat_get_extended(rat x, size_t f);
18   rat rat_get_prod(rat x, rat y);
19   rat rat_get_sum(rat x, rat y);
20
21
22   /* Functions that operate on pointers to rat. */
23   void rat_destroy(rat* rp);
24   rat* rat_init(rat* rp,
25                 long long num,
26                 unsigned long long denom);
27   rat* rat_normalize(rat* rp);
28   rat* rat_extend(rat* rp, size_t f);
29   rat* rat_sumup(rat* rp, rat y);
30   rat* rat_rma(rat* rp, rat x, rat y);
31
32   /* Functions that are implemented as exercises. */
33   /** @brief Print @a x into @a tmp and return tmp. **/
34   char const* rat_print(size_t len, char tmp[len], rat const* x);
35   /** @brief Print @a x normalize and print. **/
36   char const* rat_normalize_print(size_t len, char tmp[len],
37                                   rat const* x);
38   rat* rat_dotproduct(rat rp[static 1], size_t n,
39                       rat const A[n], rat const B[n]);
40
41   #endif


!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":0,\"ch\":1},{\"line\":0,\"ch\":2}],[{\"line\":1,\"ch\":26},{\"line\":1,\"ch\":27}],[{\"line\":9,\"ch\":0},{\"line\":9,\"ch\":1}],[{\"line\":10,\"ch\":0},{\"line\":10,\"ch\":1}],[{\"line\":11,\"ch\":0},{\"line\":11,\"ch\":1}],[{\"line\":12,\"ch\":0},{\"line\":12,\"ch\":1}],[{\"line\":13,\"ch\":0},{\"line\":13,\"ch\":1}],[{\"line\":14,\"ch\":0},{\"line\":14,\"ch\":1}],[{\"line\":15,\"ch\":0},{\"line\":15,\"ch\":1}],[{\"line\":16,\"ch\":0},{\"line\":16,\"ch\":1}],[{\"line\":17,\"ch\":0},{\"line\":17,\"ch\":1}],[{\"line\":18,\"ch\":0},{\"line\":18,\"ch\":1}],[{\"line\":20,\"ch\":1},{\"line\":20,\"ch\":2}],[{\"line\":30,\"ch\":1},{\"line\":30,\"ch\":2}],[{\"line\":37,\"ch\":39},{\"line\":37,\"ch\":40}],[{\"line\":40,\"ch\":1},{\"line\":40,\"ch\":2}],[{\"line\":0,\"ch\":5},{\"line\":0,\"ch\":12}],[{\"line\":1,\"ch\":1},{\"line\":1,\"ch\":2}],[{\"line\":11,\"ch\":1},{\"line\":11,\"ch\":2}],[{\"line\":19,\"ch\":0},{\"line\":19,\"ch\":1}],[{\"line\":20,\"ch\":0},{\"line\":20,\"ch\":1}],[{\"line\":21,\"ch\":0},{\"line\":21,\"ch\":1}],[{\"line\":22,\"ch\":0},{\"line\":22,\"ch\":1}],[{\"line\":23,\"ch\":0},{\"line\":23,\"ch\":1}],[{\"line\":24,\"ch\":0},{\"line\":24,\"ch\":1}],[{\"line\":25,\"ch\":0},{\"line\":25,\"ch\":1}],[{\"line\":26,\"ch\":0},{\"line\":26,\"ch\":1}],[{\"line\":27,\"ch\":0},{\"line\":27,\"ch\":1}],[{\"line\":28,\"ch\":0},{\"line\":28,\"ch\":1}],[{\"line\":31,\"ch\":1},{\"line\":31,\"ch\":2}],[{\"line\":1,\"ch\":5},{\"line\":1,\"ch\":13}],[{\"line\":2,\"ch\":1},{\"line\":2,\"ch\":2}],[{\"line\":12,\"ch\":1},{\"line\":12,\"ch\":2}],[{\"line\":22,\"ch\":1},{\"line\":22,\"ch\":2}],[{\"line\":29,\"ch\":0},{\"line\":29,\"ch\":1}],[{\"line\":30,\"ch\":0},{\"line\":30,\"ch\":1}],[{\"line\":31,\"ch\":0},{\"line\":31,\"ch\":1}],[{\"line\":32,\"ch\":0},{\"line\":32,\"ch\":1}],[{\"line\":33,\"ch\":0},{\"line\":33,\"ch\":1}],[{\"line\":34,\"ch\":0},{\"line\":34,\"ch\":1}],[{\"line\":35,\"ch\":0},{\"line\":35,\"ch\":1}],[{\"line\":36,\"ch\":0},{\"line\":36,\"ch\":1}],[{\"line\":37,\"ch\":0},{\"line\":37,\"ch\":1}],[{\"line\":38,\"ch\":0},{\"line\":38,\"ch\":1}],[{\"line\":2,\"ch\":5},{\"line\":2,\"ch\":14}],[{\"line\":3,\"ch\":5},{\"line\":3,\"ch\":14}],[{\"line\":3,\"ch\":1},{\"line\":3,\"ch\":2}],[{\"line\":13,\"ch\":1},{\"line\":13,\"ch\":2}],[{\"line\":23,\"ch\":1},{\"line\":23,\"ch\":2}],[{\"line\":33,\"ch\":1},{\"line\":33,\"ch\":2}],[{\"line\":39,\"ch\":0},{\"line\":39,\"ch\":1}],[{\"line\":40,\"ch\":0},{\"line\":40,\"ch\":1}],[{\"line\":2,\"ch\":5},{\"line\":2,\"ch\":14}],[{\"line\":3,\"ch\":5},{\"line\":3,\"ch\":14}],[{\"line\":4,\"ch\":1},{\"line\":4,\"ch\":2}],[{\"line\":14,\"ch\":1},{\"line\":14,\"ch\":2}],[{\"line\":24,\"ch\":1},{\"line\":24,\"ch\":2}],[{\"line\":34,\"ch\":1},{\"line\":34,\"ch\":2}],[{\"line\":5,\"ch\":1},{\"line\":5,\"ch\":2}],[{\"line\":15,\"ch\":1},{\"line\":15,\"ch\":2}],[{\"line\":25,\"ch\":1},{\"line\":25,\"ch\":2}],[{\"line\":35,\"ch\":1},{\"line\":35,\"ch\":2}],[{\"line\":5,\"ch\":5},{\"line\":5,\"ch\":19}],[{\"line\":6,\"ch\":1},{\"line\":6,\"ch\":2}],[{\"line\":16,\"ch\":1},{\"line\":16,\"ch\":2}],[{\"line\":26,\"ch\":1},{\"line\":26,\"ch\":2}],[{\"line\":36,\"ch\":1},{\"line\":36,\"ch\":2}],[{\"line\":7,\"ch\":1},{\"line\":7,\"ch\":2}],[{\"line\":17,\"ch\":1},{\"line\":17,\"ch\":2}],[{\"line\":27,\"ch\":1},{\"line\":27,\"ch\":2}],[{\"line\":37,\"ch\":1},{\"line\":37,\"ch\":2}],[{\"line\":5,\"ch\":13},{\"line\":5,\"ch\":19}],[{\"line\":7,\"ch\":5},{\"line\":7,\"ch\":11}],[{\"line\":8,\"ch\":1},{\"line\":8,\"ch\":2}],[{\"line\":18,\"ch\":1},{\"line\":18,\"ch\":2}],[{\"line\":28,\"ch\":1},{\"line\":28,\"ch\":2}],[{\"line\":38,\"ch\":1},{\"line\":38,\"ch\":2}],[{\"line\":9,\"ch\":0},{\"line\":9,\"ch\":2}],[{\"line\":9,\"ch\":7},{\"line\":9,\"ch\":13}],[{\"line\":10,\"ch\":7},{\"line\":10,\"ch\":13}],[{\"line\":16,\"ch\":33},{\"line\":16,\"ch\":39}],[{\"line\":27,\"ch\":30},{\"line\":27,\"ch\":36}],[{\"line\":33,\"ch\":27},{\"line\":33,\"ch\":33}],[{\"line\":35,\"ch\":37},{\"line\":35,\"ch\":43}],[{\"line\":37,\"ch\":43},{\"line\":37,\"ch\":49}],[{\"line\":10,\"ch\":0},{\"line\":10,\"ch\":2}],[{\"line\":9,\"ch\":7},{\"line\":9,\"ch\":13}],[{\"line\":10,\"ch\":7},{\"line\":10,\"ch\":13}],[{\"line\":16,\"ch\":33},{\"line\":16,\"ch\":39}],[{\"line\":27,\"ch\":30},{\"line\":27,\"ch\":36}],[{\"line\":33,\"ch\":27},{\"line\":33,\"ch\":33}],[{\"line\":35,\"ch\":37},{\"line\":35,\"ch\":43}],[{\"line\":37,\"ch\":43},{\"line\":37,\"ch\":49}],[{\"line\":11,\"ch\":0},{\"line\":11,\"ch\":2}],[{\"line\":12,\"ch\":0},{\"line\":12,\"ch\":2}],[{\"line\":13,\"ch\":0},{\"line\":13,\"ch\":2}],[{\"line\":14,\"ch\":0},{\"line\":14,\"ch\":2}],[{\"line\":14,\"ch\":17},{\"line\":14,\"ch\":26}],[{\"line\":24,\"ch\":19},{\"line\":24,\"ch\":28}],[{\"line\":25,\"ch\":28},{\"line\":25,\"ch\":37}],[{\"line\":14,\"ch\":32},{\"line\":14,\"ch\":50}],[{\"line\":25,\"ch\":19},{\"line\":25,\"ch\":37}],[{\"line\":15,\"ch\":0},{\"line\":15,\"ch\":2}],[{\"line\":16,\"ch\":0},{\"line\":16,\"ch\":2}],[{\"line\":9,\"ch\":7},{\"line\":9,\"ch\":13}],[{\"line\":10,\"ch\":7},{\"line\":10,\"ch\":13}],[{\"line\":16,\"ch\":33},{\"line\":16,\"ch\":39}],[{\"line\":27,\"ch\":30},{\"line\":27,\"ch\":36}],[{\"line\":33,\"ch\":27},{\"line\":33,\"ch\":33}],[{\"line\":35,\"ch\":37},{\"line\":35,\"ch\":43}],[{\"line\":37,\"ch\":43},{\"line\":37,\"ch\":49}],[{\"line\":17,\"ch\":0},{\"line\":17,\"ch\":2}],[{\"line\":18,\"ch\":0},{\"line\":18,\"ch\":2}],[{\"line\":19,\"ch\":0},{\"line\":19,\"ch\":2}],[{\"line\":20,\"ch\":0},{\"line\":20,\"ch\":2}],[{\"line\":21,\"ch\":0},{\"line\":21,\"ch\":2}],[{\"line\":22,\"ch\":0},{\"line\":22,\"ch\":2}],[{\"line\":22,\"ch\":5},{\"line\":22,\"ch\":9}],[{\"line\":23,\"ch\":0},{\"line\":23,\"ch\":2}],[{\"line\":24,\"ch\":0},{\"line\":24,\"ch\":2}],[{\"line\":14,\"ch\":17},{\"line\":14,\"ch\":26}],[{\"line\":24,\"ch\":19},{\"line\":24,\"ch\":28}],[{\"line\":25,\"ch\":28},{\"line\":25,\"ch\":37}],[{\"line\":25,\"ch\":0},{\"line\":25,\"ch\":2}],[{\"line\":14,\"ch\":32},{\"line\":14,\"ch\":50}],[{\"line\":25,\"ch\":19},{\"line\":25,\"ch\":37}],[{\"line\":26,\"ch\":0},{\"line\":26,\"ch\":2}],[{\"line\":27,\"ch\":0},{\"line\":27,\"ch\":2}],[{\"line\":9,\"ch\":7},{\"line\":9,\"ch\":13}],[{\"line\":10,\"ch\":7},{\"line\":10,\"ch\":13}],[{\"line\":16,\"ch\":33},{\"line\":16,\"ch\":39}],[{\"line\":27,\"ch\":30},{\"line\":27,\"ch\":36}],[{\"line\":33,\"ch\":27},{\"line\":33,\"ch\":33}],[{\"line\":35,\"ch\":37},{\"line\":35,\"ch\":43}],[{\"line\":37,\"ch\":43},{\"line\":37,\"ch\":49}],[{\"line\":28,\"ch\":0},{\"line\":28,\"ch\":2}],[{\"line\":29,\"ch\":0},{\"line\":29,\"ch\":2}],[{\"line\":30,\"ch\":0},{\"line\":30,\"ch\":2}],[{\"line\":31,\"ch\":0},{\"line\":31,\"ch\":2}],[{\"line\":32,\"ch\":0},{\"line\":32,\"ch\":2}],[{\"line\":33,\"ch\":0},{\"line\":33,\"ch\":2}],[{\"line\":33,\"ch\":5},{\"line\":33,\"ch\":15}],[{\"line\":35,\"ch\":5},{\"line\":35,\"ch\":15}],[{\"line\":9,\"ch\":7},{\"line\":9,\"ch\":13}],[{\"line\":10,\"ch\":7},{\"line\":10,\"ch\":13}],[{\"line\":16,\"ch\":33},{\"line\":16,\"ch\":39}],[{\"line\":27,\"ch\":30},{\"line\":27,\"ch\":36}],[{\"line\":33,\"ch\":27},{\"line\":33,\"ch\":33}],[{\"line\":35,\"ch\":37},{\"line\":35,\"ch\":43}],[{\"line\":37,\"ch\":43},{\"line\":37,\"ch\":49}],[{\"line\":33,\"ch\":5},{\"line\":33,\"ch\":9}],[{\"line\":35,\"ch\":5},{\"line\":35,\"ch\":9}],[{\"line\":33,\"ch\":10},{\"line\":33,\"ch\":15}],[{\"line\":35,\"ch\":10},{\"line\":35,\"ch\":15}],[{\"line\":36,\"ch\":41},{\"line\":36,\"ch\":46}],[{\"line\":38,\"ch\":29},{\"line\":38,\"ch\":34}],[{\"line\":34,\"ch\":0},{\"line\":34,\"ch\":2}],[{\"line\":35,\"ch\":0},{\"line\":35,\"ch\":2}],[{\"line\":33,\"ch\":5},{\"line\":33,\"ch\":15}],[{\"line\":35,\"ch\":5},{\"line\":35,\"ch\":15}],[{\"line\":9,\"ch\":7},{\"line\":9,\"ch\":13}],[{\"line\":10,\"ch\":7},{\"line\":10,\"ch\":13}],[{\"line\":16,\"ch\":33},{\"line\":16,\"ch\":39}],[{\"line\":27,\"ch\":30},{\"line\":27,\"ch\":36}],[{\"line\":33,\"ch\":27},{\"line\":33,\"ch\":33}],[{\"line\":35,\"ch\":37},{\"line\":35,\"ch\":43}],[{\"line\":37,\"ch\":43},{\"line\":37,\"ch\":49}],[{\"line\":33,\"ch\":5},{\"line\":33,\"ch\":9}],[{\"line\":35,\"ch\":5},{\"line\":35,\"ch\":9}],[{\"line\":36,\"ch\":0},{\"line\":36,\"ch\":2}],[{\"line\":33,\"ch\":10},{\"line\":33,\"ch\":15}],[{\"line\":35,\"ch\":10},{\"line\":35,\"ch\":15}],[{\"line\":36,\"ch\":41},{\"line\":36,\"ch\":46}],[{\"line\":38,\"ch\":29},{\"line\":38,\"ch\":34}],[{\"line\":37,\"ch\":0},{\"line\":37,\"ch\":2}],[{\"line\":37,\"ch\":32},{\"line\":37,\"ch\":38}],[{\"line\":9,\"ch\":7},{\"line\":9,\"ch\":13}],[{\"line\":10,\"ch\":7},{\"line\":10,\"ch\":13}],[{\"line\":16,\"ch\":33},{\"line\":16,\"ch\":39}],[{\"line\":27,\"ch\":30},{\"line\":27,\"ch\":36}],[{\"line\":33,\"ch\":27},{\"line\":33,\"ch\":33}],[{\"line\":35,\"ch\":37},{\"line\":35,\"ch\":43}],[{\"line\":37,\"ch\":43},{\"line\":37,\"ch\":49}],[{\"line\":38,\"ch\":0},{\"line\":38,\"ch\":2}],[{\"line\":33,\"ch\":10},{\"line\":33,\"ch\":15}],[{\"line\":35,\"ch\":10},{\"line\":35,\"ch\":15}],[{\"line\":36,\"ch\":41},{\"line\":36,\"ch\":46}],[{\"line\":38,\"ch\":29},{\"line\":38,\"ch\":34}],[{\"line\":33,\"ch\":10},{\"line\":33,\"ch\":15}],[{\"line\":35,\"ch\":10},{\"line\":35,\"ch\":15}],[{\"line\":36,\"ch\":41},{\"line\":36,\"ch\":46}],[{\"line\":38,\"ch\":29},{\"line\":38,\"ch\":34}],[{\"line\":39,\"ch\":0},{\"line\":39,\"ch\":2}],[{\"line\":40,\"ch\":0},{\"line\":40,\"ch\":2}],[{\"line\":40,\"ch\":5},{\"line\":40,\"ch\":11}]]"}
!@%STYLE%@!

Browse the rational-number interface and its value-returning operations to compare pure functions with pointer-based operations. section 10.2.2

How Modern C covers it

How deep it goes
Defines purity, lists disqualifying effects, and explains optimization consequences while deferring local static variables to later treatment.
Examples
Demonstrates rational-number constructors, normalization, scaling, multiplication, and addition as value-returning operations.
What you can do after
Evaluate whether a C function is pure and recognize when its result permits movement or parallel execution.
How it connects
Connects pure functions with function parameters, global variables, static variables, I/O, and compiler optimization.

Also explained in

Compare how 19 books explain pure function →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern C. The section links point to the parts of the book it draws on.