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

I encourage you to read Philip Wadler's essay The Expression Problem, which addressed precisely the dilemma you point out:

http://www.daimi.au.dk/~madst/tool/papers/expression.txt

In brief, if you think of data types are rows, and behaviors as columns, the question is how to extend either the rows or the columns naturally.

In your example, it is easy to add a new row (datatype) – create a Triangle class which implements the Drawable interface. It is difficult to add a new column (behavior) – if you realize all of these datatypes should also have a "extrude to additional dimension" behavior, you're going to have to individually implement that in all of your different classes, across many different files, etc. All of the problems that you note arise when adding a new datatype in the FP strawman.

It's important to recognize that this is indeed a difficult problem, and that addressing it well takes real care.

The c2 wiki has a good distillation:

http://c2.com/cgi/wiki?ExpressionProblem

and this paper (by the Scala people) is very nice:

http://www.scala-lang.org/docu/files/IC_TECH_REPORT_200433.p...

Some approaches that languages take, to varying degrees of success, include typeclasses in Haskell, multimethods in Clojure and elsewhere, the Visitor or Extended Visitor patterns in OO languages, controllable extensions in C#, Ruby, and Scala, etc.



Thanks for the sources - will sit down and read them later.

The row, column analogy is pretty apt - it's an interesting way of looking at things.

While it is true that adding a new behaviour in OOP is a pain in the ass, I definitely find myself adding new datatypes far more frequently than adding new behaviours for an interface.

Isn't adding a lot of new behaviours to data typically a sign than the interface is bloated and is now dealing with too many things?




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

Search: