Pyramid of doom (programming)

Last updated

In computer programming, the pyramid of doom is a common problem that arises when a program uses many levels of nested indentation to control access to a function. It is commonly seen when checking for null pointers or handling callbacks. [1] Two examples of the term are related to a particular programming style in JavaScript, [2] and the nesting of if statements that occurs in object-oriented programming languages when one of the objects may be a null pointer. [3] [4]

Contents

Examples

Most modern object-oriented programming languages use a coding style known as dot notation that allows multiple method calls to be written in a single line of code, each call separated by a period. For instance:

theWidth=windows("Main").views(5).size().width();

This code contains four different instructions; it first looks in the collection of windows for a window with the name "Main", then looks in that window's views collection for the 5th subview within it, then calls the size method to return a structure with the view's dimensions, and finally calls the width method on that structure to produce a result that is assigned to a variable name theWidth.

The problem with this approach is that the code assumes that all of these values exist. While it is reasonable to expect that a window will have a size and that size will have a width, it is not at all reasonable to assume that a window named "Main" will exist, nor that it has five subviews. If either of those assumptions is wrong, one of the methods will be invoked on null, producing a null pointer error.

To avoid this error, the programmer has to check every method call to ensure it returns a value. A safer version of the same code would be:

ifwindows.contains("Main"){ifwindows("Main").views.contains(5){theWidth=windows("Main").views(5).size().width();//more code that works with theWidth}}

If the programmer wishes to use that value based on whether or not it exists and is valid, the functional code inside the if statements is all pushed to the right, making it difficult to read longer lines. This often leads to attempts to "flatten" the code:

ifwindows.contains("Main"){theWindow=windows("Main")}iftheWindow!=null&&theWindow.views.contains(5){theView=theWindow.views(5)}iftheView!=null{theWidth=theView.size().width();//additional code}

Or alternatively:

if!windows.contains("Main"){// handle error}elseif!windows("Main").views.contains(5){// handle error}else{theWidth=windows("Main").views(5).size().width();//more code that works with theWidth}

This sort of programming construct is very common and a number of programming languages have added some sort of syntactic sugar to address this. For instance, Apple's Swift added the concept of optional chaining in if statements [5] while Microsoft's C# 6.0 and Visual Basic 14 added the null-conditional operators ?. and ?[ for member access and indexing, respectively. [6] [7] [8] The basic idea is to allow a string of method calls to immediately return null if any of its members is null, so for instance:

theWidth=windows("Main")?.views(5)?.size.width;

would assign null to theWidth if either "Main" or the fifth subview is missing, or complete the statement and return the width if they are both valid. There are many times where the programmer wants to take different actions in these two cases, so Swift adds another form of syntactic sugar for this role, the if let statement, also known as "optional binding":

iflettheView=windows("Main")?.views(5){//do things knowing the view exists...theWidth=theView.size.width}

Resolution

Pyramid of Doom can usually be resolved in any language by simply breaking up the code into multiple nested functions (or other groupings). For instance, instead of:

main(){aaaaa(){bbbbb(){ccccc(){ddddd(){// do something now}}}}}

You can break up the functionality like this:

doSomething(){// do something now}CC(){ccccc(){ddddd(){doSomething()}}}main(){aaaaa(){bbbbb(){CC()}}}

Similarly, data structures can be broken up by levels, when similar pyramids occur.

Not only is the Pyramid of Doom solved, but it's better practice to not have large, complicated functions; smaller ones are easier to get right, and easier to read, and verify the operation of. Choosing function names for each of these levels will also help the author clarify to readers what is done where. Typically, each level doesn't need many connections to levels that are far away, so separating them out is easy. If there are such connections, the author can re-think their design to something more reliable, because this is a fertile source of bugs.

See also

Related Research Articles

C is a general-purpose computer programming language. It was created in the 1970s by Dennis Ritchie, and remains very widely used and influential. By design, C's features cleanly reflect the capabilities of the targeted CPUs. It has found lasting use in operating systems, device drivers, and protocol stacks, but its use in application software has been decreasing. C is commonly used on computer architectures that range from the largest supercomputers to the smallest microcontrollers and embedded systems.

<span class="mw-page-title-main">Dylan (programming language)</span> Multi-paradigm programming language

Dylan is a multi-paradigm programming language that includes support for functional and object-oriented programming (OOP), and is dynamic and reflective while providing a programming model designed to support generating efficient machine code, including fine-grained control over dynamic and static behaviors. It was created in the early 1990s by a group led by Apple Computer.

Pascal is an imperative and procedural programming language, designed by Niklaus Wirth as a small, efficient language intended to encourage good programming practices using structured programming and data structuring. It is named after French mathematician, philosopher and physicist Blaise Pascal.

VBScript is a deprecated Active Scripting language developed by Microsoft that is modeled on Visual Basic. It allows Microsoft Windows system administrators to generate powerful tools for managing computers without error handling and with subroutines and other advanced programming constructs. It can give the user complete control over many aspects of their computing environment.

<span class="mw-page-title-main">Visual Basic (.NET)</span> Object-oriented computer programming language

Visual Basic (VB), originally called Visual Basic .NET (VB.NET), is a multi-paradigm, object-oriented programming language, implemented on .NET, Mono, and the .NET Framework. Microsoft launched VB.NET in 2002 as the successor to its original Visual Basic language, the last version of which was Visual Basic 6.0. Although the ".NET" portion of the name was dropped in 2005, this article uses "Visual Basic [.NET]" to refer to all Visual Basic languages released since 2002, in order to distinguish between them and the classic Visual Basic. Along with C# and F#, it is one of the three main languages targeting the .NET ecosystem. Microsoft updated its VB language strategy on 6 February 2023, stating that VB is a stable language now and Microsoft will keep maintaining it.

In computer programming, indentation style is a convention, a.k.a. style, governing the indentation of blocks of source code that is generally intended to convey structure.

<span class="mw-page-title-main">C syntax</span> Set of rules defining correctly structured programs

The syntax of the C programming language is the set of rules governing writing of software in C. It is designed to allow for programs that are extremely terse, have a close relationship with the resulting object code, and yet provide relatively high-level data abstraction. C was the first widely successful high-level language for portable operating-system development.

Managed Extensions for C++ or Managed C++ is a deprecated set of language extensions for C++, including grammatical and syntactic extensions, keywords and attributes, to bring the C++ syntax and language to the .NET Framework. These extensions were created by Microsoft to allow C++ code to be targeted to the Common Language Runtime (CLR) in the form of managed code, as well as continue to interoperate with native code.

The computer programming languages C and Pascal have similar times of origin, influences, and purposes. Both were used to design their own compilers early in their lifetimes. The original Pascal definition appeared in 1969 and a first compiler in 1970. The first version of C appeared in 1972.

<span class="mw-page-title-main">C Sharp (programming language)</span> Programming language

C# is a general-purpose high-level programming language supporting multiple paradigms. C# encompasses static typing, strong typing, lexically scoped, imperative, declarative, functional, generic, object-oriented (class-based), and component-oriented programming disciplines.

this, self, and Me are keywords used in some computer programming languages to refer to the object, class, or other entity which the currently running code is a part of. The entity referred to thus depends on the execution context. Different programming languages use these keywords in slightly different ways. In languages where a keyword like "this" is mandatory, the keyword is the only way to access data and methods stored in the current object. Where optional, these keywords can disambiguate variables and functions with the same name.

C# and Visual Basic .NET are the two primary languages used to program on the .NET Framework.

The null coalescing operator is a binary operator that is part of the syntax for a basic conditional expression in several programming languages, such as : C# since version 2.0, Dart since version 1.12.0, PHP since version 7.0.0., Perl since version 5.10 as logical defined-or, PowerShell since 7.0.0, and Swift as nil-coalescing operator.

This article describes the syntax of the C# programming language. The features described are compatible with .NET Framework and Mono.

Windows Runtime (WinRT) is a platform-agnostic component and application architecture first introduced in Windows 8 and Windows Server 2012 in 2012. It is implemented in C++ and officially supports development in C++, Rust/WinRT, Python/WinRT, JavaScript-TypeScript, and the managed code languages C# and Visual Basic (.NET) (VB.NET).

PL/SQL is Oracle Corporation's procedural extension for SQL and the Oracle relational database. PL/SQL is available in Oracle Database, Times Ten in-memory database, and IBM Db2. Oracle Corporation usually extends PL/SQL functionality with each successive release of the Oracle Database.

In programming jargon, Yoda conditions is a programming style where the two parts of an expression are reversed from the typical order in a conditional statement. A Yoda condition places the constant portion of the expression on the left side of the conditional statement.

Swift is a high-level general-purpose, multi-paradigm, compiled programming language created by Chris Lattner in 2010 for Apple Inc. and maintained by the open-source community. Swift compiles to machine code, as it is an LLVM-based compiler. Swift was first released in June 2014, and the Swift toolchain has shipped in Xcode since version 6, released in 2014.

In object-oriented programming, the safe navigation operator is a binary operator that returns null if its first argument is null; otherwise it performs a dereferencing operation as specified by the second argument.

<span class="mw-page-title-main">Zig (programming language)</span> A general-purpose programming language, toolchain to build Zig/C/C++ code

Zig is an imperative, general-purpose, statically typed, compiled system programming language designed by Andrew Kelley. It is intended to be a successor to the C programming language, with the intention of being even smaller and simpler to program in while also offering more functionality.

References

  1. Dave Herman (14 December 2011). "Why coroutines won't work on the web". The Little Calculist. Archived from the original on 2016-03-06.
  2. "The Pyramid of Doom: A javaScript Style Trap". 27 November 2012. Archived from the original on 2015-12-09.
  3. Eberhardt, Colin (8 December 2014). "Tearing Down Swift's Optional Pyramid Of Doom". Archived from the original on 2016-07-31.
  4. "New Language Features in Visual Basic 14". 9 December 2014. Archived from the original on 2014-12-25.
  5. "Optional Chaining". Apple.
  6. "Null-conditional Operators (C# and Visual Basic)". Microsoft.
  7. "What's New for Visual C#". Microsoft.
  8. "What's New for Visual Basic". Microsoft.
  9. Joe Zimmerman (March 28, 2013). "What's The Point Of Promises?". telerik.com.