4

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
    I have no clue what the question is. Yes, both are methods. Yes, both are associated with a class. The one is a class method, the other is an instance method. – akuzminykh Feb 06 '21 at 23:26
  • 1
    Maybe also check out these: [What's the difference between a method and a function?](https://stackoverflow.com/q/155609/12323248), [Method vs Function vs Procedure](https://softwareengineering.stackexchange.com/q/20909/360199) – akuzminykh Feb 06 '21 at 23:48
  • How do you define a "pure function"? I believe that an answer would require knowing this. – NomadMaker Feb 07 '21 at 01:02
  • @NomadMaker Let's go with this: 'A pure function is a function that, given the same input, will always return the same output and does not have any observable side effect.' Taken from [here](https://github.com/MostlyAdequate/mostly-adequate-guide/blob/master/ch03.md), which at this time is one of the two main opening citations on the Wikipedia entry on [pure functions](https://en.wikipedia.org/wiki/Pure_function) – Jacob Archambault Feb 07 '21 at 04:03
  • @akuzminykh the distinction between class and instance methods is orthogonal to my question. To go with my earlier example, it would be trivial to have instead defined `addends.sum` to simply add two integer arguments, e.g. `myAddends.sum(2, 3)`. Ideally, such a method would be marked as static (since it wouldn't interact with its object's state), but it doesn't have to be (even if leaving this out would be bad design). – Jacob Archambault Feb 07 '21 at 04:22
  • You're going to run into terminology issues. Java doesn't have functions: it has methods. However, by your definition, most of the static methods of the Math class would be functions. The obvious exception would be Math.Random() because it returns a different number, most of the time. – NomadMaker Feb 07 '21 at 06:49
  • @JacobArchambault Is meriton's answer what you've expected or is your question still different? – akuzminykh Feb 07 '21 at 19:06
  • @akuzminykh meriton understands the question but I think the answer is importantly mistaken. Compare 'Q: Is multiplication by zero idempotent? A: Well, it depends on what you mean by 'zero'. If by 'zero' you mean 'two'...etc, etc.' Likewise, the first part of meriton's answer assumes the definition of a pure function is malleable in a way that it's simply not, since all major sources on the topic agree that pure functions by definition don't have side effects (e.g. logging). – Jacob Archambault Feb 09 '21 at 05:10
  • OTOH, the second part of the answer is really interesting and giving me a lot to chew on. – Jacob Archambault Feb 09 '21 at 05:11

1 Answers1

0

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.

meriton
  • 68,356
  • 14
  • 108
  • 175