Another pasta-flavored programming problem is "ravioli code". That kind of code has abstraction layers for everything and stuff is forced into objects and classes when all that's needed is a simple function or heck, even a goto statement. Code like this may seem elegant to the author but trying to read it is as futile an exercise as going through a pile of spaghetti code.
Given the popularity of OOP during the past few decades, ravioli may be a bigger problem than spaghetti these days.
I think the article is trying to define what you call ravioli code as a modern version of spaghetti code. But I think ravioli is a handier, more specific name. Is it your coinage?
Sure, ravioli code can be a problem, although you are supposed to be aggressively refactoring away trivial classes. Perhaps my experience is different to yours, but I've encountered "under-object oriented" code far more often than "over-object oriented". I guess it's based on the format of complexity you're used to - some people like their 20K LOC "classes". I prefer mine in the 100 to 500 LOC range, even if that results in "too many" classes.
To stay on culinary metaphors, I would call lasagna code any properly architected code base where a few layers neatly face each other with evenly spread meat in between.
I've been programming for around 20 years now, and I've very, very rarely seen goto statements used, except in the case of error handling (which, in my opinion, was a great use of goto). So, I think as an industry, we've done a good job in curtailing the use of goto, so the article really shouldn't have bothered mentioning it, because it's more like a red herring than anything else.
However, I've seen a whole crapload of terrible code. You don't need goto to create code that jumps around, and where the state is very hard to determine. That can easily be caused by things like global variables, badly designed code, etc.
> I've very, very rarely seen goto statements used
I saw them used all the time in Basic =)
> You don't need goto to create code that jumps around
Nope. All you need is a loop, with lots of continue/break statements mixed in. I have seen this quite a bit and I start twitching when I see it. That's the modern equivalent of the goto.
I found one in the PostgreSQL source not to long ago. It was well commented as to why it existed, was well modularized and quite frankly appropriate.
I use "spaghetti code" to refer to code where execution aimlessly wanders between apparent modules. You don't need goto statements to make it happen. SQL-Ledger is a good example of doing this with simple redefinition of functions. It isn't the only kind of bad code though.
IMHO the only acceptable use of a goto statement is to break from a multiply-nested loop in C-like languages. Even there, it is likely that a refactor can eliminate this. It's usually a sign that there is a simpler or more elegant way of doing things.
> We also generally agree, in 2012, that goto is flat-out inappropriate for source code in most modern programs. Exceptions to this policy exist, but they’re extremely rare.
No, we don't agree. In C, goto is very often the best way to deal with error paths. It is used in the Linux kernel and in many other important (open source or not) applications.
I doubt those qualify as rare.
Agreed, for languages like C. It's not just error paths, either. For example, to break out of an outer loop inside an inner one you can label the outer loop with OUTER and use `last OUTER` in Perl or `break OUTER` in Java/JavaScript. But in C you have to either use a goto or (shudder) tinker with the outer loop control variable and break from the inner loop.
It argues that forward gotos (that work like continue, break, returns mid-function) don't contribute to spaghetti code, while backward gotos are more problematic.
I think the disclaimer about Exceptions being a suitable form of GOTO is a big mistake.
When I started using Erlang I was amazed at how error handling and all that 'necessary' gumph just disappeared. In the Erlang world exceptions aren't handled up the call stack - when an Erlang process hits an error it just exits.
The Erlang control approach is that for each (restartable) worker process that does something there is a supervisor process whose only job is to catch 'I have died because...' messages from its children and restart sub-systems as appropriate.
It is just amazing what this approach does. There is no longer a 'fog of exception handling' necessary to keep the system running in the prescence of errors, there are clear and consistent reports of ALL errors - which means you can start squashing the bugs that cause them and iterate towards error-free programming.
I think the author meant "There are exceptions, in the real life meaning of the word", rather than the unwind-the-stack-when-a-bobo-happens programming construct.
The irony of this post is that it could have been about a third of the length and seems to have been subject to a fair amount of entropy and spaghetti-fication itself.
I guess everyone has their own mental picture of what spaghetti code is. Mine refers specifically to the old days of the early web when html and code where so heavily intertwined that is was impossible to determine what was code and what was markup. Flashbacks of enormous pages of string concatenation with with tons of escaping where the layout of the html page dictated the flow of the code. Fun times.
I don't agree `goto` is all bad. Whilst the OP said there are exceptions, they didn't list them. An ideal use (in C) is to ensure that in an error state, resources are cleaned up properly by jumping to error handling code (within the same function).
Or you have a case where a function must be restarted at a new state. Recursion is not always desirable here. intrafunctional gotos, used sparingly, are quite helpful.
Just my take but when I think of spaghetti code, I think of code that has side effects. An accessor that also performs some update. A global variable that is updated by many different points in the code. Code that needs to be run in a certain order and only a set number of times OR ELSE. You pull a noodle out and you really just have to wait to see where the effect is felt.
Code that jumps around via gotos and functions in various modules can be mapped out and you can gain an understanding of what the code does, but it is less than ideal. Code that changes its behavior depending on the time and order in which it is run is way more dangerous.
No that's mikado code, touch one little part and everything moves.
Spaghetti code is simply very long functions without structure stuffed with long nested branching. I have seen 3000 lines functions, in PHP, and that's even worse, maybe like those "crossing bridge noodle" you can eat in China.
comments here that allude to the history of spaghetti code are actually a bit off topic with respect to the article, but the early fortran family (pointedly - F66) had severly limited control structures in the language: a very weak for loop, and the goto statement.
'while' and 'until' showed up in RATFOR (rational fortran) which fits into the lexical ancestry of 'C'. I think that the Algol family had these too.
without the more powerful control statements, GOTO was heavily used, and with wild abandon. Some variants even let you GOTO up and down the execution stack.
trying to trace logic (of course there weren't symbolic debuggers way back when) could be like following a strand of spaghetti.
my most (not) favorite modern examples are coroutines, but let's not forget the evergreen example of enterprise java wherein one can easily achieve stack depths that boggle the mind.
nevertheless, spaghetti code is a frame of mind in which the untutored implement minimally functional software systems that only work for trivial conditions and for which the source code itself can not be reverse engineered except with great magic, epic heroism and extraordinary luck on the attack roll.
I believe spaghetti code happens more because of training. Programmers that are not trained to think in an OO way tend to produce spaghetti code, when a simple decomposition into objects would suffice.
[+] [-] exDM69|13 years ago|reply
Given the popularity of OOP during the past few decades, ravioli may be a bigger problem than spaghetti these days.
[+] [-] sageikosa|13 years ago|reply
[+] [-] colomon|13 years ago|reply
[+] [-] danielbarla|13 years ago|reply
[+] [-] gbog|13 years ago|reply
[+] [-] eps|13 years ago|reply
[+] [-] steve8918|13 years ago|reply
However, I've seen a whole crapload of terrible code. You don't need goto to create code that jumps around, and where the state is very hard to determine. That can easily be caused by things like global variables, badly designed code, etc.
[+] [-] eps|13 years ago|reply
[+] [-] maratd|13 years ago|reply
Me too.
> I've very, very rarely seen goto statements used
I saw them used all the time in Basic =)
> You don't need goto to create code that jumps around
Nope. All you need is a loop, with lots of continue/break statements mixed in. I have seen this quite a bit and I start twitching when I see it. That's the modern equivalent of the goto.
[+] [-] einhverfr|13 years ago|reply
I use "spaghetti code" to refer to code where execution aimlessly wanders between apparent modules. You don't need goto statements to make it happen. SQL-Ledger is a good example of doing this with simple redefinition of functions. It isn't the only kind of bad code though.
[+] [-] dllthomas|13 years ago|reply
"The goto statement comes in handy when a function exits from multiple locations and some common work such as cleanup has to be done."
http://www.kernel.org/doc/Documentation/CodingStyle
[+] [-] api|13 years ago|reply
[+] [-] zwieback|13 years ago|reply
[+] [-] unknown|13 years ago|reply
[deleted]
[+] [-] jcromartie|13 years ago|reply
[+] [-] jbk|13 years ago|reply
No, we don't agree. In C, goto is very often the best way to deal with error paths. It is used in the Linux kernel and in many other important (open source or not) applications. I doubt those qualify as rare.
[+] [-] dmethvin|13 years ago|reply
[+] [-] glassx|13 years ago|reply
It argues that forward gotos (that work like continue, break, returns mid-function) don't contribute to spaghetti code, while backward gotos are more problematic.
[+] [-] koide|13 years ago|reply
[+] [-] alexchamberlain|13 years ago|reply
[+] [-] gordonguthrie|13 years ago|reply
When I started using Erlang I was amazed at how error handling and all that 'necessary' gumph just disappeared. In the Erlang world exceptions aren't handled up the call stack - when an Erlang process hits an error it just exits.
The Erlang control approach is that for each (restartable) worker process that does something there is a supervisor process whose only job is to catch 'I have died because...' messages from its children and restart sub-systems as appropriate.
It is just amazing what this approach does. There is no longer a 'fog of exception handling' necessary to keep the system running in the prescence of errors, there are clear and consistent reports of ALL errors - which means you can start squashing the bugs that cause them and iterate towards error-free programming.
[+] [-] arithma|13 years ago|reply
[+] [-] SeanDav|13 years ago|reply
http://michaelochurch.wordpress.com/2012/08/15/what-is-spagh...
The irony of this post is that it could have been about a third of the length and seems to have been subject to a fair amount of entropy and spaghetti-fication itself.
[+] [-] jiggy2011|13 years ago|reply
[+] [-] bas|13 years ago|reply
[+] [-] duckworth|13 years ago|reply
[+] [-] edandersen|13 years ago|reply
(yes, this is actually a michaelochurch article for some reason syndicated on jelastic?)
[+] [-] alexchamberlain|13 years ago|reply
[+] [-] einhverfr|13 years ago|reply
[+] [-] partisan|13 years ago|reply
Code that jumps around via gotos and functions in various modules can be mapped out and you can gain an understanding of what the code does, but it is less than ideal. Code that changes its behavior depending on the time and order in which it is run is way more dangerous.
[+] [-] gbog|13 years ago|reply
Spaghetti code is simply very long functions without structure stuffed with long nested branching. I have seen 3000 lines functions, in PHP, and that's even worse, maybe like those "crossing bridge noodle" you can eat in China.
[+] [-] terryk88a|13 years ago|reply
'while' and 'until' showed up in RATFOR (rational fortran) which fits into the lexical ancestry of 'C'. I think that the Algol family had these too.
without the more powerful control statements, GOTO was heavily used, and with wild abandon. Some variants even let you GOTO up and down the execution stack.
trying to trace logic (of course there weren't symbolic debuggers way back when) could be like following a strand of spaghetti.
my most (not) favorite modern examples are coroutines, but let's not forget the evergreen example of enterprise java wherein one can easily achieve stack depths that boggle the mind.
nevertheless, spaghetti code is a frame of mind in which the untutored implement minimally functional software systems that only work for trivial conditions and for which the source code itself can not be reverse engineered except with great magic, epic heroism and extraordinary luck on the attack roll.
[+] [-] Zenst|13 years ago|reply
For some though it is a job security abstraction layer.
[+] [-] coliveira|13 years ago|reply
[+] [-] lbj|13 years ago|reply
[+] [-] anonymoushn|13 years ago|reply