Why do engineers insist on complexity?
-
A few years ago, I was working on some very legacy code that required a temporary array in a function. The array size would never, ever change and could be hard coded. The legacy code:
char* pData = new char[4];
//Do stuff
delete[] pData;When I mentioned this recently to a colleague, he said that a smart pointer should have been used. Today that would be:
std::unique_ptr pData = new char[4];
//Do stuffLast week, I ran across a web site discussing optimizations that a similar concept, though with more items. Applied to the legacy code, this this "expert's" solution was:
std::vector data(4);
//Do stuffWhy not just my solution:
char data[4];
//Do stuffHave people gotten so accustomed to complexity that they think of only complex solutions? (I have other examples, the second funniest was when someone suggested using a boost function instead of three lines of elementary C code.)
-
A few years ago, I was working on some very legacy code that required a temporary array in a function. The array size would never, ever change and could be hard coded. The legacy code:
char* pData = new char[4];
//Do stuff
delete[] pData;When I mentioned this recently to a colleague, he said that a smart pointer should have been used. Today that would be:
std::unique_ptr pData = new char[4];
//Do stuffLast week, I ran across a web site discussing optimizations that a similar concept, though with more items. Applied to the legacy code, this this "expert's" solution was:
std::vector data(4);
//Do stuffWhy not just my solution:
char data[4];
//Do stuffHave people gotten so accustomed to complexity that they think of only complex solutions? (I have other examples, the second funniest was when someone suggested using a boost function instead of three lines of elementary C code.)
Was it possibly an aversion to placing items on the stack versus the heap? I can't imagine that four bytes (or perhaps even 8) would be enough to warrant the overhead of using the heap. Perhaps, they just like to build in complexity as a job protection kind of thing. The times are rough, now a days. ;)
-
A few years ago, I was working on some very legacy code that required a temporary array in a function. The array size would never, ever change and could be hard coded. The legacy code:
char* pData = new char[4];
//Do stuff
delete[] pData;When I mentioned this recently to a colleague, he said that a smart pointer should have been used. Today that would be:
std::unique_ptr pData = new char[4];
//Do stuffLast week, I ran across a web site discussing optimizations that a similar concept, though with more items. Applied to the legacy code, this this "expert's" solution was:
std::vector data(4);
//Do stuffWhy not just my solution:
char data[4];
//Do stuffHave people gotten so accustomed to complexity that they think of only complex solutions? (I have other examples, the second funniest was when someone suggested using a boost function instead of three lines of elementary C code.)
We make it complex because mere mortals should never be able to understand us! Heh, heh, heh.....
Bob Dole
The internet is a great way to get on the net.
:doh: 2.0.82.7292 SP6a
-
A few years ago, I was working on some very legacy code that required a temporary array in a function. The array size would never, ever change and could be hard coded. The legacy code:
char* pData = new char[4];
//Do stuff
delete[] pData;When I mentioned this recently to a colleague, he said that a smart pointer should have been used. Today that would be:
std::unique_ptr pData = new char[4];
//Do stuffLast week, I ran across a web site discussing optimizations that a similar concept, though with more items. Applied to the legacy code, this this "expert's" solution was:
std::vector data(4);
//Do stuffWhy not just my solution:
char data[4];
//Do stuffHave people gotten so accustomed to complexity that they think of only complex solutions? (I have other examples, the second funniest was when someone suggested using a boost function instead of three lines of elementary C code.)
People have become so used to using frameworks, the primitives that the framework is built on, no longer has meaning to them. It is both a shame but also a measure of the quality of the some of the frameworks being used. :)
Chris Meech I am Canadian. [heard in a local bar] In theory there is no difference between theory and practice. In practice there is. [Yogi Berra] posting about Crystal Reports here is like discussing gay marriage on a catholic church’s website.[Nishant Sivakumar]
-
A few years ago, I was working on some very legacy code that required a temporary array in a function. The array size would never, ever change and could be hard coded. The legacy code:
char* pData = new char[4];
//Do stuff
delete[] pData;When I mentioned this recently to a colleague, he said that a smart pointer should have been used. Today that would be:
std::unique_ptr pData = new char[4];
//Do stuffLast week, I ran across a web site discussing optimizations that a similar concept, though with more items. Applied to the legacy code, this this "expert's" solution was:
std::vector data(4);
//Do stuffWhy not just my solution:
char data[4];
//Do stuffHave people gotten so accustomed to complexity that they think of only complex solutions? (I have other examples, the second funniest was when someone suggested using a boost function instead of three lines of elementary C code.)
The days programmers could understand and master their programming languages are just over.
-
A few years ago, I was working on some very legacy code that required a temporary array in a function. The array size would never, ever change and could be hard coded. The legacy code:
char* pData = new char[4];
//Do stuff
delete[] pData;When I mentioned this recently to a colleague, he said that a smart pointer should have been used. Today that would be:
std::unique_ptr pData = new char[4];
//Do stuffLast week, I ran across a web site discussing optimizations that a similar concept, though with more items. Applied to the legacy code, this this "expert's" solution was:
std::vector data(4);
//Do stuffWhy not just my solution:
char data[4];
//Do stuffHave people gotten so accustomed to complexity that they think of only complex solutions? (I have other examples, the second funniest was when someone suggested using a boost function instead of three lines of elementary C code.)
You have punched one of my hottest hot buttons: the tendency among far too many engineers to eschew the simple path.
My theory of the thing goes as follows: There are three stages in a software engineer's development / three types of software engineers / three phases to a life in software engineering:
1. The beginner: This engineer has little knowledge and less experience. That combination inclines him toward simplicity, for he hasn't the tools to get deep into the thickets, nor would he be confident of coming out alive. His programs tend to be easy to read, if sometimes a bit "naive."
2. The intermediate engineer: This engineer has begun to "feel his oats." He's learned quite a lot about various programming languages and fundamental algorithms, and he wants to show it off! So he embeds as much of what he "knows" in every program he writes as he possibly can. (Cf: "A Real Programmer knows every nuance of every instruction and uses them all in every Real Program.") His programs are next to illegible. After the passage of a few months, he won't want to admit to authoring them, much less maintain or debug them.
3. The senior engineer: This engineer is a grizzled, battle-scarred veteran. He's been around the block more times than you can count without taking off your booties. And while he can be a bit of a bore about those scars and how he earned them, his programs are a pleasure to read and maintain, because he's learned the virtues of simplicity. He never over-complicates a solution, because he's well aware that should it come apart under stress in a year's time, the most likely stuckee will be himself -- and remembering the rationale for excess complexity, and how to unsnarl it, is just too much like real work.
When I interview a fresh young candidate, I routinely describe the three types of engineers to him, and I ask: "Which sort of engineer do you aspire to be?" There are only two acceptable answers:
- A senior engineer, wise in the ways of the bits and a staunch foe of excess complexity;
- Hey, man, this engineering crap is just a stop along the way to the stars; I want to be the CEO of this place!
Food for thought.
(This message is programming you in ways you cannot detect. Be afraid.)
-
A few years ago, I was working on some very legacy code that required a temporary array in a function. The array size would never, ever change and could be hard coded. The legacy code:
char* pData = new char[4];
//Do stuff
delete[] pData;When I mentioned this recently to a colleague, he said that a smart pointer should have been used. Today that would be:
std::unique_ptr pData = new char[4];
//Do stuffLast week, I ran across a web site discussing optimizations that a similar concept, though with more items. Applied to the legacy code, this this "expert's" solution was:
std::vector data(4);
//Do stuffWhy not just my solution:
char data[4];
//Do stuffHave people gotten so accustomed to complexity that they think of only complex solutions? (I have other examples, the second funniest was when someone suggested using a boost function instead of three lines of elementary C code.)
Yes Joe, I agree with you. Your solucion is the best one. I never programmed it otherwise. Only when the size goes over some multiple of 1000 bytes I decide to allocate heap memory. And yes: some programmers don´t even know why. _______________________________________
-
A few years ago, I was working on some very legacy code that required a temporary array in a function. The array size would never, ever change and could be hard coded. The legacy code:
char* pData = new char[4];
//Do stuff
delete[] pData;When I mentioned this recently to a colleague, he said that a smart pointer should have been used. Today that would be:
std::unique_ptr pData = new char[4];
//Do stuffLast week, I ran across a web site discussing optimizations that a similar concept, though with more items. Applied to the legacy code, this this "expert's" solution was:
std::vector data(4);
//Do stuffWhy not just my solution:
char data[4];
//Do stuffHave people gotten so accustomed to complexity that they think of only complex solutions? (I have other examples, the second funniest was when someone suggested using a boost function instead of three lines of elementary C code.)
-
You have punched one of my hottest hot buttons: the tendency among far too many engineers to eschew the simple path.
My theory of the thing goes as follows: There are three stages in a software engineer's development / three types of software engineers / three phases to a life in software engineering:
1. The beginner: This engineer has little knowledge and less experience. That combination inclines him toward simplicity, for he hasn't the tools to get deep into the thickets, nor would he be confident of coming out alive. His programs tend to be easy to read, if sometimes a bit "naive."
2. The intermediate engineer: This engineer has begun to "feel his oats." He's learned quite a lot about various programming languages and fundamental algorithms, and he wants to show it off! So he embeds as much of what he "knows" in every program he writes as he possibly can. (Cf: "A Real Programmer knows every nuance of every instruction and uses them all in every Real Program.") His programs are next to illegible. After the passage of a few months, he won't want to admit to authoring them, much less maintain or debug them.
3. The senior engineer: This engineer is a grizzled, battle-scarred veteran. He's been around the block more times than you can count without taking off your booties. And while he can be a bit of a bore about those scars and how he earned them, his programs are a pleasure to read and maintain, because he's learned the virtues of simplicity. He never over-complicates a solution, because he's well aware that should it come apart under stress in a year's time, the most likely stuckee will be himself -- and remembering the rationale for excess complexity, and how to unsnarl it, is just too much like real work.
When I interview a fresh young candidate, I routinely describe the three types of engineers to him, and I ask: "Which sort of engineer do you aspire to be?" There are only two acceptable answers:
- A senior engineer, wise in the ways of the bits and a staunch foe of excess complexity;
- Hey, man, this engineering crap is just a stop along the way to the stars; I want to be the CEO of this place!
Food for thought.
(This message is programming you in ways you cannot detect. Be afraid.)
-
Some people never make it past The intemediate engineer. Their code is always almost impossible to decipher.
Well, if their employers are lucky, perhaps they go into the finance department.
(This message is programming you in ways you cannot detect. Be afraid.)
-
Well, if their employers are lucky, perhaps they go into the finance department.
(This message is programming you in ways you cannot detect. Be afraid.)
-
A few years ago, I was working on some very legacy code that required a temporary array in a function. The array size would never, ever change and could be hard coded. The legacy code:
char* pData = new char[4];
//Do stuff
delete[] pData;When I mentioned this recently to a colleague, he said that a smart pointer should have been used. Today that would be:
std::unique_ptr pData = new char[4];
//Do stuffLast week, I ran across a web site discussing optimizations that a similar concept, though with more items. Applied to the legacy code, this this "expert's" solution was:
std::vector data(4);
//Do stuffWhy not just my solution:
char data[4];
//Do stuffHave people gotten so accustomed to complexity that they think of only complex solutions? (I have other examples, the second funniest was when someone suggested using a boost function instead of three lines of elementary C code.)
-
A few years ago, I was working on some very legacy code that required a temporary array in a function. The array size would never, ever change and could be hard coded. The legacy code:
char* pData = new char[4];
//Do stuff
delete[] pData;When I mentioned this recently to a colleague, he said that a smart pointer should have been used. Today that would be:
std::unique_ptr pData = new char[4];
//Do stuffLast week, I ran across a web site discussing optimizations that a similar concept, though with more items. Applied to the legacy code, this this "expert's" solution was:
std::vector data(4);
//Do stuffWhy not just my solution:
char data[4];
//Do stuffHave people gotten so accustomed to complexity that they think of only complex solutions? (I have other examples, the second funniest was when someone suggested using a boost function instead of three lines of elementary C code.)
Joe Woodbury wrote:
Have people gotten so accustomed to complexity that they think of only complex solutions?
C'est la vie :), i often was told that a programmer that is learning a new language (or tool) tries to use every possible function of it, anyway i always advocate for simplicity, because complex solutions usually are the hardest to mantain (or change).
CEO at: - Rafaga Systems - Para Facturas - Modern Components for the moment...
-
You have punched one of my hottest hot buttons: the tendency among far too many engineers to eschew the simple path.
My theory of the thing goes as follows: There are three stages in a software engineer's development / three types of software engineers / three phases to a life in software engineering:
1. The beginner: This engineer has little knowledge and less experience. That combination inclines him toward simplicity, for he hasn't the tools to get deep into the thickets, nor would he be confident of coming out alive. His programs tend to be easy to read, if sometimes a bit "naive."
2. The intermediate engineer: This engineer has begun to "feel his oats." He's learned quite a lot about various programming languages and fundamental algorithms, and he wants to show it off! So he embeds as much of what he "knows" in every program he writes as he possibly can. (Cf: "A Real Programmer knows every nuance of every instruction and uses them all in every Real Program.") His programs are next to illegible. After the passage of a few months, he won't want to admit to authoring them, much less maintain or debug them.
3. The senior engineer: This engineer is a grizzled, battle-scarred veteran. He's been around the block more times than you can count without taking off your booties. And while he can be a bit of a bore about those scars and how he earned them, his programs are a pleasure to read and maintain, because he's learned the virtues of simplicity. He never over-complicates a solution, because he's well aware that should it come apart under stress in a year's time, the most likely stuckee will be himself -- and remembering the rationale for excess complexity, and how to unsnarl it, is just too much like real work.
When I interview a fresh young candidate, I routinely describe the three types of engineers to him, and I ask: "Which sort of engineer do you aspire to be?" There are only two acceptable answers:
- A senior engineer, wise in the ways of the bits and a staunch foe of excess complexity;
- Hey, man, this engineering crap is just a stop along the way to the stars; I want to be the CEO of this place!
Food for thought.
(This message is programming you in ways you cannot detect. Be afraid.)
-
A few years ago, I was working on some very legacy code that required a temporary array in a function. The array size would never, ever change and could be hard coded. The legacy code:
char* pData = new char[4];
//Do stuff
delete[] pData;When I mentioned this recently to a colleague, he said that a smart pointer should have been used. Today that would be:
std::unique_ptr pData = new char[4];
//Do stuffLast week, I ran across a web site discussing optimizations that a similar concept, though with more items. Applied to the legacy code, this this "expert's" solution was:
std::vector data(4);
//Do stuffWhy not just my solution:
char data[4];
//Do stuffHave people gotten so accustomed to complexity that they think of only complex solutions? (I have other examples, the second funniest was when someone suggested using a boost function instead of three lines of elementary C code.)
There's a lazy reason for vector. The programmer doesn't have to remember "4" in the code that indexes it, because they can use vector size. (You can use sizeof of course) Complexity like this is often a result of the engineer trying to cater for every imaginable change that could possibly be required in the future. So the engineer ends up saying, "What if we need to change these unsigned integer indexes into a list of Reticulating Splines?! Oh well, better make it some horrible templated monstrosity!" I've said it myself. Only, replace "templated monstrosity" with "cathedral of generalized reusability" :)
Stephen Coda
-
A few years ago, I was working on some very legacy code that required a temporary array in a function. The array size would never, ever change and could be hard coded. The legacy code:
char* pData = new char[4];
//Do stuff
delete[] pData;When I mentioned this recently to a colleague, he said that a smart pointer should have been used. Today that would be:
std::unique_ptr pData = new char[4];
//Do stuffLast week, I ran across a web site discussing optimizations that a similar concept, though with more items. Applied to the legacy code, this this "expert's" solution was:
std::vector data(4);
//Do stuffWhy not just my solution:
char data[4];
//Do stuffHave people gotten so accustomed to complexity that they think of only complex solutions? (I have other examples, the second funniest was when someone suggested using a boost function instead of three lines of elementary C code.)
We write more code with more complexity because languages have gotten more complex over the years, and also because we've been educated to more forms of complexity. Those various solutions deal with that complexity better. Simple new/delete isn't the safest solution in an operator-overloaded, exception-throwing world. The smart pointer solves that issue transparently (although I'm not sure whether it deletes a single character of the array, or the entire array). The vector<> solution allows a wider range of primatives to be used against the array, in addition to being leak-safe like the smart pointer and guaranteed to call the array version of delete. The stack solution is probably the best, and what I would opt for, if I knew I'd never need to use any of the STL primatives on it. Besides, it doesn't run any risk of memory fragmentation like ALL of the other solutions do :)
We can program with only 1's, but if all you've got are zeros, you've got nothing.
-
The days programmers could understand and master their programming languages are just over.
YvesDaoust wrote:
The days programmers could understand and master their programming languages are just over.
Nonsense. A thorough understanding of the tools is, in fact, something that separates the top devs from the wannabes. It does take a few years to achieve this mastery. The impatient recent grad or mediocre developer may delude themself that understanding cannot be achieved, but this is just an excuse. That said, some tools do make it harder than others.
-
You have punched one of my hottest hot buttons: the tendency among far too many engineers to eschew the simple path.
My theory of the thing goes as follows: There are three stages in a software engineer's development / three types of software engineers / three phases to a life in software engineering:
1. The beginner: This engineer has little knowledge and less experience. That combination inclines him toward simplicity, for he hasn't the tools to get deep into the thickets, nor would he be confident of coming out alive. His programs tend to be easy to read, if sometimes a bit "naive."
2. The intermediate engineer: This engineer has begun to "feel his oats." He's learned quite a lot about various programming languages and fundamental algorithms, and he wants to show it off! So he embeds as much of what he "knows" in every program he writes as he possibly can. (Cf: "A Real Programmer knows every nuance of every instruction and uses them all in every Real Program.") His programs are next to illegible. After the passage of a few months, he won't want to admit to authoring them, much less maintain or debug them.
3. The senior engineer: This engineer is a grizzled, battle-scarred veteran. He's been around the block more times than you can count without taking off your booties. And while he can be a bit of a bore about those scars and how he earned them, his programs are a pleasure to read and maintain, because he's learned the virtues of simplicity. He never over-complicates a solution, because he's well aware that should it come apart under stress in a year's time, the most likely stuckee will be himself -- and remembering the rationale for excess complexity, and how to unsnarl it, is just too much like real work.
When I interview a fresh young candidate, I routinely describe the three types of engineers to him, and I ask: "Which sort of engineer do you aspire to be?" There are only two acceptable answers:
- A senior engineer, wise in the ways of the bits and a staunch foe of excess complexity;
- Hey, man, this engineering crap is just a stop along the way to the stars; I want to be the CEO of this place!
Food for thought.
(This message is programming you in ways you cannot detect. Be afraid.)
You forgot... n. The retread: An experienced developer (in Java for instance) may come to C++ with habits that aren't good C++. Need a thingy object? "myThingy = new Thingy(1,2);" That's how you do it in Java. In C++ you have more choices. In fact, the revised example (using STL) looks very much like a Java programmer doing C++ to me.
-
You forgot... n. The retread: An experienced developer (in Java for instance) may come to C++ with habits that aren't good C++. Need a thingy object? "myThingy = new Thingy(1,2);" That's how you do it in Java. In C++ you have more choices. In fact, the revised example (using STL) looks very much like a Java programmer doing C++ to me.
A good point. I had a subordinate like that: a highly experienced FORTRAN 66 programmer who had done a few years in management and had only just come back to the tech side. Thought all variables should be global. Couldn't see the point of classes and objects. Linked lists and dynamically allocated memory were incomprehensible to him. He was slotted into our C++ environment and just about fell apart. It took quite a bit of work to save him from the Grim Reaper.
(This message is programming you in ways you cannot detect. Be afraid.)
-
Well, if their employers are lucky, perhaps they go into the finance department.
(This message is programming you in ways you cannot detect. Be afraid.)