The post has been translated automatically. Original language: Russian
"There is only one way to reduce development time when it is already short — to reduce the debugging time of the program."From Mr. Tompkins' notebook. Deadline, Tom DeMarco
Is it possible to create programs without errors?
Obviously, it is impossible to completely get rid of undefined behavior . However, it is definitely possible to create a tool that will eliminate errors at your level.
My name is Alexander Kozin, I have been programming since 1996 and have been creating applications for Apple since 2008.
Participated in projects:
- Western Union
- Audi
- YOTA
- Bork
- 2gis Flamp
- Kings and Queens by David Starkey
- Rema1000
- 585 Gold
- And many others
He graduated from the Institute with a degree in Automation of Technological Processes and Production in Mechanical Engineering. My thesis was an expert system for automation in mechanical engineering on iOS, 2011. This idea has turned into an expert system for software development.
I can say for sure that all the products are similar. In each case, we spend a lot of time on documentation, evaluation, communication, design and development.
Today I propose to discuss only the last point - working with the code.
Direct development is just:
- New functionality
- Error correction
Implementing new tasks is often exciting and exciting. It's easy to get into the flow. And at the beginning of the project, there are no mistakes to fix - 100% of the time is spent on development.
However, flaws inevitably accumulate in the process. Forgotten technical debt merges into legacy, logic turns into a monolith, and the percentage of debugging time increases, sometimes dramatically.
Drama, by the way, directly depends on the quality of the code.:

Mr. Tompkins put down his pen. Yes, it looks like that's the case. Since debugging and error correction takes about half of all time and resources, then in order to achieve outstanding results, you can only reduce the time allotted for debugging. In this case, there will be more time for design. Yes, one cannot disagree with this.Deadline, Tom DeMarco
Half of it! The Raw, Eddie Murphyhttps://youtu.be/3dJzvpJF33g?si=bUgLBADjRY4mftov
It's good if you manage to maintain parity in long-term projects. However, in practice, it can take more than 80% of the time for debugging, legacy digging, and other refactorings. The ratio depends mainly on the quality of the solutions used- the notorious quality of the code. This is a documented reality.
Then why does the quality of the code almost always give priority to deadlines?

It's very tempting to get a fast development speed right at the start of a project. Over time, the pace certainly drops: Not significantly when using high-quality high-quality solutions and categorically in the opposite case.
Why is this happening?
The time to implement new tasks directly depends on the quality of the decisions made:

That's why hiring two average developers for the budget of one experienced one is a bad idea squared. After all, the speed of development decreases exponentially with increasing team size. But that's a completely different story.
Going back to ours, it turns out that we spend half the time in the project on:
- Mistakes
- Technical debt
- Legacy
So how do we speed up development? Remembering the great work of Tom DeMarco, it is only necessary to find an approach that will allow you to write programs without errors. Or parts of programs using this approach.
Huh, that sounds too easy. But how can we solve such an incredible task?
If we use the best solutions approach (high-quality code), this will happen automatically.:
The time to correct errors does not put pressure on the deadlines for the implementation of new tasks, there is no need to make changes in a hurry by accumulating technical debt. And a debt that has been forgotten forever will not turn into a legacy. Profit.
We need high-quality solutions that are easy to test, reuse, maintain, and integrate.
- But how can we write code without a single mistake?- Well, look. You have just discovered an error in one of the modules. Where is this error located?- In the module.- no. It is located on the border. At the very edge of the module. Of course, there are local errors in the middle of the module, but they are the easiest to catch and fix. The most insidious errors, the real ones, those that take a lot of time and effort from developers, are found in the interface between the module and the rest of the program.— That's right, everyone knows that. So what?Deadline, Tom DeMarco
Said and done! All that remains is to find this place on the very border and focus on this layer.
In modern development, we all use architectural patterns: MVC, MVP, MVVM, VIPER, etc.
And they all start with a Model. These are the objects and services to receive them. This is the place where the SDK and our modules interact.
It is very logical to start from the beginning. In addition, it is in this layer that the error concentration is maximum. Here it is Profit.

