Computer Science

Pure Function

A pure function is a function that always produces the same output for a given input and has no side effects. It does not modify any external state or data and is therefore predictable and easy to test. Pure functions are a fundamental concept in functional programming.

Written by Perlego with AI-assistance

11 Key excerpts on "Pure Function"

  • Mastering JavaScript Functional Programming
    eBook - ePub

    Mastering JavaScript Functional Programming

    Write clean, robust, and maintainable web and server code using functional JavaScript and TypeScript

    4

    Behaving Properly – Pure Functions

    In Chapter 3 , Starting Out with Functions , we considered functions as the critical elements in functional programming (FP ), went into detail about arrow functions, and introduced some concepts, such as injection, callbacks, polyfilling, and stubbing. In this chapter, we’ll have the opportunity to revisit or apply some of those ideas.
    In this chapter, we will do the following:
    • Consider the notion of purity and why we should care about Pure Functions —and imPure Functions as well!
    • Examine the concept of referential transparency
    • Recognize the problems implied by side effects
    • Show some advantages of Pure Functions
    • Describe the main reasons behind imPure Functions
    • Discover ways to minimize the number of imPure Functions
    • Focus on ways of testing both pure and imPure Functions

    Pure Functions

    Pure Functions behave the same way as mathematical functions and provide various benefits. A function is pure if it satisfies two conditions:
    • Given the same arguments, the function always calculates and returns the same result : This should be true no matter how many times it’s invoked or under which conditions you call it. This result cannot depend on any outside information or state, which could change during the program execution and cause it to return a different value. Nor can the function result depend on I/O results, random numbers, some other external variable, or a value that is not directly controllable.
    • When calculating its result, the function doesn’t cause any observable side effects : This includes output to I/O devices, the mutation of objects, changes to a program’s state outside of the function, and so on.
    You can simply say that Pure Functions don’t depend on (and don’t modify) anything outside their scope and always return the same result for the same input arguments.
    Another word used in this context is idempotency , but it’s not exactly the same. An idempotent function can be called as many times as desired and will always produce the same result. However, this doesn’t imply that the function is free from side effects.
  • Mastering JavaScript Functional Programming
    eBook - ePub

    Mastering JavaScript Functional Programming

    Write clean, robust, and maintainable web and server code using functional JavaScript, 2nd Edition

    Behaving Properly - Pure Functions

    In Chapter 3 , Starting Out with Functions – A Core Concept , we considered functions as the key elements in Functional Programming (FP ), went into detail about arrow functions, and introduced some concepts, such as injection, callbacks, polyfilling, and stubbing. In this chapter, we'll have the opportunity to revisit or apply some of those ideas. We will also do the following:
    • Consider the notion of purity , and why we should care about Pure Functions —and impure functions as well!
    • Examine the concept of referential transparency .
    • Recognize the problems implied by side effects.
    • Show some advantages of Pure Functions.
    • Describe the main reasons behind imPure Functions.
    • Find ways to minimize the number of imPure Functions.
    • Focus on ways of testing both pure and imPure Functions.
    Passage contains an image

    Pure Functions

    Pure Functions behave in the same way as mathematical functions and provide diverse benefits. A function is pure if it satisfies two conditions:
    • Given the same arguments, the function always calculates and returns the same result : This should be true no matter how many times it's invoked or under which conditions you call it. This result cannot depend on any outside  information or state, which could change during the program execution and cause it to return a different value. Nor can the function result depend on I/O results, random numbers, some other external variable, or a value that is not directly controllable.
    • When calculating its result, the function doesn't cause any observable side effects
      : This includes output to I/O devices, the mutation of objects, changes to a program's state outside of the function, and so on.
    If you want, you can simply say that Pure Functions don't depend on (and don't modify) anything outside their scope and always return the same result for the same input arguments.
    Another word used in this context is idempotency
  • The JavaScript Workshop
    eBook - ePub

    The JavaScript Workshop

    A New, Interactive Approach to Learning JavaScript

    • Joseph Labrecque, Jahred Love, Daniel Rosenbaum, Nick Turner, Gaurav Mehla, Alonzo L. Hosford, Florian Sloot, Philip Kirkbride(Authors)
    • 2019(Publication Date)
    • Packt Publishing
      (Publisher)
    These concepts will be covered over the course of this chapter. If implemented correctly, functional programming can result in code that is more predictable, less error-prone, and easier to test compared to other programming methods.

    Pure Functions

    Pure Functions are one of the pillars of functional programming. A function is pure if it always returns the same result when it's given the same parameters. It also cannot depend on or modify variables or state outside of the function's scope.
    A simple example of an imPure Function is as follows: var positionX = 10; function moveRight(numSlots) { return positionX += numSlots; } moveRight(5);
    You can plainly see how the function is manipulating a value outside of its scope in the positionX global variable. A Pure Function should only use the arguments that have been passed in for its logic, and should not directly modify them. Another issue is that the function doesn't actually return a value.
    Consider the following code. Can you see why it would not be considered a pure function? var positionX = 10; function moveRight(numSlots) {     return positionX + numSlots; } positionX = moveRight(5);
    Though the function only reads the global variable value and does not manipulate the variable directly, it is still not pure. To see why think about what happens if you call the function multiple times with the value 5 for the numSlots parameter:
    • The first time, the result is 15 (since positionX is 10 and 10 + 5 = 15 )
    • The second time, the result would be 20
    • The third time, the result would be 25
    In other words, there is a different result for each invocation. For the function to be pure, the result would have had to resolve to the exact same value for the given parameter value, that is, 5
  • Functional Programming in Scala
    • Paul Chiusano, Runar Bjarnason(Authors)
    • 2014(Publication Date)
    • Manning
      (Publisher)
    observable. (For example, we can mutate data that’s declared locally in the body of some function if we ensure that it can’t be referenced outside that function, or we can write to a file as long as no enclosing function can observe this occurring.)

    1.2. Exactly what is a (pure) function?

    We said earlier that FP means programming with Pure Functions, and a Pure Function is one that lacks side effects. In our discussion of the coffee shop example, we worked off an informal notion of side effects and purity. Here we’ll formalize this notion, to pinpoint more precisely what it means to program functionally. This will also give us additional insight into one of the benefits of functional programming: Pure Functions are easier to reason about.
    A function f with input type A and output type B (written in Scala as a single type: A => B, pronounced “A to B” or “A arrow B”) is a computation that relates every value a of type A to exactly one value b of type B such that b is determined solely by the value of a. Any changing state of an internal or external process is irrelevant to computing the result f(a). For example, a function intToString having type Int => String will take every integer to a corresponding string. Furthermore, if it really is a function, it will do nothing else.
    In other words, a function has no observable effect on the execution of the program other than to compute a result given its inputs; we say that it has no side effects. We sometimes qualify such functions as pure functions to make this more explicit, but this is somewhat redundant. Unless we state otherwise, we’ll often use function to imply no side effects.
    [2 ]
    2 Procedure is often used to refer to some parameterized chunk of code that may have side effects.
    You should be familiar with a lot of Pure Functions already. Consider the addition (+) function on integers. It takes two integer values and returns an integer value. For any two given integer values, it will always return the same integer value
  • Learning TypeScript 2.x
    In the preceding section, we learned that a Pure Function returns a value that can be computed using only the arguments passed to it. A Pure Function also avoids mutating its arguments or any other external variable that is not passed to the function as an argument. In FP terminology, it is common to say that a Pure Function is a function that has no side effects. This means that when we invoke a Pure Function, we can expect that the function is not going to interfere (via a state mutation) with any other component in our application.
    Some programming languages, such as Haskell, can ensure that an application is free of side effects using its type system. TypeScript has fantastic interoperability with JavaScript, but the downside of this, compared to a more isolated language such as Haskell, is that the type system is not able to guarantee that our application is free of side effects.
    If you like the idea of your JavaScript applications being free of side effects, you can try open source projects such as https://github.com/bodil/eslint-config-cleanjs . The project is an ESLint configuration that aims to restrict you to a subset of JavaScript that is as close to an idealized Pure Functional language as possible. Unfortunately, at the time of writing, there were no similar tools available that were specifically designed for TypeScript.
    Passage contains an image

    Referential transparency

    Referential transparency is another concept closely related to Pure Functions and side effects. A function is pure when it is free of side effects. An expression is said to be referentially transparent when it can be replaced with its corresponding value without changing the application's behavior.
    A Pure Function is a referentially transparent expression. An expression that is not referentially transparent is known as referentially opaque.
    Passage contains an image

    Immutability

    Immutability refers to the inability to change the value of a variable after a value has been assigned to it. Purely FP languages include immutable implementations of common data structures. For example, when we add an element to an array, we are mutating the original array. However, if we use an immutable array, and we try to add a new element to it, the original array will not be mutated, and we will add the new item to a copy of it.
  • Functional Programming in C#, Second Edition
    • Enrico Buonanno(Author)
    • 2022(Publication Date)
    • Manning
      (Publisher)
    Mutates global state—Global here means any state that’s visible outside of the function’s scope. For example, a private instance field is considered global because it’s visible from all methods within the class.
  • Mutates its input arguments—Arguments passed by the caller are effectively a state that a function shares with its caller. If a function mutates one of its arguments, that’s a side effect that’s visible to the caller.
  • Throws exceptions—You can reason about Pure Functions in isolation; however, if a function throws exceptions, then the outcome of calling it is context-dependent. Namely, it differs depending on whether the function is called in a try -catch .
  • Performs any I/O operation—This includes any interaction between the program and the external world, including reading from or writing to the console, the filesystem, or a database, and interacting with any process outside the application’s boundary.
  • In summary, Pure Functions have no side effects, and their output is solely determined by their inputs. Note that both conditions must hold:
    • A function that has no side effects can still be impure. Namely, a function that reads from global mutable state is likely to have an output that depends on factors other than its inputs.
    • A function whose output depends entirely on its inputs can also be impure. It could still have side effects such as updating global mutable state.
    The deterministic nature of Pure Functions (they always return the same output for the same input) has some interesting consequences. Pure Functions are easy to test and to reason about.1
    Furthermore, the fact that outputs only depend on inputs means that the order of evaluation isn’t important. Whether you evaluate the result of a function now or later, the result does not change. This means that the parts of your program that consist entirely of Pure Functions can be optimized in a number of ways:
  • Functional Programming in JavaScript
    eBook - ePub

    Functional Programming in JavaScript

    How to improve your JavaScript programs using functional techniques

    • Luis Atencio(Author)
    • 2016(Publication Date)
    • Manning
      (Publisher)
    Pure Functions.
    1.2.2. Pure Functions and the problem with side effects
    Functional programming is based on the premise that you build immutable programs based on the building blocks of Pure Functions. A Pure Function has the following qualities:
    • It depends only on the input provided and not on any hidden or external state that may change during its evaluation or between calls.
    • It doesn’t inflict changes beyond their scope, such as modifying a global object or a parameter passed by reference.
    Intuitively, any function that doesn’t meet these requirements is “impure.” Programming with immutability can feel strange at first. After all, the whole point of imperative design, which is what we’re accustomed to, is to declare that variables are to mutate from one statement to the next (they’re “variable,” after all). This is a natural thing for us to do. Consider the following function:
    var counter = 0; function increment() { return ++counter; }
    This function is impure because it reads/modifies an external variable, counter, which isn’t local to the function’s scope. Generally, functions have side effects when reading from or writing to external resources, as shown in figure 1.1 . Another example is the popular function Date.now(); its output certainly isn’t predicable and consistent, because it always depends on a constantly changing factor: time.
    Figure 1.1. Function increment() causes side effects by reading/modifying an external variable, counter. Its result is unpredictable because counter can change at any time between calls.
    In this case, counter is accessed via an implicit global variable (in browser-based JavaScript, it’s the window object). Another common side effect occurs when accessing instance data via the this keyword. The behavior of this in JavaScript is unlike it is in any other programming language because it determines the runtime context of a function. This often leads to code that’s hard to reason about, which is why I avoid it when possible. I revisit this topic in the next chapter. Side effects can occur in many situations, including these:
  • Functional Programming in Go
    eBook - ePub

    Functional Programming in Go

    Apply functional techniques in Golang to improve the testability, readability, and security of your code

    This means that no matter how many times the function is executed, it will always return the same output, assuming that the input arguments have remained the same. In the preceding example, the add function is always returning the same sum of two numbers provided the same input. On the other hand, the time.Now function is not (nor would that have been the desired behavior). You might be familiar with idempotence as it also shows up when you are implementing a REST service or dealing with HTTP calls in general. When implemented correctly, the GET, HEAD, PUT, and DELETE methods should be idempotent. A notable exception is the POST method. Statelessness A Pure Function should not depend on any state of the system. This means that neither the input nor the output should change the state. Web requests are often said to be stateless; each request can run independently of the other and still generate the same result. In Go terms, this also means that our function should not depend on things such as global variables, files on our filesystem, or general I/O operations. Side effects The properties mentioned previously tie together in creating functions that are free of side effects. A side effect is any operation that your function does that changes the state of your system. In the next chapter, we’ll dive deeper into what it means for the state to be immutable at the struct level. In this chapter, we’ll consider the state to mean the system within which your program is operating. Why does purity improve our code? So far, we have looked into some properties of purely functional code. We’ve also seen some examples of both pure and imPure Functions. Now, let’s look at what benefits we can expect from writing Pure Functional code. Increases the testability of our code When writing Pure Functions, your functions will be easier to test
  • Professional Scala
    eBook - ePub
    • Janek Bogucki, Alessandro Lacava, Aliaksandr Bedrytski, Matthew de Detrich, Benjamin Neil(Authors)
    • 2016(Publication Date)
    • Wrox
      (Publisher)
    Pure Functions, also known as “side-effect free,” are functions that take some value as an input and return a value without using any outside scope for the computations. Such functions are also called “referentially transparent.” That means a call to a side-effect free function may be directly replaced with its returned value. How can you find out if a function is not pure? If it accesses an outside scope or database, mutates input values, prints anything, or returns Unit, it has side effects. As an example of such functions, consider this:
    def helloWorld(): Int = { println("Hello") println("World") 42 }
    The function is not side-effect free, because it can't be replaced with its return value, a number 42, as there are still calls to a println() that do something, such as showing a string in the terminal. This is why it is not referentially transparent. This function, however, is pure:
    def add(a: Int, b: Int): Int = a + b
    It doesn't use any outside scope and it can be directly replaced with its return value, add(1, 2) , which can be replaced with 3 without any consequences. Otherwise, if the add() function stores something in the database, it can't be possible to replace the call with the results so easily.
    The benefits of Pure Functions are:
    • Improved testability: Your code doesn't need any mocks or dependency injections. A simple call to the function with predefined input values will always return the same result no matter what happens outside of it.
    • Improved readability: Methods are loosely coupled because there is no shared scope between them. You will not break the functionality by creating another Pure Function. Also method signatures are more explicit in side-effect free functions.
    • Improved performance: If your Pure Function is computation heavy, you may add caching to prevent it from recomputing the same value twice.
    • Improved concurrency: Side-effect free functions are thread safe, because they don't use any shared scope. This is especially important in concurrent code, as you will see in Chapter 11 . But for instance, imagine calling the helloWorld() function above by many threads at the same time. It would be impossible to predict in what order the words “Hello” and “World” would be printed!
    Though Pure Functions are great, it's often impossible to create an application without using functions with side effects. For instance, every access to a database is a side effect. The solution to this problem is to extract side-effect free code into separate functions with meaningful names and keep them as small as possible. For example, instead of:
  • Grokking Functional Programming
    • Michal Plachta(Author)
    • 2023(Publication Date)
    • Manning
      (Publisher)
    We say that Pure Functions are “easy to reason about.” We don’t have to build large models of state transitions in our brains to understand them. Everything a function can do is right there in its signature. It takes some arguments and returns a value. Nothing else matters.
    THIS IS BIG! Pure Functions are the foundation of functional programming.
    Mathematical functions are pure
    Pure Functions’ existence in programming is inspired by mathematical functions, which are always pure. Let’s say we need calculate the final price of a discounted item we want to buy. The discount is 5%. We get our calculator out and input the price, $20, then press * , then 95 (100% - 5%) and then we get rid of percentages by pressing / 100 . After pressing = , we get our final price: $19. What we just did, mathematically speaking, is
    f(x) = x * 95 / 100
    If the price is $20, we will pay only $19 after the discount! Pretty cool!
    For any given price x , the function f above will give us a discounted price back. So, if we give 20, 100, or 10 as x , calling f will give us the correct answers:
    f(20) = 19 f(100) = 95 f(10) = 9.5
    f is a Pure Function because it has three important characteristics:
    • It always returns a single value.
    • It calculates the return value based only on its arguments.
    • It doesn’t mutate any existing values.
    These three characteristics are the main focus of this chapter. We have already applied them in our real programming tasks and seen that we can trust more in our code if it’s built in a pure way. Now, it’s time to discuss the characteristics and rules of a Pure Function in depth. We’ll learn how to detect Pure Functions and what programming language primitives are needed to write them.

    Pure Functions in programming languages

    This is the pure mathematical function that calculates a discounted price:
    f(x) = x * 95 / 100 Math Both snippets do the same thing: they calculate 95% of a given value.
  • Functional Programming in C++
    • Ivan Cukic(Author)
    • 2018(Publication Date)
    • Manning
      (Publisher)
    Instead of saying you can’t change any state, let’s see how to design software in a way that keeps mutations and side effects to a minimum. But first, you need to better understand the difference between pure and nonPure Functions. In chapter 1, I said Pure Functions use the values of the arguments passed to them only in order to return the result. They need to have no side effects that influence any other function in your program or any other program in your system. Pure Functions also need to always return the same result when called with the same arguments.
    We’re going to define purity more precisely now, through a concept called referential transparency . Referential transparency is a characteristic of expressions, not just functions. Let’s say an expression is anything that specifies a computation and returns a result. We’ll say an expression is referentially transparent if the program wouldn’t behave any differently if we replaced the entire expression with just its return value. If an expression is referentially transparent, it has no observable side effects , and therefore all functions used in that expression are pure.
    Let’s see what this means through an example. You’re going to write a simple function with a vector of integers as its parameter. The function will return the largest value in that collection. In order to be able later to check that you calculated it correctly, you’ll log the result to the standard output for errors (std::cerr is the character error stream). You’ll call this function a couple of times from main
  • Index pages curate the most relevant extracts from our library of academic textbooks. They’ve been created using an in-house natural language model (NLM), each adding context and meaning to key research topics.