Python and Plato (1) — Using Python to Introduce the Great Philosopher
Who was Plato?
‘A picture speaks a thousand words’.
This is a painting I’m sure everyone would recognise.
It is known as ‘The School of Athens’ by Raphael, the renaissance artist.
At the centre of the picture are Plato and Aristotle.
- Plato points upwards — did you notice?
- Aristotle gestures towards the ground.
That captures the essence of the two giants of philosophy.
- Plato looks upwards to the eternal realms we cannot reach.
- Aristotle seeks truth, first and foremost, in the created order.
Python?
I promised that this would be related to Python somehow.
I’ll try my best.
Forms
Plato believed that there was something known as ‘Forms’.
They are entities that reside in a perfect realm, beyond our immediate senses.
As human beings, he would say, we can perceive what is good.
- The “goodness” of a gulp of fresh water on a hot day.
- The “goodness” of seeing the combination of colours on your code editor.
But there are different, perhaps nobler, kinds of goodness:
- The goodness of a warm hug from a friend in times of trouble.
- The goodness of an embrace from a loved one or a partner.
Because we are able to hold a diversity of goodness in our minds, Plato concludes:
Since these things are so, we must agree that that which keeps its own form unchangingly, which has not been brought into being and is not destroyed, which neither receives into itself anything else from anywhere else, nor itself enters into anything anywhere, is one thing.
- from Timaeus
Essentially:
The most fundamental, exalted, eternal, unchanging — Goodness - must exist.
- Me
It must also exceed what we can immediately perceive and understand.
Python Iterators
One analogue I can think of in Python is the Iterator class.
According to the docs:
The iterator objects themselves are required to support the following two methods, which together form the iterator protocol:
iterator.__iter__()
Return the iterator object itself. This is required to allow both containers and iterators to be used with the for and in statements. This method corresponds to the tp_iter slot of the type structure for Python objects in the Python/C API.
iterator.__next__()
Return the next item from the iterator. If there are no further items, raise the StopIteration exception. This method corresponds to the tp_iternext slot of the type structure for Python objects in the Python/C API.
So let’s say we try to implement a class which has these two methods, “Sentence”:
import re
import reprlib
RE_WORD = re.compile(r'\w+')
class Sentence:
def __init__(self, text):
self.text = text
self.words = RE_WORD.findall(text)
def __repr__(self):
return f'Sentence({reprlib.repr(self.text)})'
def __iter__(self):
return SentenceIterator(self.words)
where SentenceIterator has the __next__ dunder method:
class SentenceIterator:
def __init__(self, words):
self.words = words
self.index = 0
def __next__(self):
try:
word = self.words[self.index]
except IndexError:
raise StopIteration()
self.index += 1
return word
def __iter__(self):
return self
Taken from Ramalho, Luciano. Fluent Python (pp. 607–608). O’Reilly Media.
Let’s verify that an instance of Sentence is an Iterable.
s = Sentence('It is time to learn Philosophy from Plato, Pythonistas.')
# try it out - to get a feel for what is iterated over
for word in s:
print(word)
from collections import abc
print(isinstance(s, abc.Iterable)) # returns True
isinstance(s, abc.Iterable) returns True.
Diversity of Iterables
So there are many things in the world that can be represented by iterables.
Sentences, thoughts, random-number-generators, days of a year, a puppet that can only say ‘hallo’ when you press its button somewhere.
But all these things come down to having the __iter__ and __next__ dunder methods. (In the goose typing approach.)
Inheritance Not Needed
For Plato, things of beauty don’t have to be biologically related to each other.
A beautiful dog can of course give birth to beautiful dogs.
But a thing can be beautiful without having to be a descendent of some other beautiful thing.
Similarly, Python doesn’t require a class to inherit abc.Iterable in order for a class to be an iterable.
The whole idea of Plato’s Philosophy is to understand what the essence of fundamental forms is.
It’s easy for us, because we’ve simply defined what an Iterable is.
But the task of the Philosopher is not as easy.
Exeunt
I don’t know if they clapped in Plato’s school, The Academy, shown at the top of the article.
But if this somehow inspired you, feel free to imagine yourself to be in the hallway of the Academy and make a resounding noise.