To solve any task, you need to set goals. There are only four of them:
- TDD
- Reuse
- Update
- Connect
If the code needs to be reused, it must be free of defects. And vice versa. The tested code is easy to reuse- it is isolated and covered with Unit tests and does not contain errors in the covered cases.
This code is easy to maintain and update. It can be used to create complex structures using different blocks of logic together.
According to the IQR (the ideal end result), everything should remain as it was, but either the harmful, unnecessary quality should disappear, or a new, useful quality should appear.Finding an Idea: An Introduction to TRIZ, Heinrich Altshuller
Let's Imagine The Perfect End Result:
A programming language in which it is enough only to describe an object in order to get it as quickly as possible with minimal resource expenditure.
In programming theory, this is called a declarative language. It completely encapsulates the logic of creating and receiving any objects.
Suitable for all platforms:
//Get one location, one set of steps, a user from the network, and execute a block of code
Location.one | PedometerData.one | CurrentUser.one | .all {
}
//An object that does not require configuration options
|{ (result: Object) in
}
//An object with input data
ingredients | { (result: Object) in
}
//One, all, according to the condition
ingredients | .one { (t: T) in
} | .every { (u: U) in
} | .while { (v: V) in
true
}The prototype runs on Swift:
//Request current Location
|{ (location: CLLocation) in
}
//Request .authorizedAlways permissions once
CLAuthorizationStatus.authorizedAlways | .one { (status: CLAuthorizationStatus) in
}
//Retrieve Pedometer Data updates
|{ (data: CMPedometerData) in
}
//Scan for Bluetooth Peripheral
|{ (peripheral: CBPeripheral) in
}
//Wait for a Notification
UIWindow.keyboardWillShowNotification | { (n: Notification) in
}
//Scan an NFC tag
|.every { (tag: NFCNDEFTag) in
}
//Perform Face Observation
URL(string: "http://example.com/image.jpg") | { (faces: [VNFaceObservation]) in
}
//Perform Pose Observation
//Wait for two persons
data | .while { (bodies: [VNHumanBodyPoseObservation]) in
bodies < 2
}
//Detect shake
|{ (motion: UIEvent.EventSubtype) in
if motion == .motionShake {
}
}Wand is a declarative language. It is translated into native code at the preprocessing stage. The implementation for Android, Windows, and Linux will be done in the foundation.
The core and plug-ins for common tasks are available in OpenSource on GitHub.:
https://github.com/The-Wand/Wand
Technical presentation on the Krasnodar Coffee Code in T-Bank and How To:
https://www.youtube.com/playlist?list=PLvprpeoOl6IoZ67BcD-t0rS1L5c5J4lPh
We can create bug-free business programs on a commercial basis and keep such plug-ins private for Wand.
On long-term projects, potentially 50% more efficient.
Write to me if you have any questions about creating optimal programs for any platform.
"Есть только один способ сократить время на разработку, когда его и без того мало — уменьшить сроки отладки программы."
Из записной книжки Мистера Томпкинса. Deadline, Том ДеМарко
Возможно ли создавать программы без ошибок?
Очевидно что полностью избавиться от неопределенного поведения невозможно . Однако, точно можно создать инструмент который избавит от ошибок на своём уровне.
Меня зовут Александр Козин, программирую с 1996 года и создаю приложения для Apple с 2008-ого.
Участвовал в проектах:
- Western Union
- Audi
- YOTA
- Bork
- 2gis Flamp
- Kings and Queens by David Starkey
- Rema1000
- 585 Золотой
- И многих других
Закончил институт по специализации «Автоматизация Технологических Процессов и Производств в Машиностроении». Моей дипломной работой была экспертная система для автоматизации в машиностроении на iOS, 2011 год. Эта идея превратилась в экспертную систему для разработки ПО.
Могу сказать точно- все продукты похожи. В каждом мы тратим уйму времени на документацию, оценку, коммуникации, проектирование и разработку.
Сегодня я предлагаю обсудить исключительно последний пункт- работу с кодом.
Непосредственно разработка это только:
- Новый функционал
- Исправление ошибок
Реализовывать новые задачи часто увлектельно и захватывает. Легко получается войти в поток. И в начале проекта нет ошибок чтобы исправлять - 100% времени уходит на развитие.
Однако, в процессе неизбежно накапливаются недочёты. Забытый технический долг слипается в legacy, логика превращается в монолит и процент времени на отладку растёт, иногда драматически.
Драматичность, кстати, напрямую зависит от качества кода:

Мистер Томпкинс отложил ручку. Да, похоже, все так и есть. Раз на отладку и исправление ошибок уходит около половины всего времени и ресурсов, то чтобы добиться выдающихся результатов, можно только сократить время, отведенное на отладку. В таком случае останется больше времени на проектирование. Да, с этим нельзя не согласиться.
Deadline, Том ДеМарко
Половину!
The Raw, Эдди Мерфи
https://youtu.be/3dJzvpJF33g?si=bUgLBADjRY4mftov
Хорошо, если в длительных проектах получится сохранять паритет. Однако, на практике, может уходить и больше 80% времени на отладку, раскапывание legacy и прочие рефакторинги. Соотношение зависит в основном от качества применяемых решений- пресловутого качества кода. Это задокументированная реальность.
Тогда почему качество кода практически всегда уступает в приоритете срокам сдачи?

Очень заманчиво получить быструю скорость разработки сразу на старте проекта. Со временем темп непременно падает: Не значительно при использовании высококлассных качественных решений и категорически в обратном случае.
Почему же это происходит?
Время реализации новых задач напрямую зависит от качества принимаемых решений:

