-3

A pure function is one which given the same arguments, will always return the same result and will have no side effects.

So Sum(x,y) => x + y; is pure because it meets this criteria.

However, in a language like C# where you can have properties, this makes things more complicated...

class Summer
{
  public int X { get; set; }
  public int Y { get; set; }

  public int Sum() => X + Y;
}

In the above, can Sum be considered to be pure? Can you make the argument that X and Y are still just parameters to the function?

Or would it be better if refactored to something like:

class Summer
{
  public int X { get; set; }
  public int Y { get; set; }
}
static class SummerExn
{
  public static int Sum(this Summer s)
  {
    return s.X + s.Y;
  }
}

In the extension method, s is a parameter so this meets the criteria for being pure I think, but realistically there is no practical difference since the underlying variables are the same. Would there be a technical reason this code is better, such as being more easily tested, faster, more memory efficient, easier to logically reason about etc. ?

Chris
  • 107
  • 5
  • If you're worried about the class mutating and don't consider that as "different arguments" then just make the class immutable. `class Summer{ public Summer(int x, int y) => (X,Y) = (x,y); public int X {get;} public int Y{get;} public int Sum() => X + Y;}` – juharr Sep 23 '21 at 20:50
  • 1
    i would say only if the properties themselves are pure. – Daniel A. White Sep 23 '21 at 20:51
  • 2
    The version with an X and Y property and calling Sum() gets X and Y is not pure. Easy to prove: Call `Sum()`, get 0. Set `X` to 1. Call `Sum()` get 1. Called with the same arguments, got different results. – Heretic Monkey Sep 23 '21 at 20:52
  • The properties do (and need to) mutate over time, but the counter argument is that if I do: ```cut.X=5; cut.Y=5; cut.Sum() /* 10 no matter how many times I do it */ cut.X = 6; cut.Sum(); /* arguably still pure but being called with different parameters */``` – Chris Sep 23 '21 at 20:57
  • 2
    This has now been closed as being opinion based - I'm not sure this is correct. A function is either pure or it isn't, and my question was "is this pure". Can anybody suggest an edit to make this clearer? – Chris Sep 23 '21 at 21:04
  • 1
    May be helpful: https://stackoverflow.com/questions/65872468/is-this-javascript-function-taking-a-mutable-reference-argument-a-pure-functio – jaco0646 Sep 23 '21 at 23:43
  • @jaco0646 yes that's a similar idea and is interesting, thank you. I think it's still open as to whether there's more merit one way or the other but maybe that goes too far into opinion rather than objective fact... – Chris Sep 24 '21 at 07:27
  • *"Is this better? If so, is there a good reason it's better, or just a matter of taste? Is there another good way to do this that I've not thought of?"* "Better", "good", "matter of taste" are all opinion-seeking words and phrases. Your question is not just "is this pure". – Heretic Monkey Sep 24 '21 at 12:29
  • @HereticMonkey no, that's not the context I used though. I didn't ask "what is your taste?" on its own, I was asking "is there a technical reason for one or the other?". If the answer to that is "no there's no technical reason for either, it's just opinion" that's a valid answer that would be factual. I think the context is important rather than just applying "grep" to the question. Similarly "better" is ambiguous because it could be "more memory use but faster" or "slower but easier to understand" or any combination that would promote one over the other. – Chris Sep 24 '21 at 16:46
  • You were not asking "is there a technical reason"; you literally ask "is there a good reason it's better, or just a matter of taste?" There'd be no problem if you asked for facts and evidence. I'm not just running a grep; I'm reading the question. If you're not interested in editing your question to make it seem less opinion based, why ask? – Heretic Monkey Sep 24 '21 at 17:22
  • 1
    By your definition of pureness, your second method is actually not pure, because it may be passed "the same" reference to a single `Summer` object multiple times and come out with different results (if `Summer` has been mutated inbetween). Of course the exact same argument applies to the first method if you consider `this` to be a hidden parameter. In other words: there is quite literally no difference and there cannot be, as long as you mix in references to mutable objects. You can have methods that will not modify state and so are easier to reason about, but that's not the same thing. – Jeroen Mostert Sep 24 '21 at 20:32
  • @HereticMonkey To post a question you have to simplify your question so that you aren't posting too much code. Then everybody says "this is an X-Y problem" so you have to post extra detail to explain why it's not (it always looks like that once the context is removed, in part because I do actually research before asking a question). Once you do that, one wrong word choice and instead of understanding the question everybody wants to argue with your English, which may not be your first language. This said, I've taken your suggestions and tried to tidy up the wording, thank you. – Chris Sep 24 '21 at 20:43
  • @JeroenMostert thanks, I hadn't thought about it in terms of references, that's a good point. I guess it follows that it can only be pure if it only takes value types that are passed by value. – Chris Sep 24 '21 at 20:48
  • 1
    Not quite -- all that's needed is immutability, since then by construction no method can modify state, and then all methods are pure as long as they don't reference outside state. You can make immutable reference types in C#, it just takes a bit more effort. The new `record` feature makes this easier, as records are immutable by default. – Jeroen Mostert Sep 25 '21 at 05:55

1 Answers1

-1

Your example doesn't meet the definition you gave:

A pure function is one which given the same arguments, will always return the same result...

Every call is given the same arguments (none) yet obviously can return different results. Another definition from Wikipedia makes this a little more explicit:

The function return values are identical for identical arguments (no variation with local static variables, non-local variables...)

Properties are non-local variables.

And to be especially pedantic, not only is your example not a pure function, it's not a function at all. A function-like thing that's a non-static class member is called a method.

Tech Inquisitor
  • 343
  • 1
  • 7
  • Thanks, but I'm not sure I understand - the wikipedia definition doesn't say it can't use non-local variables, just that there can't be variation in them, unless I'm misreading it. If I don't change the property values between calls, the result would be the same each time I call it. Also, I'm aware C# calls this a method, but is this an important distinction here? I'm all for being pedantic if it helps it to be clearer. – Chris Sep 24 '21 at 20:53
  • 1
    It matters that it *can* change, not that it did or didn't in a particular case. A function that isn't pure because it sometimes mutates external state doesn't become pure when it doesn't mutate state. A function that returns a different value when external state changes doesn't become pure when the state doesn't change. – Tech Inquisitor Sep 24 '21 at 21:33