- Mission Impossible Code - Hyper-planning + Hyper-pragmatism = Get the Job Done Every Time (Part 1) [May 25, 2019]
Super action spies like Ethan Hunt, Jason Borne and Evelyn Salt live in an ethos of getting the job done no matter what! They complete their missions in vastly diverse conditions and in the face of the unexpected.
Super spies make use of specialized tools and techniques when available (and working), but simple and pragmatic alternatives are always top of mind. They jump out of windows, walk across moving cars, use household objects as weapons and drive cars down staircases. They are consistently fashioning situational tools of whatever is found around them. They don’t think of objects and situations as having fixed purposes - but rather that objects and situations are flexible to serve their imposed purposes.
Is it possible to write code that acts like a super spy? Over time I have adhered to a set of coding design heuristics whose parallels to super spy priorities are intriguing.
In This Post
- Recognize When an Effort is Not a Spy Mission
- When Possible, Drive on Roads
- Qualities of a Super-Spy
- Train Your Super-Spy Instincts Using Design Heuristics
- Show Me The Code
- Lesson 1 Right Now - Degrade Your Implementation For Simplicity and Compatibility Reach
- Related MI:Code and Philosophy
The Super-spy’s hard bent commitment to hyper-pragmatism is counter balanced by an equal commitment to hyper-planning. Every action, every move and every breath will be planned to a tee if and when possible. To the super-spy, planning and opportunism are not seen as two opposite ways to approach a problem, but rather as perfectly complimentary.
A super-spy’s work is never put in an art gallery, nor does it underpin the workings of some great machine. Their work is judged by results alone. While super-spies appreciate beautiful art and love excellent machines - making such things is simply not the skills they bring to bear on their work.
As a coding disposition, pragmatism first, frequently means breaking conventions of coding style, verbosity or slavish adherence to best practices - to go for what works under the most diverse conditions.
Recognize When an Effort is Not a Spy Mission
Inevitably when one speaks with passion and advocacy of a certain approach - more than a few take it as the declaration of a universal manifesto. That the principles within apply to all circumstances, for all time. I will tell you right now that I love mission impossible coding. However, that love has also attracted me (self-selected me) to a specific area of technology. I am a Cloud DevOps Automation Developer and as such I am constantly called upon to knit together systems and requirements that span many different technologies, contexts and layers.
I admit that super-spies have the same self-selection - they are called upon to knit together a variety of diverse requirements, equipment and people to get the job done. We all intuitively understand that James Bond is the best guy to drive the 2 million dollar super-spy car. But we also understand that Q - not James Bond - is the best one to build the spy car.
Some problems require super-spy field methods and some problems require spy car engineering methods. The methods advocated here might not only fail miserably at building spy cars, most are likely to be anti-patterns to such an effort.
When Possible, Drive on Roads
So if you find yourself repulsed by the methods advocated here because they do not stay within the constructs of a language, do not obey rules for self-documentation or because the solution does not account for proper modularity or other similar details, then, please keep building super-spy cars and weapons, because they are very important in the grand scheme!
Qualities of a Super-Spy
The rest of this series will look at how rugged and opportunistic super-spies engage their work using specific characteristics that ensure they can get the job done no matter what. Some of these are:
- minimal assumptions
- fault tolerant
Train Your Super-Spy Instincts Using Design Heuristics
Do the above characteristics sometimes conflict with one another? Yes.
Is it sometimes difficult to discern which of these should be prioritized in a given situation? Yes.
Despite these challenges, do these heuristics generate results? YES.
A design heuristic is like a needle on a gauge - it indicates which end of a spectrum of choice to favor - all other things being equal. However, when heuristics are combined, they have competitive tensions in the overall determination of what priorities should be optimized - precisely because all other things are NOT equal when combing them. (A combined set of heuristics are more like connected points in 3D space that define a shape within which are the possible solutions)
To get better at leveraging design heuristics, one must step in and practice - feeling and resolving these tensions again and again. It is not an unnatural learning mode for the human mind and it is supported by the ideas of Agile Discovery. The rewarding result is the training of your “instincts” so that they come up with pragmatic solutions given a complex set of input criteria. Design heuristics also account for the real-world experience that many problems are solvable with multiple different solutions. An approach of rigid laws can imply that there are few solutions or one solution to a given problem.
Show Me The Code
Ahh great, yet another article series espousing some theoretical position about how the world of code ought to work - I’d rather go code. Me too! That is why this series will be liberally peppered with working code. My working code.
This series is not an untested set of design assertions, it is a distillation of having applied the practices. The practices have emerged from performing continuous iterations of tackling super-spy problems.
Lesson 1 Right Now - Degrade Your Implementation For Simplicity and Compatibility Reach
Super-spies will quickly and purposely degrade their choices from the “best” or “purpose specific” option to older, at hand options. Don’t have a modern weapon like a gun? Use an ink pen instead!
Here is a case in point - PowerShell’s task scheduling CMDLets versus schtasks.exe. Knitting together three or more PowerShell CMDlets for scheduling a simple task is challenging - it takes hours or days the first time, but it seems to take hours or days to reliably update the same code for newly discovered requirements. In my opinion this is because the CMDLet set reflects the underlying object structures of scheduled tasks a little too directly (A place where PowerShell implementations usually hide the underlying complexity). Consequently scheduling most tasks requires creating 3 or more types of objects with CMDLets and parameters for each. To add to this, these CMDLets are not available on all versions of PowerShell and they are easy to confuse with PowerShell job scheduling CMDlets.
I’m thinking Ethan Hunt would prefer schtasks.exe - it is available on all versions of Windows and most tasks can be scheduled with a single line. For really complex scenarios an exported XML from a working task can be used to setup a new system.
Using PowerShell CMDLets:
$TaskTrigger = (New-ScheduledTaskTrigger -atstartup) $TaskAction = New-ScheduledTaskAction -Execute Powershell.exe -argument "-ExecutionPolicy Bypass -File $scriptlocation" $TaskUserID = New-ScheduledTaskPrincipal -UserId System -RunLevel Highest -LogonType ServiceAccount Register-ScheduledTask -Force -TaskName HeadlessRestartTask -Action $TaskAction -Principal $TaskUserID -Trigger $TaskTrigger
schtasks.exe is more concise to accomplish the same thing:
schtasks.exe /create /f /tn HeadlessRestartTask /ru SYSTEM /sc ONSTART /tr "powershell.exe -file $scriptlocation"
While I am aware there are ways to reduce the number of lines of the CMDLet version, the number of objects does not reduce which means condensing the lines makes the final result much more complex and challenging to build, understand and maintain. It also requires more refactoring when new requirements are discovered.
For me, this is a case where Mission Impossible coding guides me away from the preferred stance of staying within the built-in functionality of one language.
My perspective on scheduling tasks by the most pragmatic methods did not come from a single implementation attempt - I have repeatedly implemented using the CMDlets and repeatedly come up against it’s complexity challenges (both for initial build and code maintenance) and PowerShell version limitations - schtasks.exe simply does not have these problems.
The use of schtasks.exe has these super-spy benefits:
- the resultant code is simple and easy to understand.
- the resultant code has excellent back reach (ScheduledTask CMDLets are available in PowerShell V4 and later).
- when necessary, you can process schedule tasks XML which is readily exported from the task scheduler - so you can use the GUI task scheduler as an code builder for scheduled tasks.