Именно поэтому нанимать двух средних разработчиков за бюджет одного опытного это плохая идея в квадрате. Ведь скорость разработки падает экспоненциально при увеличении размера команды. Но это совсем другая история.
Возвращаясь к нашей, выходит что половину времени в проекте мы тратим на:
- Ошибки
- Технический долг
- Legacy
Так как же нам ускорить разработку? Вспоминая грандиозный труд Тома ДеМарко, необходимо только найти подход который позволит писать программы без ошибок. Или части программ использующие этот подход.
Хах, звучит слишком легко. Но как же нам решить такую невероятную задачу?
Если мы будем использовать подход с лучшими решениями (высокое качество кода), это произойдет автоматически:
Время исправления ошибок не давит на сроки реализации новых задач, не нужно на скорую руку вносить изменения накапливая тех. долг. А забытый навсегда долг не превратиться в legacy. Profit.
Нам нужны решения высокого качества которые легко тестировать, переиспользовать, поддерживать и объединять.
- Но как мы можем написать код без единой ошибки?
- Ну, смотрите. Вот только что вы обнаружили ошибку в одном из модулей. Где находится эта ошибка?
- В модуле.
- Нет. Она находится на границе. На самой границе модуля. Конечно, бывают и локальные ошибки, в середине модуля, но их легче всего выловить и исправить. Самые коварные ошибки, настоящие, те, которые отнимают у разработчиков массу времени и сил, обнаруживаются в интерфейсе между модулем и всей остальной программой.
—Правильно, это каждому известно. И что же?
Deadline, Том ДеМарко
Сказано – сделано! Осталось только найти это место на самой границе и сфокусироваться на этой прослойке.
В современной разработке мы все используем архитектурные паттерны: MVC, MVP, MVVM, VIPER, etc.
И все они начинаются с Модели. Это объекты и сервисы для их получения. То самое место взаимодействия SDK и наших модулей.
Очень логично начать с начала. К тому же, именно в этом слое концентрация ошибок максимальная. Вот он Profit.

Чтобы решить любую задачу, нужно поставить цели. Их всего четыре:
- TDD
- Reuse
- Update
- Connect
Если код нужно переиспользовать, он не должен содержать дефектов. И vice versa. Протестированный код легко переиспользовать- он изолирован раз покрыт Unit тестами и не содержит ошибок в покрытых кейсах.
Такой код легко поддерживать и обновлять. Из него можно создавать сложные конструкции используя совместно разные блоки логики.
Согласно ИКР (идеальному конечному результату), всё должно остаться так, как было, но либо должно исчезнуть вредное, ненужное качество, либо появиться новое, полезное качество.
Найти идею: Введение в ТРИЗ, Генрих Альтшуллер
Вообразим Идеальный Конечный Результат:
Язык программирования в котором достаточно только описать объект чтобы получить его максимально быстро с минимальными затратами ресурсов.
В теории программирования это называется декларативным языком. Он полностью инкапсулирует логику создания и получения любых объектов.
Подходит для всех платформ:
//Получи одну геопозицию, один набор шагов, пользователя из сети и выполни блок кода
Location.one | PedometerData.one | CurrentUser.one | .all {
}
//Объект для которого не нужны опции настройки
|{ (result: Object) in
}
//Объект с данными на входе
ingredients | { (result: Object) in
}
//Один, все, по условию
ingredients | .one { (t: T) in
} | .every { (u: U) in
} | .while { (v: V) in
true
}Прототип работает на Swift:
//Request current Location
|{ (location: CLLocation) in
}
//Request .authorizedAlways permissions once
CLAuthorizationStatus.authorizedAlways | .one { (status: CLAuthorizationStatus) in
}
//Retrieve Pedometer Data updates
|{ (data: CMPedometerData) in
}
//Scan for Bluetooth Peripheral
|{ (peripheral: CBPeripheral) in
}
//Wait for a Notification
UIWindow.keyboardWillShowNotification | { (n: Notification) in
}
//Scan an NFC tag
|.every { (tag: NFCNDEFTag) in
}
//Perform Face Observation
URL(string: "http://example.com/image.jpg") | { (faces: [VNFaceObservation]) in
}
//Perform Pose Observation
//Wait for two persons
data | .while { (bodies: [VNHumanBodyPoseObservation]) in
bodies < 2
}
//Detect shake
|{ (motion: UIEvent.EventSubtype) in
if motion == .motionShake {
}
}Wand это декларативный язык. Транслируется в нативный код на этапе препроцессинга. Реализация для Android, Windows, Linux будет сделана в фонде.
В OpenSource на GitHub выложено ядро и плагины для распространенных задач:
https://github.com/The-Wand/Wand
Техническая презентация на КофеКод Краснодар в Т-Банке и How To:
https://www.youtube.com/playlist?list=PLvprpeoOl6IoZ67BcD-t0rS1L5c5J4lPh
Мы можем создавать программы для бизнеса в которых не будет ошибок на коммерческой основе и сохранять такие плагины для Wand приватными.
На длительных проектах, потенциально на 50% эффективней.
Пишите мне по вопросам создания оптимальных программ (ИКР) для любых платформ.