Shawn McGrath Critiques Object-Oriented Programming Using David Eberly's C++ Geometric Tools
Pinkie Pinkie Mew Mew
Summary:
Shawn McGrath critiques Object-Oriented Programming (OOP) in a C++ context, demonstrating its complexities with David Eberly's Geometric Tools library.
- He emphasizes that despite Eberly's high intellect and experience, the OOP design makes his code almost impossible to understand and debug.
- McGrath illustrates this by attempting to step through a simple triangulation algorithm in the Visual Studio debugger, repeatedly getting lost due to excessive indirection, template use, and inheritance hierarchies.
- He contrasts this with his own linear, function-oriented implementation of the same algorithm, which he claims is significantly easier to follow and debug.
- McGrath argues that OOP principles like encapsulation and abstraction, when poorly applied, lead to unnecessary complexity and obscure program flow, making code harder to read and maintain.
- He highlights how basic tasks become convoluted due to numerous object instantiations and method calls, rather than straightforward conditional logic.
Shawn McGrath's Criticism of Object-Oriented Programming (OOP) [00:00:00]
Shawn McGrath expresses a strong negative opinion about Object-Oriented Programming (OOP), stating that it makes code:
- More difficult to understand.
- More difficult to read.
- More difficult to write.
- More difficult to debug.
- More difficult to make fast.
- Generally worse for everything.
- He emphatically declares that OOP is "bad from beginning to end" [00:00:29].
Introduction to David Eberly's Code and Expertise [00:00:34]
McGrath uses David Eberly's source code as a prime example to demonstrate the flaws of OOP, highlighting Eberly's exceptional qualifications:
- Eberly's Credentials:
- Possesses superior knowledge in math and underlying game programming systems compared to McGrath and most others [00:00:47].
- Is an "incredibly smart" and "brilliant game programmer" [00:01:09].
- Has published multiple books on complex topics [00:01:40].
- Refused to write a second edition of a book because the co-author wasn't up to his standards [00:01:44].
- Has two master's degrees, two PhDs, and a BA in math [00:25:36].
- Has extensive publications in image processing and signal processing, which are very complicated fields [00:25:53].
- Worked on the early version of the Microsoft HoloLens [00:26:29].
- Justification for using Eberly's code:
- McGrath chose Eberly's code because it represents "as good as OOP code can get," countering potential arguments that he cherry-picked bad code [00:02:25].
The Problem: Triangulating Curves in a Game [00:02:30]
McGrath outlines the task he wanted to perform:
- His game features many curves [00:02:40].
- The goal was to convert these curves into triangles (triangulation) [00:03:10].
- He initially researched algorithms and then found David Eberly's source code, which implemented a triangulation algorithm (ear clipping method) [00:03:24].
- He normally avoids using other people's implementations, but decided to use Eberly's to specifically illustrate why OOP is problematic [00:03:38].
Debugging Eberly's OOP Triangulation Code [00:04:17]
McGrath attempts to step through Eberly's C++ code using the Visual Studio debugger, encountering immediate difficulties:
- Initial confusion with
Create function:
- The
Create function takes a template and a window type with parameters, immediately making him "lost" on the first line [00:05:05].
- The debugger cannot even tell him the type of "window type," which is a templated class [00:05:52].
- Deep Inheritance Hierarchy:
- Discovering
ECWindow is a subclass of Window2, which is a subclass of Window, necessitates understanding multiple levels of inheritance [00:06:31].
- This creates uncertainty about overloaded methods and the actual functions being called [00:06:44].
- Loss of Program Flow Control:
- By the second line, he feels he has "lost total flow control" due to numerous redirections through abstract interface objects [00:08:26].
- He states that if statements would make the flow clear, but OOP's indirection obscures it [00:08:47].
- He admits to skipping large parts of the call stack because he cannot understand it [00:09:09].
- Difficulty understanding
resize function:
- Even a 17-line
resize function becomes incomprehensible due to nested complexities [00:10:43].
- He sarcastically challenges viewers to understand it [00:10:48].
- Problems with
Triangulator object and type inference:
- Creating a
Triangulator object and stepping into its constructor leads to multiple accidental steps into unrelated or complex functions [00:15:23].
- Difficulty in understanding
m_query.Set due to m_query being a PrimalQuery2f of an unknown ComputeType [00:17:51].
- It takes an "hour" to deduce that
ComputeType is a rational type due to nested templated type definitions and typedefs [00:20:43].
- Initialization via Constructor vs. Function Calls:
- Questions why data (
m_numPoints, m_points) is set in a constructor rather than passed via explicit function invocations, leading to state being "stuck in objects for no reason" [00:22:47].
- This initialization process via the C++ constructor with a colon syntax is particularly frustrating and hard to follow [00:29:39].
- Debugger's Limitations with OOP:
- The debugger struggles to provide useful information about types and variable states due to OOP's abstract nature [00:30:34].
- Cannot easily tell if stepping into a constructor for
m_points or m_numPoints [00:30:08].
- "Fing state connected to functions":*
- Expresses anger about member functions being tied to "state" when it could simply be functions, attributing it to following "good object-oriented programming principles" that lead to convoluted code [00:31:59].
Shawn McGrath's Alternative: Linear, Procedural Code [00:13:02]
McGrath contrasts Eberly's OOP implementation with his own linear version of the same triangulation algorithm:
- Simplicity and Readability:
- His implementation is presented as a "thousand lines of code" but is straightforward and easy to understand [00:13:14].
- Clearly outlines steps: generate circular list, perform ear clipping, search for reflex verts [00:13:22].
- Uses standard library containers like
STD::Vector [00:13:34].
- Direct Flow Control:
- The code follows a clear, logical, sequential order: "do this then do this then do this then do this" [00:14:18].
- The algorithmic complexity remains the same, but the "programmatic complexity" is drastically reduced [00:36:29].
- OOP's Hiding of Details:
- Argues that OOP's concept of "hiding implementation details" ironically makes code incomprehensible because one has to navigate "so many levels of indirection" to understand what's happening [00:37:51].
- Contrasts this with direct "if A do B, if C do D" logic [00:37:36].
Conclusion on OOP's Failures [00:26:37]
McGrath reiterates his main thesis:
- Eberly's code is "fundamentally broken because it's written in object-oriented programming," not because of Eberly's programming skill [00:26:40].
- The OOP style, particularly C++'s features like virtual constructors, function calls, templates, and inheritance, makes debugging and understanding program flow "irrationally difficult" [00:36:49].
- He concludes that OOP, despite its proponents, makes programming harder and understanding code nearly impossible, especially with its excessive indirection and hidden complexities [00:38:07].