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

I'm all for proper rants against popular tools to keep people on their toes.

This isn't one of those.

"Objects bind functions and data structures together in indivisible units. I think this is a fundamental error since functions and data structures belong in totally different worlds."

Sure—a class defines a type and operations on that type. What's fundamentally wrong about date.addDays(1) vs. date_add_days(date, 1)? (Let's skip the mutable state argument and assume both versions return a new date.)

There is the problem that sufficiently opaque classes are hard or impossible to extend. That's the class author's fault: this is an avoidable problem in every object-oriented language I've used.

"Functions are understood as black boxes that transform inputs to outputs. If I understand the input and the output then I have understood the function. … Functions are usually 'understood' by observing that they are the things in a computational system whose job is to transfer data structures of type T1 into data structure of type T2."

A constructor is a black box that converts a data structure of type T1 into a data structure of type T2. Objects just also have other black box functions defined on them.

Sure, some objects are stateful, but they don't have to be.

"In an OOPL I have to choose some base object in which I will define the ubiquitous data structure, all other objects that want to use this data structure must inherit this object."

Um, no. This is a job for composition, not inheritance.

"Instead of revealing the state and trying to find ways to minimise (sic) the nuisance of state, they hide it away."

They hide state's implementation, for mutable objects.

  std::vector<std::string> some_list;
  std::cout << "Items: " << some_list.size() << std::endl;
  some_list.push_back("Hello, world!");
  std::cout << "Items: " << some_list.size() << std::endl;
  // Oh no! State, EXPOSED!
Sure, an allocated piece of memory might have grown, or even moved. Why should I care? I still see the state I care about, presented through a hopefully useful abstraction.

This rant seems to somehow miss the points of both object-oriented and functional programming, instead harping on mostly meaningless (or outright wrong) details. Or am I missing something here?



> What's fundamentally wrong about date.addDays(1) vs. date_add_days(date, 1)?

One issue involves cross-cutting concerns. Say I'm creating a JSON API for my system. I use an API framework that lets me return objects that implement a JsonSerializable interface, and the framework calls to_json() to create the actual network response. The built in container classes (Hash, Array, etc.) implement this interface already, calling to_json() on their elements. I make all my core domain classes implement a JsonSerializable interface with to_json() methods. Now I can return an array of objects and it just works. Very straightforward.

Problem 1: I only need to_json for the API, but now that code is available everywhere. Every time I change my JSON API, it requires recompilation and testing of every component of the system, whether or not they are even related to the API.

Problem 2: Next I go on to add an XML API, HTML representations, database persistence, third party API integration. All those concerns go into my core domain classes, which become quite bloated. I could use decorator classes, but they require me to be aware of whether I'm using a decorated or non-decorated object. They also add a lot of boilerplate. Code becomes both bloated and ugly.

Problem 3: Next I need a new version of the JSON API, to be run concurrently with the old one. The new version is going to serialize things in a different style, so each class needs two versions of to_json(). I could make a to_json2(), but how would the API framework know to call it? I fork the framework. Now I have to merge my changes every time they release a new version of the framework. Code is bloated, ugly, and unmaintainable.

Problem 4: Next I need to return API responses with classes from third party libraries, for which I don't even have the source to fork. Fuck.

Ultimate solution is to wrap everything -- foo_as_json(foo), bar_as_json(bar), foo_as_xml(foo). It's ugly as hell but it's the only thing that basically works.


I owe the author an apology on one point. "Minimise" is a correct spelling, though neither my system's dictionary or I realized this.


I think minimise vs minimize is just British vs American spelling respectively. So neither is strictly wrong.




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

Search: