Wiele z tego, czego nauczyliśmy się w praktyce inżynierii oprogramowania w ciągu ostatnich 30 lat, ma postać „technologia X może przyspieszyć początkowy rozwój nowego oprogramowania, ale jeśli nie poświęcisz tyle czasu lub więcej na zastanawianie się, jak i kiedy używać go tak, jak zaoszczędziłeś, korzystając z niego, na dłuższą metę zamieni twoją aplikację w zasysające bagno długu technicznego, co będzie kosztować cię o rząd wielkości więcej czasu i wysiłku w utrzymaniu. ”
Technologie, które podlegają tej maszynce to: ręcznie kodowany język asemblera, kompilatory, interpretatory, biblioteki procedur, programowanie imperatywne, programowanie funkcjonalne, programowanie obiektowe, ręczne przydzielanie pamięci, odśmiecanie, typy statyczne, typy dynamiczne, zakres leksykalny, zakres dynamiczny , „bezpieczne” wskaźniki, „niebezpieczne” wskaźniki, brak wskaźników jako koncepcja języka, formaty plików binarnych, formaty plików ze znacznikami strukturalnymi, makra, szablony, unikanie makr i szablonów, pamięć współdzielona, przekazywanie wiadomości, wątki, coroutines, asynchroniczne pętle zdarzeń, scentralizowane usługi zdalne, usługi rozproszone, lokalnie zainstalowane oprogramowanie, tablice, listy połączone, tabele skrótów i drzewa.
Fakt, że wiele pozycji z powyższej listy występuje w grupach, które razem wyczerpują przestrzeń znanego rozwiązania, jest bardzo celowy i powinien sam w sobie coś powiedzieć. Można argumentować, że jedynymi jednoznacznymi, ogólnymi poprawkami w praktyce, jakie mieliśmy od czasu pierwszego włączenia Z3, są programy o strukturze blokowej (w przeciwieństwie do kodu spaghetti) i ochrona pamięci (chłopcze, czy ja nigdy nie tęsknię dni, w których literówka może zdjąć cały mój komputer).