Core Principles Quiz: Pure Functions, Immutability, and Lazy Evaluation Quiz

Explore key computer science concepts with this quiz focusing on pure functions, immutability, and lazy evaluation. Assess your understanding of these foundational ideas essential for functional programming and efficient, predictable code.

  1. Pure Functions: Consistency

    Which statement best describes a pure function using the example of adding two numbers together?

    1. A function that returns a random number each time it is called
    2. A function that modifies global variables as it adds numbers
    3. A function that prints the sum to the console every time it is called
    4. A function that always gives the same output for the same inputs and causes no side effects

    Explanation: A pure function consistently returns the same result for the same arguments and has no side effects, like modifying external variables. Modifying a global variable or printing to the console introduces side effects and is not pure. Returning a random number makes the output unpredictable and dependent on more than just the inputs, so it is not pure either.

  2. Immutability: Variable Behavior

    In the context of immutability, what happens if you attempt to modify an immutable data structure like a string or a tuple?

    1. The program crashes immediately
    2. A new copy is created with the change, leaving the original untouched
    3. Only the last element is updated
    4. The original data structure is changed in place

    Explanation: When modifying immutable data structures, a new copy reflecting the change is produced, and the original remains unchanged. Changing the original in place is only possible with mutable types. Program crashes do not typically happen in such cases, and only updating the last element is unrelated to immutability.

  3. Lazy Evaluation: When Are Values Computed?

    Which best explains the concept of lazy evaluation in programming?

    1. Values are immediately removed from memory after use
    2. All computations are avoided to save memory
    3. All values are calculated at the start of the program
    4. Values are computed only when they are actually needed

    Explanation: Lazy evaluation means that a value or expression is computed only when it is required by the program, often increasing efficiency. Calculating all values at the beginning uses eager evaluation, not lazy. Avoiding all computations is impossible as some are necessary, and immediately removing values from memory is not a feature of lazy evaluation.

  4. Identifying a Pure Function

    Is a function that sorts a list but does not modify the original list considered a pure function?

    1. Yes, because any sorting is always pure
    2. No, because it does not return any value
    3. Yes, because it does not change the original list and the output depends only on the input
    4. No, because sorting is inherently impure

    Explanation: A pure function must not change its inputs and should produce the same output for the same input. If the original list remains untouched and the result relies only on its input, the function is pure. Sorting itself is not inherently impure; it depends on implementation. Not returning a value would typically mean the function has no useful output, and just saying 'any sorting is pure' is incorrect.

  5. Immutability and Thread Safety

    Why are immutable objects often considered safer for multi-threaded programs?

    1. Because they cannot be changed by any thread once created
    2. Because their type cannot be determined by threads
    3. Because they are always faster than mutable objects
    4. Because they automatically handle synchronization

    Explanation: Immutability ensures that once an object is created, it cannot be modified, so no thread can alter its contents. This reduces risks from concurrent modifications. While immutable objects can help with performance, they are not always faster. Their type is still known to threads, and immutability does not provide automatic synchronization.

  6. Example of Lazy Evaluation

    Given a function that generates an infinite sequence of numbers but only processes the first ten when needed, which concept is being used?

    1. Strict evaluation
    2. Mutable data structures
    3. Pure side effects
    4. Lazy evaluation

    Explanation: Generating values from an infinite sequence only as they are needed is an example of lazy evaluation, allowing efficient use of resources. Mutable data structures are unrelated to generating data on demand. Strict evaluation would compute the entire sequence, which is not practical for infinite data. 'Pure side effects' is not a standard concept in this context.

  7. Side Effects in Functions

    Which of the following is an example of a side effect that makes a function impure?

    1. Calculating a mathematical expression
    2. Receiving a value as a parameter
    3. Writing output to a log file from within the function
    4. Returning the sum of two numbers

    Explanation: Writing to a log file is a side effect because it changes something outside the function. Returning calculated values and receiving parameters are core parts of functional programming and do not introduce side effects. Merely calculating or returning math expressions does not affect external state.

  8. Effect of Immutability on Debugging

    How does using immutable data structures typically affect the debugging of software?

    1. It can make bugs easier to trace because values do not change unexpectedly
    2. It increases debugging complexity due to frequent value changes
    3. It hides variable types during debugging
    4. It makes debugging impossible because values never change

    Explanation: With immutability, data cannot be altered after it is created, which means changes are explicit and easier to track during debugging. This does not make debugging impossible; in fact, it can simplify debugging. Immutability leads to fewer unexpected changes, not more, and variable types remain visible during debugging.

  9. Pure Functions and Global State

    If a function accesses and modifies a global variable each time it is called, is it still a pure function?

    1. Yes, because it still has a return value
    2. No, unless the global value is always zero
    3. Yes, only if the global variable is not changed
    4. No, because accessing or changing global state creates side effects

    Explanation: A pure function must not produce or rely on side effects, and modifying or even reading a global variable counts as such. Simply having a return value does not guarantee purity. Not changing the variable still constitutes relying on outside state. The value of the global variable does not permit side effects in pure functions.

  10. Evaluation Strategies: Lazy vs. Eager

    How does lazy evaluation differ from eager (strict) evaluation when processing a list of values?

    1. Lazy evaluation does not support functions with parameters
    2. Lazy evaluation computes each value only when required, while eager evaluation computes all values immediately
    3. Lazy evaluation calculates values twice for accuracy, while eager evaluates only once
    4. Eager evaluation ignores unused values, but lazy uses all of them

    Explanation: Lazy evaluation postpones computation until a value is needed, increasing efficiency in some cases. Eager evaluation computes everything upfront, regardless of necessity. Lazy evaluation does not calculate twice for accuracy and fully supports parameters. Eager evaluation does not ignore values; it computes all, even if unused.