I'll give you two examples. One functional and the other OOP. Both programs aim to simulate driving given an input of 10 energy units to find the final output energy.
#oop
engine = Engine(10)
car = Car(engine)
car.drive() #result 8
class Car:
def __init__(self, engine):
self.engine = engine
def ignite(self):
self.engine.energy =- 1
def run(self):
self.engine.energy =- 1
def drive(self):
self.ignite()
self.run()
return self.engine.energy
class Engine:
def __init__(self, energy):
self.energy = energy
# ignite not testable without engine
# run not testable without engine
# drive not testable without engine and a car
# ignite, run, and drive are not modular cannot be used without engine.
# engine testable with any integer.
# Car useless without engine
# engine useless without car
#functional \
def composeAnyFunctions(a,b):# returns function C from A and B. See illustration above.
return lambda x: a(b(x))
def ignite(total_energy):
return total_energy - 1
def run(total_energy):
return total_energy -1
drive = composeAnyFunctions(run, ignite)
drive(10) #result 8
# compose testable with any pair of functions
# run testable with any integer
# ignite testable with any integer
# drive testable with any integer
# all functions importable and reuseable with zero dependencies.
# input_energy -> ignite -> run -> output_energy
"I think the lack of reusability comes in object-oriented languages, not functional languages. Because the problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle." - Joe Armstrong
you don't necessarily need the car or engine to simulate the energy output of driving.