Sunday, December 15, 2024

Characterizing complexity of software and social systems

BLUF: Definitions of distance and modularity enable characterization of complexity in technical and social systems. However, I am unable to find a simple quantification of complexity or rank complexity.

This post is a mixture of notes from a YouTube video (linked at the bottom of this post) plus some analysis. 


Characterizing Complexity

The scope of this post covers the both software complexity and social complexity. 

Software complexity is characterized by

  • how many layers of abstraction: namespace/package, classes, functions?
  • the number of modules at each level of abstraction: how many of each for namespaces, classes per namespace, functions per class?
  • number of interfaces per module at each level of abstraction
  • the distance between interdependent modules
  • the amount of information transmitted between modules

Social complexity is characterized by

  • how many layers in the hierarchy? 
  • the number of modules at each level of hierarchy: how many of each for organizations, teams-per-organization, and people-per-team
  • the number of interfaces at each level of hierarchy. A person talks to how many other people? A team coordinates with how many other teams?
  • the distance between interdependent modules. When two teams have to coordinate, are they in the same parent organization? Or separate organizations?
  • the amount of information transmitted between modules. A short email, a long telephone call, or multiple in-person meetings?

[Claim] When refactoring a system (whether software redesign or re-oganization of people roles and titles) that lacks redundancies, the complexity of the software+social is conserved if the functionality remains the same. Here conservation means productivity and efficiency are unchanged.

Even with the characterizations above and the definitions below I don't see how to quantify complexity in software-social systems as a scalar number or as a vector. I don't see how to rank complexity to enable comparison of different systems, or how the complexity of a system changes over time.


Definitions

In the characterizations above I used words that need explanation.

Definition of System

System: "an interconnected set of elements that is clearly organized in a way that achieves something"
source: "Thinking in Systems" by D. Meadows

In other words, a set of components + interactions that accomplish a goal. This applies to software, hardware, and social settings.


Definition of Distance within a System

Distance within a system of software is characterized by
  • services, which are decomposed into
  • namespace or package, which are decomposed into
  • class, which are decomposed into
  • methods or functions, which are decomposed into
  • lines
Distance in hierarchical social systems is characterized by
  • organization
  • team
  • person

Definition of Modularity

Modularity is defined as having these characteristics
  • enacts self-contained capability
  • capability can be called by other modules
  • capability can operate independently
source: "Composite/structured design" by G. Myers

modules + interactions accomplish future goals (aka flexibility)

There's a 2018 review that surveys the various types of coupling in software and the tooling capable of measuring the coupling. 

From "A Survey on Software Coupling Relations and Tools" by Fregnan et al, 2018 https://fpalomba.github.io/pdf/Journals/J16.pdf

From "A Survey on Software Coupling Relations and Tools" by Fregnan et al, 2018 https://fpalomba.github.io/pdf/Journals/J16.pdf


The tables above illustrate that there are nuances to what "modularity" means in software. Modularity can improve flexibility for re-use but incurs cognitive load of the relationships and dependencies.



Definition of Complexity

Once you write a line of software it becomes legacy code and technical debt is incurred. Similarly in social settings, as soon as one person engages with another (cooperatively or competitively) there are decisions to be made about the interaction. The best you can aim for is to be aware of both the available trade-offs and the consequences of your actions when altering the system.


Complexity is characterized by cause and effect in the https://en.wikipedia.org/wiki/Cynefin_framework in contrast with other categories:

  • Obvious = relationship between cause and effect is obvious to system participants
  • Complicated = relationship between cause and effect requires analysis
  • Complex = relationship between cause and effect is clear only in hindsight
  • Chaotic = no relationship between cause and effect

When a software developer is exploring a software that is novel to them, the code can seem complex or complicated. After they have internalized the design and the reasoning for the design the same code base can seem obvious. Complexity is not a static characterization.

Similarly for interactions of people, a person new to an organization may initially feel overwhelmed, but after forming relationships and understanding the history views the organization as obvious.

Ways to measure complexity of software

Cyclomatic Complexity - measure the control flow of software
http://www.literateprogramming.com/mccabe.pdf
https://en.wikipedia.org/wiki/Cyclomatic_complexity

Halstead complexity -- countable aspects of software
https://en.wikipedia.org/wiki/Halstead_complexity_measures


Why measure complexity

  • To find heterogenous distribution of complexity within a system (and then re-distribute)
  • To compare one system to another
  • To compare changes across time
    • historical: has the system become more complex? If yes, how?
    • forecasting: would this design change make a future system more or less complex?



Sources for the ideas in this post

This post is primarily informed by two recent sources. The first is a superb talk by Sonya Natanzon, https://www.youtube.com/watch?v=Ukv0JVDh_BI titled "Complexity & Modularity: the Yin and Yang of Socio-Technical Design". This post is a summary of that talk plus an extension of the ideas.  The second is a blog post that qualitatively ranks social distance, https://tej.as/blog/how-to-grow-professional-relationships-tjs-model

References

A Philosophy of Software Design | John Ousterhout | Talks at Google
https://www.youtube.com/watch?v=bmSAYlu0NcY


"A Survey on Software Coupling Relations and Tools" by Fregnan et al, 2018 
https://fpalomba.github.io/pdf/Journals/J16.pdf