[HN Gopher] A Formal Theory of Spaghetti Code
       ___________________________________________________________________
        
       A Formal Theory of Spaghetti Code
        
       Author : nickdrozd
       Score  : 46 points
       Date   : 2022-03-12 16:56 UTC (6 hours ago)
        
 (HTM) web link (nickdrozd.github.io)
 (TXT) w3m dump (nickdrozd.github.io)
        
       | pmichaud wrote:
       | It's a fun crack at the problem. I'll say (very annoyingly) that
       | I have a hunch that the formalization is fundamentally wrong
       | somehow that I can't quite put my finger on, even though branch
       | factor does seem like a really great candidate for the relevant
       | measure.
        
         | parksy wrote:
         | One of the first principles I learned in programming was
         | coupling and cohesion. This type of graph-based measurement of
         | program complexity already existed some 60 years ago.
         | 
         | I think your hunch is on point, I think because the author
         | conflates running time of a busy beaver with benchmarks of
         | programmatic coupling and cohesion.
         | 
         | Busy beaver algorithms are single-purpose programs. An
         | eCommerce website is layers upon layers of interrelated modules
         | and functions.
         | 
         | I get where they're going, reducing a problem space down to its
         | simplest representation is ideal. I just don't on first pass
         | understand how busy beaver accomplishes this.
        
       | everyone wrote:
       | [Discussing article title, not article]
       | 
       | I have thought about spaghetti code.. spaghetti is..
       | 
       | * Messy. * Disorganized. * Every part of it is connected to every
       | other part.
       | 
       | The third one is the actually really bad one. U tug on one thing
       | and it affects another thing and so on.
       | 
       | I call my code rice code, its like spaghetti code but its made of
       | _tiny_ little modules and no part is connected to another. It
       | also (like spaghetti) has no order  / design patterns n stuff.
       | Imo committing to a design pattern is kind of a mini-failure cus
       | your project is now less flexible, you've committed to a certain
       | pattern and everything in future has to follow it. Maybe the next
       | feature does not fit well into this pattern. Ideally you can get
       | to end of project without ever committing to one. (But sometimes
       | u give in and use one to overcome a difficult problem)
        
       | [deleted]
        
       | bsedlm wrote:
       | seems the author should be aware of the Big Ball Of Mud
       | http://laputan.org/mud/
        
       | neilk wrote:
       | Theory-curious but mostly workaday programmer here. Does this
       | have any application to detecting spaghetti code in conventional
       | codebases, or is it specific to the Busy Beaver problem?
       | 
       | "Cyclomatic complexity" is as old as the hills, but attempts to
       | count the paths through the code from a begin state to and end
       | state. According to Wikipedia it's similar to "circuit rank"
       | which is the minimum number of edges to remove in order to break
       | cycles. That smells like it's related to this graph reduction
       | thing but I lack intuition into this problem.
        
         | hackerfromthefu wrote:
         | Low Cyclomatic Complexity is absolutely the result of careful
         | management of interfaces in the system. The inverse is also
         | true that high CC is a sign of poorly structure code, which
         | tends towards spaghetti. Thus I agree it's related to the
         | premise of detecting spaghetti code.
         | 
         | There's nice CC visualizers that can show you at a glance areas
         | that have higher complexity. Sometimes that complexity is
         | related to the problem domain, but sometimes it comes from
         | overhead of poor system architecture.
        
         | ravi-delia wrote:
         | I highly doubt it does, it's largely a fun puzzle with
         | potential ramifications for limits of computability.
        
         | atq2119 wrote:
         | People are perfectly capable of writing spaghetti code in
         | structured programming languages (without goto) and such
         | programs are always reducible in the sense of this article.
         | 
         | Actually, I have a hunch that every program that is reducible
         | in the standard compiler sense is also reducible in the sense
         | of the article, but the converse does not hold. 1 -> 2 -> 3 ->
         | 4, 1 -> 3 -> 2 is irreducible in the compiler sense (there is a
         | loop with two entries) but reducible in the sense of the
         | article (first merge 2 and 3, then delete self loop, an acyclic
         | graph remains which is trivially reducible).
        
       | marcodiego wrote:
       | Besides Spaghetti Code there is a development practice which is
       | relatively common and yet people usually fall for it. I like to
       | call it: flag oriented programming.
       | 
       | People usually think it is a good idea to use flags. They create
       | a flag to store states of entities and think the problem is
       | solved. Actually it sometimes duplicates the number of possible
       | new problems.
       | 
       | I once tried to convince a friend not to use it. In a part of the
       | code, I asked him: "Look, how can you guarantee that the states
       | of the flags are consistent here?", he then added code just
       | before the line to check for consistency of the flags. I then
       | said that if the flags fell into an inconsistent state, then it
       | should be fixed there, not when they are checked. He tried
       | another fix: created "set methods" for each of the flags, each
       | method called a function "checkFlags" which detected
       | inconsistencies in the flags and automatically set them to a
       | consistent state.
       | 
       | I continued: "Look, every time you add a new flag you will have
       | to check this function and infer, among possible combinations,
       | which are valid and which are not. If you need states, use an
       | enumeration with few states all of which are consistent."
       | 
       | That is the problem with flag-oriented programming: each new
       | flags doubles the number of possible states and it is very
       | complicated to guarantee consistency between them considering all
       | possible combinations and temptation to just add, set and check a
       | new flag when writing code.
        
         | bitwize wrote:
         | Ah, I see you've met YandereDev.
        
         | echelon wrote:
         | I can relate to this. Flags are great, but you need to exercise
         | discipline to not wind up with dangerous spaghetti.
         | 
         | This problem is amplified further because flags can come in so
         | many different shapes and sizes:
         | 
         | - Rollout: binary on/off, percentage rollout, beta group
         | rollout, single user rollout, etc.
         | 
         | - Control plane: eg. emergency shut off valve for the caching
         | layer, switch that controls routing, etc.
         | 
         | - Multi-valued or numeric: ie. not just true/false, typically
         | combined with A/B testing
         | 
         | Conflating these can lead to extremely messy code. Each of
         | these cases deserves its own special type of treatment.
         | 
         | Rollout flags should have a self-destruct or mechanism that
         | _strongly encourages_ engineers to remove them as soon as they
         | 're no longer used.
         | 
         | Control plane stuff shouldn't really be mixed with feature
         | flagging at all. It would be dangerous to remove them, and
         | regularly vetting the states should be a necessary requirement
         | for any type of disaster recovery assurance testing.
         | 
         | I really appreciate your call to represent these states as an
         | enumeration. Capturing the flag states at the start of a
         | request and then determining the proper bucket helps to make
         | the problem more concrete. Engineers can then better reason
         | about the explosion of states and the impact to control flow.
         | 
         | Ultimately, I think flagging is one of those "hard problems"
         | that comes with the job territory. You don't want to throw the
         | technique out entirely along with the bath water, because it
         | has plenty of justifiable benefits. There are best practices
         | and proper hygienic steps we can take to make the use of flags
         | easier on ourselves.
        
           | sjf wrote:
           | I think the OP is referring to the kind of thing you might
           | find in frontend code, like maintaining state for things like
           | isVisible, isExpanded, isSelected.
        
         | wa1987 wrote:
         | State charts / FSM's work wonders in these situations.
        
         | jonhohle wrote:
         | I often pushed for immutable objects specifically for this
         | reason. At construction time you guarantee the state of the
         | object once, otherwise, as you said, complexity doubles with
         | each mutable property.
        
         | joostdevries wrote:
         | The need for flags in itself may be a sign of the wrong
         | approach. You create a shared module. But for some cases the
         | handling should be different. Let's pass in a flag or
         | configuration. So somewhere in the shared component it will
         | handle things differently. Oh wait, there's another case.
         | Another flag. Which combinations of flags are meaningful and
         | which aren't? The nearest improvement is to put all the cases
         | in an enumeration. But wait it's not one 'dimension'. Let's
         | have two enumerations. And the extreme end point is that your
         | shared module has a full blown DSL for the parameters it
         | receives. Or even an interpreter. The other solution that is
         | often more understandable and debuggable in the long run is to
         | not have the shared module call specific code for cases. But to
         | have specific code pull in shared commonalities. No need for
         | flags.
        
         | LightHugger wrote:
         | To boil it down:
         | 
         | Flags work brilliantly when the states are independent and
         | there is no such thing as an inconsistent state... the moment
         | you have strange interdependence you lose all the benefits.
        
         | gumby wrote:
         | This is perfectly encapsulated by my favorite joke.
         | 
         | A physicist is showing their friend the computer scientist a
         | thermos.
         | 
         | "This thing is so cool: you can pour something hot into it, and
         | no matter how cold it is outside it stays hot". The friend is
         | duly impressed.
         | 
         | "But that isn't all: you can pour something _cold_ into it, and
         | no matter how hot it is outside it stays cold "!
         | 
         | Now the computer scientist is puzzled. "But how does it know?"
         | 
         | Code like this is the bane of my existance.
        
           | WinterMount223 wrote:
           | I'm sorry I don't get it.
        
         | kens wrote:
         | You might want to glance at the article, which is about Turing
         | machine busy beaver programs and has nothing to do with
         | spaghetti code as a development practice.
        
           | fshbbdssbbgdd wrote:
           | What hacker news needs is a separate "discuss title" page.
        
         | elijaht wrote:
         | Giving you a heads up- I think you may have accidentally
         | commented in the wrong thread. This isn't related to the main
         | article
        
       | pkrumins wrote:
       | Theorem: Any spaghetti code that's pushed to production and
       | solves a customer's problem is no longer spaghetti code.
       | #deployordie
        
       ___________________________________________________________________
       (page generated 2022-03-12 23:00 UTC)