This is another instance of situations where teaching compsci or at least programming could help teaching maths rather than the other way around as it is traditionally thought.
This is another instance of situations where teaching compsci or at least programming could help teaching maths rather than the other way around as it is traditionally thought.
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).
[<Measure>] type lbFeather
[<Measure>] type lbGold
[<Measure>] type lbLead
let convertGoldToLead ( weight : float<lbGold> ) = 1.0<lbLead> / 1.0<lbGold> * weight
// works
let barOfGold = 1.0<lbGold>
let barOfLead = convertGoldToLead barOfGold
// doesn't work
let bagOfFeathers = 1.0<lbFeather>
let leadDuck = convertGoldToLead bagOfFeathers
// Error reported: mismatched units.