Note that I'm using ratio notation because the answer for the above is not the same as adding 5:10 apples and 1:2 oranges; in other words, the exact numerator and denominator both matter, so it's not really a simple fraction; a simple fraction can be reduced to its lowest terms (e.g. 5/15 becomes 1/3), but you can't do that here and still support the mediant operation. https://en.wikipedia.org/wiki/Mediant_(mathematics)
You can convert apples to fruit and oranges to fruit and then do operations on fruit, but you can't go back from the result to apples and/or oranges. For example, 1/7 of (3 apples + 4 oranges) is 1 fruit, but we can't tell if it's one orange, or 1 apple, or 1/3 apple and 2/3 orange.
The lesson mixes two of the physical world concepts that are often modeled by fractions.
One is an incomplete whole (the six pack) and the other is the proportions of a mixture (table demographics).
Fractions always have the same rules, but the rules map differently to the different territory being modeled.
abstract class Fruit:
prop name: string
prop rotten: bool
class Apple (Fruit):
prop name: string = "apple"
prop rotten: bool = False
class Orange (Fruit):
prop name: string = "orange"
prop rotten: bool = False
func add (a: List<Fruit>, b: List<Fruit>) -> List<Fruit>:
return foldl(lambda l, f: l.append(f), a, b)
func filter (p: Func<[Fruit], bool>, l: List<Fruit>) -> List<Fruit>:
return [f for f in l if p(f)]
func is_rotten (f: Fruit) -> bool:
return f.rotten
a1 = Apple()
a2 = Apple()
a3 = Apple()
a3.rotten = True
apples = [a1, a2, a3]
o1 = Orange()
o2 = Orange()
o3 = Orange()
o3.rotten = True
oranges = [o1, o2, o3]
fruits = add(apples, oranges)
print(len(filter(is_rotten, apples)), "/", len(apples))
> "1/3"
print(len(filter(is_rotten, oranges)), "/", len(oranges))
> "1/3"
print(len(filter(is_rotten, fruits)), "/", len(fruits))
> "2/6"And of course this only works if 1 apple = 1 orange = 1 fruit, which means that they are the same unit of measure, or, equivalently they are of substitutable types. It's even debatable of it's correct to say that 'if I have 1/3 of an apple and 1/3 of an orange, I have 2/3 of a fruit', so depending on what you want to do with your apples, oranges and fruit, your hierarchy may in fact break Liskov substitution. For example, if 1 apple + 1 orange = 2 fruit, so 2 fruit - 1 apple = 1 orange, so 1 apple = 1 orange, which is not true.
> In normal mathematical notation, 1/3 is interpreted as 1/3 of 1
Why would you deny the possibility of 1 being 1 list of fruits rather than 1 fruit?
In the original example, it was 1 table of students, not 1 student.
Everything you say after that is based on this broken assumption.
And then by way of analogy of course, (e apples)^(pi oranges) + 1 apple = 0.
For example, 1/3 + 1/3 = 1 is true, if I mean 1/3 of 3 + 1/3 of 0. 1/3 + 1/3 = 2/6 can only be true if we add some quantities, we can't make it true by choosing the right types (we could fix it by choosing a different definition of +, or =, though).