Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It's not really a typing problem, it's a problem of references. You can't add 1/3 apples and 1/3 oranges. However, you can add 1/3 * x people with 1/3 * y people and get 2/6 * z people, if x people +y people =z people.


You definitely can add 1:2 apples and 1:2 oranges, you just need to do so using a common base type (such as fruits or objects).

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't perform operations with apples, oranges and fruits unless you use them completely interchangeably ,i.e. 1 apple = 1 orange. Otherwise, you will break algebraic equalities.

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 grandparent's note about units and your mention of ratios get at the same problem for me:

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"


This does nothing to elucidate the problem. 1/3 apples + 1/3 oranges could be 2/6 fruits, or 2/781 fruits, or any other number you want. In normal mathematical notation, 1/3 is interpreted as 1/3 of 1, and in that case 1/3 apple + 1/3 orange is 2/3 fruit.

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.


You're being dishonest in your reasoning.

> 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.


you can. It's what you do in fruit salad.


Well, in fruit salad 1/3 apple + 1/3 orange = 1/3 apple + 1/3 orange. I can say 3 * (1/3 apple + 1/3 orange) = 1 apple + 1 orange.

And then by way of analogy of course, (e apples)^(pi oranges) + 1 apple = 0.


I think you both are saying the same thing, in this context at least.


There is a very important difference between types and quantities.

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).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: