The more I program the more I realize that most of my time is spent writing scaffolding for programs so that I can debug them and then strip away the scaffolding for production.
The problem is that I haven't found a language where the idea of scaffolding is a built-in notion. Ideally I want the scaffolding to be part of the actual program that gets stripped away for production deployments instead of being sections of code that are commented and un-commented whenever I'm debugging a problem.
An example of what I'm talking about in some made-up pseudo-language
def scaffold(f, *args) # ... pre condition verifications and state logging f(*args) # ... post condition verifications and state logging end @scaffold def buggy_function(a, b, c) # ... some buggy code end
This looks a little bit like python decorators but the semantics is different. When running in production
@scaffold literally dissolves from the AST and is nowhere to be found. Some of you might argue that I've created a very bloated and ad-hoc kind of type system but it's not quite that. I'll give an example to demonstrate.
I had written a parser for single and double quoted strings and it was failing somewhere in the middle of parsing another expression. The reason it was failing was because I wasn't handling the empty case (
'') properly and I'm not aware of any type system that would have been able to verify the validity of the state-machine for the string parser to verify that the empty case was handled properly. The only way to uncover this would have been to write tests and even then getting a reduced test case would have required the kind of scaffolding I had to put in place to pinpoint the problem. Plus, you can easily imagine other scenarios where neither the type system nor tests would have hit the bug.
I haven't figured out a good way to manage the kind of scaffolding I need during debugging and an easy way to get rid of it once I'm done debugging. How do people usually handle it?