Пара мыслей вдогонку вчерашнему разговору.
1. Я тут недавно писал что-то на C и внезапно вспомнил, насколько же это страшно неудобно, когда ты не можешь покрутить отдельный кусочек кода, а должен писать огромный код, потом весь целиком его запускать и верить, что ты нигде не ошибся. Думаю, что дебаггер для компилируемых языков был как раз ответом на эту проблему, по сути давая возможность работать с языком в интерпретируемом режиме. Ну и здесь поэтому и лежит частично ответ на вопрос, как можно жить без дебаггера - используйте REPL, это и есть ваш дебаггер. Язык уже имеет возможность запускать отдельные куски кода и исследовать получающиеся объекты, по сути это и есть то, что даёт дебаггер.
2. Разумеется есть и отличие у простого REPL от дебаггера. В дебаггере вы можете добежать до какой-то точки программы за один проход, а если это делать руками, то нужно воспроизводить множество промежуточных шагов. Ну и если есть какая-то большая сложная функция, которая внутри себя создаёт много промежуточных структур, то их тоже может быть достаточно затруднительно воспроизвести, выглядит как довольно много лишней работы.
Но тут хочу сравнить с немного другой вещью. В питоне есть рекомендация, писать строки не шире 80 символов. Когда я поначалу с этим столкнулся, то меня это ужасно раздражало, я думал "что за ерунда и наследие 90-х годов, у нас уже давно гораздо больше на экран влезает". Однако, когда я начал придерживаться этого правила, то внезапно выяснил, что оно тянет за собой много чего. По другому начинаешь структурировать программу, перекомпонуешь какие-то куски кода, чтобы не было глубоких вложений, что-то выносишь в функции-хелперы и так далее. И на выходе, получается не просто код шириной в 80 символов, а получается гораздо более легко читаемый и более лего рефакторизуемый код.
Я это веду к том, что если поставить себе задачу "жить без дебаггера", то хотя поначалу это будет вызывать головную боль, в долгой перспективе это может привести к тому, что код будет писаться в другом стиле. Более функциональный, состоящий из более коротких и специализированных кусков, с более чёткими соотношениями входа/выхода. И в конечном итоге это приведёт к легче поддерживаемому и более простому коду.