Can pure functions exist in pure object-oriented programming languages?

1k Views Asked by At

For the purposes of this question, by 'pure object-oriented programming language' I mean one in which functions can only exist inside (static or non-static) objects, i.e. as methods.

Consider the following Java code:

import java.lang.Math;

class Program {

     public static void main(string[] args){
          Math.addExact(2, 3);
          new Addends(2, 3).sum();
     }
}

final class Addends {
     private final int addend1;
     private final int addend2;
     Addends(int x, int y){
        addend1 = x;
        addend2 = y;
     }

     final int sum(){
        return addend1 + addend2;
     }
}

In this example:

  1. Is Math.addExact a pure function?
  2. Is Addends.sum a pure function?

The answer to the first depends on how methods are understood to relate to functions, i.e. whether methods are considered kinds of functions or merely their nearest OOP equivalent.

The answer to the second depends on whether fields whose values are injected into an object may be considered inputs for an associated method using those fields (assuming a pure function to be one that gives the same output for the same inputs). The reason for thinking so is the recognition that for any object and particularly for those exhibiting high cohesion, it's fairly easy to convert any n-parameter method in it into an n - m-parameter method by requiring its enclosing object be instantiated by injecting m values, assigned to m immutable fields, into an m-parameter constructor for that object.

NOTE: I recognize the answer to this question is going to be partly a matter of semantics/convention. I'm asking whether there happen to be agreed upon conventions on this matter, and if so, what they are.

CLARIFICATION AFTER QUESTION WAS CLOSED AS OPINION-BASED: As stated above, I'm not asking for the opinions of individual contributors on this question: I'm asking whether there is convergence among programmers and/or computer scientists on examples like those given, based on a) whether methods are considered functions, and b) how broadly 'input' is construed in the definition of a pure function; and if there is convergence, what it is. Compare

  • Opinion-based: What is morality?
  • Not opinion-based: How is morality defined on Wikipedia?
  • Disputed: Do uncountable sets exist?
  • Not disputed: is the existence of uncountable sets provable in classical set theory (yes)? What about in intuitionistic set theory (no)?
1

There are 1 best solutions below

0
On

In mathematics, a function is a mapping that maps inputs to outputs such that every input maps to exactly one output.

When computer sciencey people talk about "pure functions", they mean something that can be treated like a mathematical function.

And that's pretty much all everyone agrees on. You see, whether we can treat something "like a mathematical function" depends on what we are interested in. It also depends just how we translate computer code into the realm of mathematics.

Why our interest matters

The method

int foo(x) {
    logger.trace("foo was called with {}, x);
    return x * x;
}

is pure if we don't care about log entries, but impure if we do.

The method

int max(int x, int y, int z) {
    return IntStream.of(x, y, z).max().get();
}

is pure if we don't care about object allocation, or that the IntStream class will be initialized, but impure if we do.

Why the translation into mathematics matters

When dealing with an object oriented programming language, there is the obvious challenge that methods are attached to objects, but mathematical functions aren't. We can deal with in two ways:

  • We can pretend the function is not affected by the object it is attached to. That is, given a method

    int f(int x) {
        return x + 1
    }
    

    we treat it like the function

    f(x) = x + 1
    

    This can be entirely adequate for many purposes.

  • Or we can treat this, and the state reachable through it, as implicit parameters to our function. For instance, if we have

    int f(int x) {
        return x + this.x;
    }
    

    we would treat this as the function

    f(heap, this, x) = x + heap(this)("x")
    

    where heap is function that takes an object reference, and returns a function that takes a field name and returns the value that field currently has for that object.

Both approaches can be useful, but which one is better depends on what you are after. And that's why, when somebody talks about pure functions, you should ask them which definition they use.