Hacker News new | ask | show | jobs
by hotBacteria 2563 days ago
I like the shapes problem because I actually encountered it and it made me think.

I'm not sure about the switch approach described in the post:

  function area(shape)
    switch shape.type
      case "square": return shape.side ** 2
      case "circle": return 2 * PI * shape.radius
      case "triangle": return ... 
      case "segment": return 0
      case "polygon": return ...
      ...
      case "oval": return ...
You can have a lot of cases, some of them requiring non trivial code... Eventually you write a function for each case and it's more work than adding a method for each shape because you still need to write the switch...

Classes seem work better than structures here.

But then you want to handle intersections

The switch approach doesn't seem realistic:

  function intersection(shapeA, shapeB)
    if(shapeA.type == "circle" AND shapeB.type == "circle")...
    if(shapeA.type == "circle" AND shapeB.type == "square")...
    if(shapeA.type == "square" AND shapeB.type == "circle")...
    ...//uh oh you have nShapes**2 cases to handle
But java classes or not better: where do you define Circle-Square intersection? In Circle? In Square?

Even with multiple dispatch the solution is not ideal. You now have some things related to Circle (area, perimeter...) in the Circle.blub file, and intersection(Circle, Circle) wich only works with Circles is now in intersections.blub...

I don't see a good solution and sometimes I feel like the problem is more with our tools (code in text files) rather than programming paradigms

2 comments

I have to admit I don't quite understand your issue. To me it seems like you've used a lot of OOP and cannot befriend the idea that the data structure (e.g. "Circle" in file GeometryTypes.blub) and operations that are performed with it (e.g. collisions in "CollisionDetection.blub") are completely separate. There should be no discussion whether the circle type and collision belong in the same file, while combinations are in some other file. Think of it like this: if you're going to add 3d rendering of circles, will you put that in Circle.blub together with collision detection? Wouldn't you rather add it to 3DRenderer.blub?

That said, ultimately it doesn't really matter. If you're going to implement collision detection like this, then yes, you will have a combinatorial explosion. This is not a language issue. Switching from Java to some other language with a different form of dispatch will not save you from implementing a lot of algorithms when adding bezier curves into the mix.

The practical approach is reduce the problem to a common case, e.g. to turn the collision shapes into a set of triangles first, and then perform triangle-triangle collision detection.

Business logic tends to be more organic than the rules of geometry and physics. Thus, many of the "toy" OOP examples that use shapes and physics don't extrapolate well to real world abstractions, which often turn out to be semi-abstractions. Geometry and physics generally don't change so we know certain patterns will always stay around. Business logic (the domain) is often NOT like this. Be careful.