1

Consider these functions:

def f():
    print("WTF?!")

def g():
    print("WTF?!")

They both do exactly the same thing, but a test of f == g still gives False. Do I assume from this that functor equality is evaluated by reference, and that there is no difference between is and ==?

Whether or not that is the case, which one is better to use (even if only stylistically)?

By the way I'm primarily interested in Python 3 (Python 3.6).

EDIT

This question is not a duplicate, I think. I understand the difference between reference equality and value equality, I just want to understand how == uses value equality (if at all) on functors.

MSeifert
  • 145,886
  • 38
  • 333
  • 352
Ray
  • 7,833
  • 13
  • 57
  • 91
  • This kind of comparison doesn't really make sense. Python is not a functional language in that way. – Daniel Roseman Aug 10 '17 at 11:31
  • doing `print(f)` and `print(g)` will give you an idea was to why `f == g` returns `False` – Ma0 Aug 10 '17 at 11:31
  • @Chris_Rands thank you for pointing that out but I've read the main answer of that link (the rest TLDR so far) but that's not a duplicate. I understand the difference between reference equality and value equality, my question is about whether `==` uses value equality on functors and if so, how? – Ray Aug 10 '17 at 11:31
  • @Ray I removed my close vote, but what kind of comparison are you actually trying to do? What is your expected output for some examples? – Chris_Rands Aug 10 '17 at 11:32
  • @Ev.Kounis, my understanding is that `print(f)` and `print(g)` explains why `f is g` returns `False`, not why `f == g` returns `False`. – Ray Aug 10 '17 at 11:35
  • 1
    @Ray I see your point. But there is no such thing as the value of a function if the function is **not called** (`f` vs `f()`). And that is why, to my understanding, `==` boils down to `is` as @MSeifert explains below. – Ma0 Aug 10 '17 at 11:36
  • @Chris_Rands my use case is that I have some script (main function) to run some numerical simulation and I want to easily substitute different subroutines (`f` and `g`) and I want to have the main function to test which subroutine (functor `f` or `g`) is passed and do different things accordingly. – Ray Aug 10 '17 at 11:37
  • 1
    You can't really determine if two nonpure functions are equal. With pure functions you can decide on a discrete domain `R` and then run a test like this: `for x in R: if f(x) != g(x): break # f!=g` – mike3996 Aug 10 '17 at 11:38
  • 1
    And you can probably use the `dis` module to make an equality operator that compares if the functions `f` and `g` *are written* in a similar way if that helps you at all – mike3996 Aug 10 '17 at 11:39
  • 2
    relevant: https://stackoverflow.com/questions/20059011/check-if-two-python-functions-are-equal – Chris_Rands Aug 10 '17 at 11:42

2 Answers2

3

Function objects have no custom __eq__ method (this method is called when comparing values with ==) so they fall back to the superclasses __eq__ method. In this case it's object.__eq__ which, indeed, just compares if they are the same object.

So:

>>> f == g
False

is identical (in this case) to:

>>> f is g
False

Just in case your interested how I know that functions have no custom __eq__ method:

>>> type(f).__eq__ is object.__eq__
True
MSeifert
  • 145,886
  • 38
  • 333
  • 352
  • Perfect answer. I should have thought to test "type(f).__eq__ is object.__eq__" myself. – Ray Aug 10 '17 at 11:40
1

No you cant , because of this :

https://en.wikipedia.org/wiki/Rice%27s_theorem

ZAhmed
  • 1,232
  • 8
  • 15
  • 3
    Even though it's unlikely that the link goes stale it would be a better answer if you included the relevant portions in the answer itself. – MSeifert Aug 10 '17 at 11:37
  • It's reasonable to assume that the above functions produce the same bytecode, and thus can be trivially compared using a sequence comparison. – Joel Cornett Aug 10 '17 at 12:06