# FOIL Python's strong typing!

Your task is to write some code in Python 2 or 3 such that this expression:

(a+b)(c+d) == a*c + b*c + a*d + b*d


will evaluate to True without raising any exceptions.

To clarify, I will copy your code into a file, then from the file import *. Then I will type the expression into the console and verify that it is True.

This is code-golf, so the answer with the shortest length (in bytes) wins.

## 545250494845 39 bytes

Removed 4 bytes thanks to Dennis.

The latest version is inspired by the "some reason" in xnor's answer.

class t(int):__add__=type
a=b=t()
c=d=0

• Nice! There's 0 .__mul__ for lambda y:0 but it's the same length. – xnor Oct 28 '16 at 23:28
• x.count saves a byte. – Dennis Oct 28 '16 at 23:36
• I don't get it... type(t(), t()) or t().type(t()) throws an exception, so what is happening when you do t() + t()? – feersum Oct 29 '16 at 3:56
• @feersum __add__ is called with two, but the first is interpreted as self, only other is passed to type. Weird, yes. – Jonathan Allan Oct 29 '16 at 10:12
• @feersum: a + b first tries a.__add__(b). a.__add__ is type, so that becomes type(b). The key difference between this case and the usual case for methods is that usually, a.__add__ would be a different object from the thing you set __add__ to in the class definition, due to the descriptor protocol, which ordinary function objects implement. (There are also a few other tricky bits that aren't relevant here.) – user2357112 supports Monica Oct 29 '16 at 18:25

## 54 bytes

class m(int):__call__=__add__=lambda*x:m()
a=b=c=d=m()


Make an object that inherits from int, except adding or calling just returns a copy of itself.

Same length:

class m(int):__call__=__add__=lambda a,b:a
a=b=c=d=m()


I thought min or {}.get would work in place of lambda a,b:a, but for some reason they act only on the second argument.

• (it's code-golf) – Addison Crump Oct 28 '16 at 23:10
• Oops, I only saw programming-puzzle, will golf. – xnor Oct 28 '16 at 23:11
• That was quite a reduction o-o – Addison Crump Oct 28 '16 at 23:19
• @xnor It doesn't work because min already has a __self__ attribute, so the class skips binding its own self. Why min has __self__ is another question... – matsjoyce Oct 29 '16 at 19:00
• @matsjoyce: No, it doesn't have anything to do with the fact that min has a __self__. min.__self__ is just an artifact of how built-in functions and built-in methods are implemented as the same type. min doesn't work here because unlike functions written in Python, built-in functions don't support the descriptor protocol, which is responsible for binding the first argument. – user2357112 supports Monica Oct 30 '16 at 1:07

# 81 66 bytes

class e:__mul__=lambda*o:0;__add__=lambda*o:lambda x:0
a=b=c=d=e()


### 68 bytes

While it cannot really compete with the existing answers, this one actually performs the calculation in question:

from sympy.abc import*
type(a+b).__call__=lambda x,y:(x*y).expand()


Explanation:

• SymPy is a module for symbolic computations.
• sympy.abc contains all single-letter symbols, in particular ones named a, b, c, and d.
• a+b is an Add object, which represents a general sum.
• type(a+b).__call__= […] monkey-patches the Add class to give it evaluation capabilities, in this case enabling it to work like a multiplication of caller and callee.
• expand is necessary to make the expressions actually equal (since SymPy only performs thorough equality checks on demand).