In defense of spaghetti code. *ducks*
-
Things like a long if statement rather than a switch, assuming that made an actual difference, isn't what constitutes spaghetti code. Optimizations that are not "normal" to fit on a microcontroller or having to rollup loops for performance, etc. isn't spaghetti. And those can be documented in code as well. Comments have zero impact. There is rarely a reason to not have some organization with your code, even if the cost of a function call is expensive.
Jeremy Falcon
While I hear you, I do have one niggling nit to pick with your suggestion that comments *do* have zero impact if you mean they have zero negative impact on your codebase. They do. Comments are extra maintenance, and often get stale. They should be used as sparsely as possible and no sparser. For the most part, code should be self documenting. This is not as true in embedded where you often can't afford the necessary abstractions to express intent, such as using the STL algorithms everyone is familiar with. In the case of embedded comments tend to be more necessary.
To err is human. Fortune favors the monsters.
-
I have the impression that OP interchanges 2 things: purpose built single use code, and code with horrible control flow and global data access. I've written code for running on DSPs, on the bare hardware, and everything was purpose coded with a thin hardware abstraction library I made. In my case I had only 16K program memory and 2K RAM. hardware limits aside, when you are programming close to bare metal, it starts to be less and less useful to implement generic frameworks.
In my case, I opted for making the code flow with the rather complicated flowcharts I was provided. Rather than abstract everything to make it cleaner, because of the reasons I stated before, I decided that at the very least the code could follow the documentation, however messy. At least the documents and the code match somewhat. :)
To err is human. Fortune favors the monsters.
-
I ran into an issue recently on a professional embedded project, and that was this: In translating the flow diagrams to code, there were so many conditions around state changes and such that my options were to either abstract the flow with some sort of generalized framework, or cook some spaghetti code. I chose the latter. Why? Simple. The actual effort if anything would be about equal, or favor the spaghetti approach. More importantly, progress remains visible with the spaghetti approach rather than the abstract flow framework which requires a lot of up front design and work without progress visible to the client. Finally, this is embedded code, where a rewrite is maybe a grand or two $USD, on the outside, assuming not a lot of reuse. It would cost at least half that to develop a simple framework, which might make things more maintainable, but questionable in terms of how effortlessly one can make changes (whereas maintainability is more about stepping away for a month and being able to pick it up again, mostly - or someone else picking up your code). It's all a matter of robbing peter to pay paul. The bottom line here is that while we may chase perfect code, and "best practices" that's not always the most effective technique for keeping the lights on. Flame away.
To err is human. Fortune favors the monsters.
I'd only have a problem with spaghetti code if there was a fairly straightforward way to simplify it (maybe with a table of state transitions) or if it would have to evolve to support a stream of new capabilities in subsequent releases. I worked on telecom call servers for many years, where spaghetti code made it a pain to work on various products. The problem is hundreds of supplementary services that modify the behavior of basic calls. If some of their logic is inserted into the basic call code, it soon becomes spaghetti. More services were implemented every release, so you also got a bunch of developers all needing to add more spaghetti to that code. When I was tasked with rewriting one of these products, the design eliminated the spaghetti by separating all of the services' state machines. It used static and dynamic chains of responsibility with observer capabilities, which allowed state machines to be triggered, after which they could override or reuse basic call behavior. I'd write an article about it, but I think the design is overkill for most domains. However, it would likely be very useful when developing software that supports a lot of bidding conventions for contract bridge.
Robust Services Core | Software Techniques for Lemmings | Articles
The fox knows many things, but the hedgehog knows one big thing. -
I'd only have a problem with spaghetti code if there was a fairly straightforward way to simplify it (maybe with a table of state transitions) or if it would have to evolve to support a stream of new capabilities in subsequent releases. I worked on telecom call servers for many years, where spaghetti code made it a pain to work on various products. The problem is hundreds of supplementary services that modify the behavior of basic calls. If some of their logic is inserted into the basic call code, it soon becomes spaghetti. More services were implemented every release, so you also got a bunch of developers all needing to add more spaghetti to that code. When I was tasked with rewriting one of these products, the design eliminated the spaghetti by separating all of the services' state machines. It used static and dynamic chains of responsibility with observer capabilities, which allowed state machines to be triggered, after which they could override or reuse basic call behavior. I'd write an article about it, but I think the design is overkill for most domains. However, it would likely be very useful when developing software that supports a lot of bidding conventions for contract bridge.
Robust Services Core | Software Techniques for Lemmings | Articles
The fox knows many things, but the hedgehog knows one big thing.I'm almost doing that, but I actually have several state machines working in tandem, which, while kind of unfortunate due to the spinning plates factor, was very expedient. The codebase is small, and a rewrite wouldn't be terribly expensive given how little time it took me to write it in the first place. I've found with a lot of embedded stuff it's like that. You *have* to keep it small and efficient, so the rules and priorities change a bit as the landscape shifts.
To err is human. Fortune favors the monsters.
-
I ran into an issue recently on a professional embedded project, and that was this: In translating the flow diagrams to code, there were so many conditions around state changes and such that my options were to either abstract the flow with some sort of generalized framework, or cook some spaghetti code. I chose the latter. Why? Simple. The actual effort if anything would be about equal, or favor the spaghetti approach. More importantly, progress remains visible with the spaghetti approach rather than the abstract flow framework which requires a lot of up front design and work without progress visible to the client. Finally, this is embedded code, where a rewrite is maybe a grand or two $USD, on the outside, assuming not a lot of reuse. It would cost at least half that to develop a simple framework, which might make things more maintainable, but questionable in terms of how effortlessly one can make changes (whereas maintainability is more about stepping away for a month and being able to pick it up again, mostly - or someone else picking up your code). It's all a matter of robbing peter to pay paul. The bottom line here is that while we may chase perfect code, and "best practices" that's not always the most effective technique for keeping the lights on. Flame away.
To err is human. Fortune favors the monsters.
I can make the argument that spaghetti code is the better solution in this case. Creating a general-purpose framework tends to hide the logic. At least when you came back at some future time you only have to understand the spaghetti, and not a framework as well. I think YAGNI and KISS both apply here. Obviously the answer is different if you're tailoring the spaghetti for multiple solutions.
Software Zen:
delete this;
-
I understand and mostly agree with your reasoning, but writing spaghetti code feels dirty, somehow.
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.
-
I ran into an issue recently on a professional embedded project, and that was this: In translating the flow diagrams to code, there were so many conditions around state changes and such that my options were to either abstract the flow with some sort of generalized framework, or cook some spaghetti code. I chose the latter. Why? Simple. The actual effort if anything would be about equal, or favor the spaghetti approach. More importantly, progress remains visible with the spaghetti approach rather than the abstract flow framework which requires a lot of up front design and work without progress visible to the client. Finally, this is embedded code, where a rewrite is maybe a grand or two $USD, on the outside, assuming not a lot of reuse. It would cost at least half that to develop a simple framework, which might make things more maintainable, but questionable in terms of how effortlessly one can make changes (whereas maintainability is more about stepping away for a month and being able to pick it up again, mostly - or someone else picking up your code). It's all a matter of robbing peter to pay paul. The bottom line here is that while we may chase perfect code, and "best practices" that's not always the most effective technique for keeping the lights on. Flame away.
To err is human. Fortune favors the monsters.
I don’t remember who said that engineering is the art of knowing when one approximately equal with two and when one is much smaller than two. Intelligent compromise is at the heart of what we (hopefully) do.
Mircea
-
I ran into an issue recently on a professional embedded project, and that was this: In translating the flow diagrams to code, there were so many conditions around state changes and such that my options were to either abstract the flow with some sort of generalized framework, or cook some spaghetti code. I chose the latter. Why? Simple. The actual effort if anything would be about equal, or favor the spaghetti approach. More importantly, progress remains visible with the spaghetti approach rather than the abstract flow framework which requires a lot of up front design and work without progress visible to the client. Finally, this is embedded code, where a rewrite is maybe a grand or two $USD, on the outside, assuming not a lot of reuse. It would cost at least half that to develop a simple framework, which might make things more maintainable, but questionable in terms of how effortlessly one can make changes (whereas maintainability is more about stepping away for a month and being able to pick it up again, mostly - or someone else picking up your code). It's all a matter of robbing peter to pay paul. The bottom line here is that while we may chase perfect code, and "best practices" that's not always the most effective technique for keeping the lights on. Flame away.
To err is human. Fortune favors the monsters.
As one guy who was frequent in this fine establishment used to say: "Who needs an OOP when there are copy and paste."
Advertise here – minimum three posts per day are guaranteed.
-
While I hear you, I do have one niggling nit to pick with your suggestion that comments *do* have zero impact if you mean they have zero negative impact on your codebase. They do. Comments are extra maintenance, and often get stale. They should be used as sparsely as possible and no sparser. For the most part, code should be self documenting. This is not as true in embedded where you often can't afford the necessary abstractions to express intent, such as using the STL algorithms everyone is familiar with. In the case of embedded comments tend to be more necessary.
To err is human. Fortune favors the monsters.
honey the codewitch wrote:
They should be used as sparsely as possible and no sparser.
To use your wording with Ravi... you may wish to re-read what I said. It was in the context of having to do something not considered normal. Which clearly includes the scenario you referring to. That being said, I disagree with the premise of being too sparse with comments. I'm not a junior programmer. I don't have the time nor inclination to tell people comments like
// assign variable x to y
are bad. That should be a given for senior level chats. This is actually the reason I visit CP less and less these days if I'm being honest. If comments get stale, that's not the fault of comments but the developer. There reasons tools like doxygen and jsdoc exist. Again, if this is code that is for your personal use only, all of this is overkill. But when being paid for it, that tends to suggest it's not.Jeremy Falcon
-
I ran into an issue recently on a professional embedded project, and that was this: In translating the flow diagrams to code, there were so many conditions around state changes and such that my options were to either abstract the flow with some sort of generalized framework, or cook some spaghetti code. I chose the latter. Why? Simple. The actual effort if anything would be about equal, or favor the spaghetti approach. More importantly, progress remains visible with the spaghetti approach rather than the abstract flow framework which requires a lot of up front design and work without progress visible to the client. Finally, this is embedded code, where a rewrite is maybe a grand or two $USD, on the outside, assuming not a lot of reuse. It would cost at least half that to develop a simple framework, which might make things more maintainable, but questionable in terms of how effortlessly one can make changes (whereas maintainability is more about stepping away for a month and being able to pick it up again, mostly - or someone else picking up your code). It's all a matter of robbing peter to pay paul. The bottom line here is that while we may chase perfect code, and "best practices" that's not always the most effective technique for keeping the lights on. Flame away.
To err is human. Fortune favors the monsters.
My experience is that spaghetti code is usually, but not always, the result of improper factoring with decision making conditionals either too high a level or too low a level. However, this isn't always the case and it appears Honey found one of the exceptions. Just document the sauce out of it and sprinkle in a little garlic.
-
honey the codewitch wrote:
They should be used as sparsely as possible and no sparser.
To use your wording with Ravi... you may wish to re-read what I said. It was in the context of having to do something not considered normal. Which clearly includes the scenario you referring to. That being said, I disagree with the premise of being too sparse with comments. I'm not a junior programmer. I don't have the time nor inclination to tell people comments like
// assign variable x to y
are bad. That should be a given for senior level chats. This is actually the reason I visit CP less and less these days if I'm being honest. If comments get stale, that's not the fault of comments but the developer. There reasons tools like doxygen and jsdoc exist. Again, if this is code that is for your personal use only, all of this is overkill. But when being paid for it, that tends to suggest it's not.Jeremy Falcon
My point in making the statement about comments going stale is not about assigning blame. I thought that was a given, considering assigning blame doesn't do anything. My point was that it is extra maintenance.
To err is human. Fortune favors the monsters.
-
While I hear you, I do have one niggling nit to pick with your suggestion that comments *do* have zero impact if you mean they have zero negative impact on your codebase. They do. Comments are extra maintenance, and often get stale. They should be used as sparsely as possible and no sparser. For the most part, code should be self documenting. This is not as true in embedded where you often can't afford the necessary abstractions to express intent, such as using the STL algorithms everyone is familiar with. In the case of embedded comments tend to be more necessary.
To err is human. Fortune favors the monsters.
Also, and I repeat, code _should_ be self-documenting as much as possible for the most part. But, the context of this entire chat is about crap code. This is completely contradictory to the subject at hand for the conversation you started.
Jeremy Falcon
-
Also, and I repeat, code _should_ be self-documenting as much as possible for the most part. But, the context of this entire chat is about crap code. This is completely contradictory to the subject at hand for the conversation you started.
Jeremy Falcon
Jeremy Falcon wrote:
Also, and I repeat, code should be self-documenting as much as possible for the most part
I said the same thing in my post. In fact it was a fundamental part of my position.
To err is human. Fortune favors the monsters.
-
My point in making the statement about comments going stale is not about assigning blame. I thought that was a given, considering assigning blame doesn't do anything. My point was that it is extra maintenance.
To err is human. Fortune favors the monsters.
I fully understand the maintenance aspect, but that's nothing to do with blame. Unless you consider telling a coder to not be lazy with code blame then sure. But, I'll repeat again the context of what said and me referring to specific scenarios. This does not disqualify me from understanding what maintenance is.
Jeremy Falcon
-
I've been programming since 1986, and professionally since 1996.
To err is human. Fortune favors the monsters.
Then you should know better.
Jeremy Falcon
-
I fully understand the maintenance aspect, but that's nothing to do with blame. Unless you consider telling a coder to not be lazy with code blame then sure. But, I'll repeat again the context of what said and me referring to specific scenarios. This does not disqualify me from understanding what maintenance is.
Jeremy Falcon
If comments get stale, that's not the fault of comments but the developer.
To be clear, this is what I was talking about when I brought up blame. When you're assigning a fault to someone that's blame. And again, I don't think it's productive. People make mistakes. Code gets stale. It happens to everyone. My comment was about maintenance.
To err is human. Fortune favors the monsters.
-
Then you should know better.
Jeremy Falcon
I do know better. Much better. When I was a less experienced developer, I used to refuse to write expedient code like this, and my projects would suffer in cases where it was called for, particularly given that a lot of abstracted tends code to not survive contact with real world changes. Again, we have a disagreement. Not only that, a lot more programmers here seem to agree with me than with you, so maybe this doesn't have so much to do with what I don't know or lack of experience, and again, a lot more to do with us simply disagreeing.
To err is human. Fortune favors the monsters.
-
Jeremy Falcon wrote:
Knowing why this is a bad idea separates the seniors from those who think they are seniors but are not. Even on the off chance you can make sense of spaghetti, in a year or two it'll be harder if you come back to it. If it's handed off to another dev, it'll be harder.
Perhaps I wasn't clear in my original comment, but I tried to be explicit about the low cost of a rewrite. There is no justification for spending $1000 to possibly save $1000 down the road. It makes no sense. There's little justification for even spending $500 to again, possibly save $1000 down the road when the downside is that you go dark in terms of client visibility as you're developing the framework in the alternative. Edit: What we have is a fundamental disagreement, which you're trying to paint as hubris, and that's insulting. I think my contributions here speak for themselves, as well as my extensive history of successful development projects. I wish you'd be a little bit more circumspect about what you write here. It would be nice to keep it civil. :)
To err is human. Fortune favors the monsters.
honey the codewitch wrote:
There is no justification for spending $1000 to possibly save $1000 down the road. It makes no sense.
Despite needing a diagram? Something isn't adding up. Not sure how many people you've employed before but $500-$1K is a joke. Seems that the diagram would take longer than the code according to you. Which makes no sense. People don't diagram something that takes 1-2 days to develop.
honey the codewitch wrote:
I wish you'd be a little bit more circumspect about what you write here. It would be nice to keep it civil.
I'm not being uncivil. I'm just challenging you. If saying a senior programmer knows why this is a bad idea is being uncivil in your book, then that's just oversensitivity. I could also say that always arguing with people (this is where you say you're not) is also being uncivil. But, this is the Internet. Arguing is a way of life here. This is where you say you're just defending your position. And so am I. But, don't make it seem like I'm a bad guy here because I speak of what a senior should know. But don't worry, this is easily solvable. I'll just stop replying to your click baits. :)
Jeremy Falcon
-
If comments get stale, that's not the fault of comments but the developer.
To be clear, this is what I was talking about when I brought up blame. When you're assigning a fault to someone that's blame. And again, I don't think it's productive. People make mistakes. Code gets stale. It happens to everyone. My comment was about maintenance.
To err is human. Fortune favors the monsters.
This is going nowhere. You have more time to argue than I have a desire to be here. Tootles.
Jeremy Falcon
-
honey the codewitch wrote:
There is no justification for spending $1000 to possibly save $1000 down the road. It makes no sense.
Despite needing a diagram? Something isn't adding up. Not sure how many people you've employed before but $500-$1K is a joke. Seems that the diagram would take longer than the code according to you. Which makes no sense. People don't diagram something that takes 1-2 days to develop.
honey the codewitch wrote:
I wish you'd be a little bit more circumspect about what you write here. It would be nice to keep it civil.
I'm not being uncivil. I'm just challenging you. If saying a senior programmer knows why this is a bad idea is being uncivil in your book, then that's just oversensitivity. I could also say that always arguing with people (this is where you say you're not) is also being uncivil. But, this is the Internet. Arguing is a way of life here. This is where you say you're just defending your position. And so am I. But, don't make it seem like I'm a bad guy here because I speak of what a senior should know. But don't worry, this is easily solvable. I'll just stop replying to your click baits. :)
Jeremy Falcon
Jeremy Falcon wrote:
Despite needing a diagram?
I already have a diagram, which I made the code closely follow.
Jeremy Falcon wrote:
Not sure how many people you've employed before but $500-$1K is a joke.
You've maybe never done embedded? Projects don't sprawl when you have kilobytes of RAM and less than 1MB to store your code.
Jeremy Falcon wrote:
I'm just challenging you.
I'm sorry but that's false. If you were just challenging me you wouldn't be insinuating things like I think I'm a senior developer when I'm not - that's insulting, and it's nonsense. You should know better.
Jeremy Falcon wrote:
I could also say that always arguing with people (this is where you say you're not) is also being uncivil.
There's nothing uncivil about a debate. This is about the statements you made that specifically did not further it. I stand by what I wrote.
To err is human. Fortune favors the monsters.