[I have send this on icon-group, but I didn't seen it appeared, so I'm sending it here. Sorry if you seen it twice. ]

Few years ago, I noticed that this simple Tax payer problem is surprisingly hard for OO programming. Actually, because of that problem I finally concluded that OO is too much complication for too little power and gave up from it.

Icon solution is, however, very elegant.
==================
1) Write program that calculates tax for different persons.

2) Each person is member of some group (soldier, professor ... ), and each group has own rules for tax calculations. For example, tax for soldiers is salary/10.

3) For addition of each new group (and tax rule) one should write only one new function (or class), somewhere in the code. Existing code should not be changed!

Until now, it was easy but ...

4) One person can be member of a few groups in the same time (and membership can change during run time)

5) In that case, tax is maximum of all taxes calculated on the basis of groups membership.


====================================


# GENERAL PART, UNNECESSARY BUT MAKES SPECIAL PART PRETTIER

procedure poly(s,X)

  # returns list [proc(s||t1)(X),...,proc(s||tn)(X)]
  # where t1,...,tn are elements of X.member_of

  result:=[]
  every ti:=!X.member_of do
    put(result, proc(s||"_"||ti)(X)) # <= most important line
  return result
  end

procedure max(L)

  if *L > 0 then
    {
      result:=L[1]
      every result <:= !L
      return result
    }
  end

# SPECIAL PART

invocable all
record person(salary, member_of) #member_of is special!

procedure tax_soldier(X)
  return X.salary/10.0
  end

procedure tax_professor(X)
  return X.salary/20.0 + 100
  end

procedure tax(X)
  return max(poly("tax",X)) # :^)
  end

procedure main()
  A:=person(1000.0, [ "soldier" ])
  B:=person(1000.0, [ "professor" ])
  C:=person(1000.0, [ "soldier", "professor" ])
  write(tax(A) ,", ", tax(B) ,", ", tax(C)) # this line is goal
  end

# THATS ALL.


----
Kazimir Majorinc, Zagreb, Croatia

Reply via email to