News for hackers. Stuff that matters.
Re:A Dangerous Obsession with Primitives by carsongross on Thursday May 31, 2012 @11:43AM (#4048598)
This is what refactoring is for. Start out simple (maybe a primitive is all you need) and then, if and when the need arises, refactor and introduce a value object. That's where the failure is in this story.

I've seen a lot of premature abstraculation blow up the opposite way: incomprehensible, elaborate object models attempting to be The Best Abstraction Evar around fundamentally simple concepts. These things can be hard to work with and change, contribute difficult to discern complexity to applications and cause huge performance headaches.

You aren't gonna need it, worse is better, simplicity of implementation above all else.

Re:A Dangerous Obsession with Primitives by famousactress on Thursday May 31, 2012 @11:58AM (#4048698)
Yes Yes Yes, this. The world is littered with code that never made a dent in the world but was uber-prepared for the day that we'd suddenly need a new way to talk about numbers/dates/strings.
Re:A Dangerous Obsession with Primitives by jdlshore on Thursday May 31, 2012 @02:56PM (#4049711)
It's not quite that simple. Primitive obsession is a form of duplication, and it's particularly difficult to spot without practice. Once found, it can be a real bear to remove. Chapter 4 of my screencast [1] shows this; it took me an hour and a half to refactor a trivial application to remove its primitive obsession. (And there's strong case to be made that some of the difficulty I had in earlier episodes was due to primitive obsession as well.)

I agree that premature abstraction is a pain, too, so I wouldn't want to go down that route. However, preventing primitive obsession can be as trivial as using a two-method wrapper class. More methods and abstraction can be added on an as-needed basis. Also, removing the wrapper class is automatable with the "Inline Method" refactoring in some IDEs.

So the design tradeoffs I see are:

1- Primitive obsession: high duplication burden, high complexity burden, hard to remove

2- Wrapping primitives that don't need it: low complexity burden, easy to remove

So I prefer to error on the side of wrapping primitives. That said, I've never actually encountered a case where I wrapped a primitive that didn't need it, and I still accidentally create the primitive obsession smell a lot. It seems so innocuous at first.

[1] http://jamesshore.com/Blog/Lets-Play/

Re:A Dangerous Obsession with Primitives by skybrian on Thursday May 31, 2012 @04:36PM (#4050211)
That's language-specific advice. Go handles this much more elegantly. You can create a Celsius type very simply:

type Celsius float64 // Temperature in degrees Celsius

It's no harder to use than 'typedef' in C and similarly it doesn't get in your way, but you get a real type and nice errors when you screw up. There's no reason not to do it right away.

Re:A Dangerous Obsession with Primitives by swanson on Thursday May 31, 2012 @12:34PM (#4048867)
Thanks for the comment, I definitely agree that this should have been picked up in a refactoring. I've also been on other projects that go the opposite direction of abstracting everything to the point that you don't realize some function has already been abstracted so you write a new one!
Re:A Dangerous Obsession with Primitives by fizx on Thursday May 31, 2012 @01:48PM (#4049323)
This is also what experience is for. It teaches you the probability that you will need the abstraction in the future. As a beginner, you should err on the side of YAGNI; as an expert, you probably already know what to do.