<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Coder What Codes At Midnight]]></title><description><![CDATA[Code and Data Design]]></description><link>http://blog.novem.technology/</link><image><url>http://blog.novem.technology/favicon.png</url><title>Coder What Codes At Midnight</title><link>http://blog.novem.technology/</link></image><generator>Ghost 3.42</generator><lastBuildDate>Sat, 04 Apr 2026 10:00:56 GMT</lastBuildDate><atom:link href="http://blog.novem.technology/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[The Maturity Sequence]]></title><description><![CDATA[<p>From my point of view the meta-philosophy of agile is <em>iterative development</em> and relies on the definition of <em>capability and maturity</em> provided by the Carnegie Mellon <a href="https://en.wikipedia.org/wiki/Capability_Maturity_Model">Capability Maturity Model</a>. Scrum and Kanban provide a workshop full of tools and we choose certain ceremonies, processes and guidelines as our tools for</p>]]></description><link>http://blog.novem.technology/the-maturity-sequence/</link><guid isPermaLink="false">62d612cf720ebe00019c9e1f</guid><dc:creator><![CDATA[Craig B Allen Jr]]></dc:creator><pubDate>Sat, 29 Oct 2022 17:43:18 GMT</pubDate><content:encoded><![CDATA[<p>From my point of view the meta-philosophy of agile is <em>iterative development</em> and relies on the definition of <em>capability and maturity</em> provided by the Carnegie Mellon <a href="https://en.wikipedia.org/wiki/Capability_Maturity_Model">Capability Maturity Model</a>. Scrum and Kanban provide a workshop full of tools and we choose certain ceremonies, processes and guidelines as our tools for building a workflow that fits the problem domain and specific problem.</p><p>This model has five levels of maturity and capability. Successful software can be made at any level, but it's more likely with a more mature software process. What I personally add to this is the concept that the level a software project <em>should</em> have is related to it's actual maturity. In other words, one is not seeking maximum maturity day on, that's developed iteratively. Less mature levels are appropriate for less mature code. We apply our full set of practices incrementally, over time. </p><p>The levels are as follows:</p><ol><li>Initial - Otherwise known as heroic, where problems are daringly resolved, hopefully, through long hour antics and fire fighting incidents. A mature system should not be at level one, but a research or demonstration project may be.</li><li>Repeatable - The programmer's practices, such as installing software or giving a demonstration, are repeatable. This implies some notes and instructions, especially assuming repeatability by a team. However, some things are still only in the brains of the engineers working on the system. Some practices are ad hoc, the way a particular team naturally interacts, and will not translate forward easily as the team grows or transitions.</li><li>Defined - The repeatable processes are fully defined. In this day and age this definition is used to automate repeatable processes as through CI/CD, but also processes like sprints, right-sizing them, team size, creation, and breadth.</li><li>Capable - At this level there are metrics for the repeatability of all processes, from technical things like system deployment in the cloud, point capacity per sprint, and any other sprint metrics. This allows the team to accurately say how long a particular project will take and accurately schedule it in calendar time.</li><li>Efficient - All systems are continually refined according to metrics. These metrics will also be continually refined in terms of end results, like the popularity of the system with users, or costs. The metrics themselves thus become a focus of refinement as they now can drive the rest of the development process, but cannot be relied on forever. Over time the limitations of some metrics become clear, or the terrain changes requiring different metrics.</li></ol><p>When starting a project, level 1 and 2 can come more or less simultaneously by documenting things, always... in other words by keeping notes and publishing them.  Comments in code can be the first notes, then that can be moved to READMEs, then also to wiki's and other document repos. When installing a system, always make notes, even the most crappy notes, so that next time you can read them. Seeing what they lack creates a better next draft. After a few times the instructions for the repeated activity will be complete. If the process is inherently complex, making the notes and documentation complex, this indicates that you should change the system to make it easier to document.</p><p>This initial level is appropriate to proof of concept, prototypes, initial development for libraries and tools, done by a single person. Level two projects emerge as projects are shared with other developers, the notes published, and the system can be reliably deployed and developed.</p><!--kg-card-begin: html--><div style="width:100%; position: relative">
<img style="width:70%; margin: 0 15%" src="http://blog.novem.technology/content/images/2022/07/devMainSequence.png">
</div><!--kg-card-end: html--><p>Level 3 should exist no later than the beginning of a team development effort, especially since we have tools such as kanban issue systems, sprint workflow tools, and the like, and what such tools provide is specifically <em>level 3 definition</em>. They are places to execute the defined actions, guiding all improvements and problem solving effort.</p><p>The fact is, a functional application, such as an internal tool or small site, can operate sustainably at level 3, but will falter when a major problem arises, which it eventually will. But some organizations will prefer to wait until that time, and then do a spike, and rebuild their system, and that effort can succeed at level 3 b/c of the freedom to just write new code and abandon old.</p><p>Serious software and enterprise software (even smaller scale) must operate at Level 4. Without the measuring, when the "major problem" arises mission critical software failure is likely, and at scale this cannot be solved with a spike in a reasonable time period, and the system is too complex to rewrite greenfield, and there would be no way to measure the results of the new effort in comparison to the last. Level 4 must be in place long before its needed.</p><p>If at Level 4, you should absolutely begin to act at Level 5. The metrics are there for you to have a basis against which to improve, or measure degradation as the software increases in capability. Ultimately there is little reason to have metrics unless you use them, and if you don't improve the metrics themselves, your gaze is fixed and isn't taking into account the changing environment which leads to the major problems we are trying to avoid.</p><p>Thanks for reading.</p><!--kg-card-begin: html--><small style="font-variant:small-caps">Note: This article is subject to further editing<small><!--kg-card-end: html--><p></p></small></small>]]></content:encoded></item><item><title><![CDATA[Novem Computing Ontology]]></title><description><![CDATA[<p>I consider myself very adaptable to many varied practices used for development and workflow management. My primary concern in a local development culture is that it's internally consistent, coherent, and realistic. There are countless such systems that are valid in themselves but not compatible with each other. To mix two</p>]]></description><link>http://blog.novem.technology/novem-computing-ontology/</link><guid isPermaLink="false">6172e048e89fcb0001d1c9e9</guid><dc:creator><![CDATA[Craig B Allen Jr]]></dc:creator><pubDate>Sat, 30 Oct 2021 21:28:00 GMT</pubDate><content:encoded><![CDATA[<p>I consider myself very adaptable to many varied practices used for development and workflow management. My primary concern in a local development culture is that it's internally consistent, coherent, and realistic. There are countless such systems that are valid in themselves but not compatible with each other. To mix two incompatible approaches is what it means to not be coherent, when the two systems don't cohere with each other under a compatible set of approaches and assumptions. This means the value of a practice from one well vetted workflow cannot be relied upon when used out of the context of that workflow. </p><p>In practice, each system of practices in a workflow will obviously have its strengths and weaknesses. Only systems with well known catastrophic weaknesses, such as "waterfall", are thought of as invalid. Centralized designs catastrophically fail at scaling. However, the flaws of waterfall and centralization can be mitigated, so removing some of the practices and creating new practices that address those weaknesses is never off the table. Some special projects and some particular cases may lead us to seek some of their practices for a particular project.</p><p>Let me point out specifically what the reader may have already noticed, I am mixing engineering management issues with engineering architecture issues. This is intentional, because the two are intimately related. The engineering management practices used to develop software leaves its mark inside the software, and leads to many of the characteristics, laid down in sedimentary fashion in the source code. Nevertheless, as I continue, I will be focusing more and more on the analytic engineering abstractions used to understand particular software systems, leaving you to relate them back to workflow design.</p><p>I analyze all software systems using a set of abstractions into which I decompose them. Another truism, we all have no choice but to do this, but what is the set of abstractions? This truism applies to any existing systems and subsystems, be they libraries, processes, classes, or executables, and to any system I will build. I do something similar with workflow methodologies. For example, I decompose a team's particular use of Jira, or other work tracking software, into my own project tracking methods.  I map it into my system, but I don't <em>change </em>it. My own system is just a set of elements to which I can break down the other system, like analyzing water and finding it's hydrogen and oxygen, related by covalent bonds.</p><p>I recognize, and the reader should consider, that the system being decomposed to elements will have richness that is not obviously represented directly in the decomposition.  The behavior of water is not obviousl from the behaviors of Hydrogen and Oxygen on their own. Their relationship transforms their behavior into a very different observable behavior when connected in a system. The decomposition is just an additional way of understanding it, translating it, into more fundamental laws of computation. They allow doing local work in the system.</p><p>My fundamental system is un-opinionated, like organic chemistry, allowing all possible system behavior, but it is very reductive.  A particular system <em>always</em> <em>is opinionated</em>, it is specifically itself, and makes decisions about which ingredients to include and what relationships to coax them into. A cake and a jam can both be understood in terms of organic chemistry and seen as particular implementations of it. If an organic chemist encounters the most amazing food they've ever had, having never encountered anything like it, they can be amazed how such a thing is possible. When they take that food to their lab and decompose it, they will nevertheless discover the basic elements of organic chemistry or it would not be edible. They will discover the enzymes, emulsions, and particular chemicals. This increases their understanding of the particular system that surprised them with new systematic behavior. </p><p>You can describe baking cake in terms of chemistry and emulsions; the "opinionated" part is what makes the result a cake instead of an industrial solvent. Decomposing a problem domain into my own model helps explains the problem domain for me, clarifying any inherent complexities. In my model there are general purpose software artifacts that can be applied at this elemental level which at the higher level may seem opaque or unsolvable due to assumptions upon which the system relies. </p><p>In workflow, I maintain my model for what's going on in the software in parallel with any workflow system like Jira. Jira and the like are <em>communication software </em>for having a conversation about workflow. I'm certain good managers and engineers maintain their own models of project status throughout a project. If they didn't, they wouldn't be able to improve the workflow they implemented in Jira, or define it in the first place.</p><!--kg-card-begin: html--><div style="margin:1em; padding:.5em; float:right; width:45%;border: solid gray 1px ">
    The word <i>ontology</i> is a noun which names the group of all things referenced by a system. <b><i>For example</i></b>, the ontology of mathematics is numbers, the number line, the arithmetic operations, and so on. The ontology of physics is math plus the measurable quantities, space, mass, and time. The ontology of space is a coordinate system, of which there are many complete examples, cartesian, polar, logarithmic, which all share dimensionality.
</div><!--kg-card-end: html--><p>For the programmer or logician of any sort, abstractions are like tools in a workshop. They are used to break down ideas into parts, or combine them into systems. There are an infinite number of ways to equip a workshop, but there are patterns. The spectrum of tools you'll likely need or find helpful for a type of task bears relationships to all possible tools. A wood shop for making furniture will bear many similarities to other furniture workshops. It will even bear noticeable relationships to a workshop for making doll house furniture. Woodworking shops bear some similarities to a metal machine shop. Japanese gardening tools and European gardening tools cover the same spectrum of tasks, some are interchangeable with each other, but some are special. </p><p>The abstractions below are the primary tools of my workshop. Of course I have a lot of more specialized tools, including fantastic software created by thousands of fellow programmers. But all these other tools are decomposable into these principles and can be built from them. I think of all particular or specialized tools (i.e. opinionated software) in terms of how it can be decomposed into the following elements.</p><h2 id="unit-of-computation-and-flow-of-control">Unit of Computation and Flow of Control</h2><p>The unit of computation is the <strong>function</strong>. </p><!--kg-card-begin: html--><div style="margin:1em; padding:.5em; float:right; width:45%;border: solid gray 1px ">
    <p>
    By "function" I actually mean the general case, a <i>routine</i>. The <i>coroutine</i> is the most general case of a routine. The ordinary function in most classical programming languages is a special case called a <i>subroutine</i>. A subroutine has one entry point taking input data, and one exit point returning output data. Of course, internally the code can branch, and return from different points with different data, but a subroutine can return data exactly once, and accept data exactly once.
    </p>
    <p>
        In the <i>general case</i> of the <i>coroutine</i>, a coroutine can return a <i>series of values</i> via <i>yielding</i>. After each yield, the caller can re-enter the coroutine at the point of the yield where it will continue running. New data can be sent in during this re-entry, and new output data can be returned until the routine decides it is done, or the caller stops re-entering. Communication between the caller and callee is ongoing, the caller is co-operating with the caller, thus, it's a co-routine. The relationship between caller and coroutine is that of highly efficient single-threaded "cooperative" multitasking.
        </p>
    <p>
    Coroutines are about cooperative multitasking in a single thread in which the caller is a controller (aka "a control loop") and the callee is a worker. The controller is not necessarilly a loop, technically, but it will generally use a loop to call the co-routine, since it is called repeatedly before finishing.
        </p>
    <p>
         In the case where the called routine does not handle data being sent in when re-entering the routine, the routine is called a <i>generator</i> and can be used as an iterator, such as in a for..in loop. The <i>generator</i> yeilds a series of values, but only accepts exactly one input. Note that async/await in JavaScript and asyncio in Python are implemented with generators. The syntax in asyncio is syntatic sugar to yeild control back to an event loop that can schedule the function call for the future, and await that resolution in the calling scope.
    </p>
    <p>
        Having said that, the subroutine, or traditional function, is good enough to think of as the base abstraction conceptually, since coroutines have special coupling with their controllers, another subject. My model relies on the interchangeability of messages and functions, which is most easily imagined with subroutines/functions because of the looser coupling between caller and callee since message passing (input message/output message) happens exactly once in and once out. That is, the regular function signature, taken as a message schema or vice versa, is universally transmitable, as a network message for example. The signature of controler/coroutine interaction always adds some particular protocol of interaction, not only in the data schema passed as with a subroutine, but also acceptable vs unacceptable ordering issues and the type of control messages which may be a part of what is necessarilly a communication protocol. 
    </p>
    
</div><!--kg-card-end: html--><p>To execute the function, we hand it the <strong>flow of control</strong>. That of course gives the function control, and the flow of control flows downward in the function, and when sub-functions are called, deeper in the stack. The currently running function is the <em>control, </em>to the function it calls, and its caller is its controller. Having said this, in practice some routines specialize in controlling their called functions, and are called <em>controllers </em>in the design. Other routines specialize in performing the system logic (i.e. data reduction and business logic) , and these are called <em>workers</em> and <em>services</em>.</p><p>The flow within the function <em>could </em>be entirely sequential, it <em>could </em>branch, it <em>can loop </em>and so on, skipping around the source code. Nevertheless this is all powered by a <em>downward flow </em>through the source code. The body of the function is executed from top to bottom, from caller into to callee, deeper down through the callee, and eventually back to the caller to move downward again. Embedded in the flow of control in the body of some of the functions are the <em>computations</em>. The computations are the explicit <strong>data transformations </strong>that take place. Functions always transform data. To return nothing is to transform your input into nothing.</p><p>Lest you think this is a philosophy purely from functional programming, no, it's merely noting that other abstractions, like "classes", can also be thought of as made of functions. I am not a functional programming purist, merely a functional realist. Object oriented class declarations declare a set of functions. It provides syntactic sugar for easily bundling functions together in a tiny library, and sharing state. The shared state can be freely and multiply instantiated, allowing multiple alternates states handled simultaneously, and provides a way to pass this library as a single reference, supporting things like injection of complex dependencies.  That's super useful, and is a set of functions coupled together. Often, in a regular old standard function library the library keeps state, the pattern does not require OO syntax, it's just a lot easier and better looking. A class is just a useful syntactic sugar from the compiler to make working with this miniature library, the object instance, easier to manipulate and easier to write.</p><p><strong>Decomposing things into functions.</strong></p><p>A function always owns exactly one flow of control, which to the function is like its flow of consciousness. The flow is always at one particular point of the source code of the function at any given moment in time. That is analagous to <em>what the function is thinking </em>at a particular moment. It will share that flow of control with other functions, no doubt, the other functions it calls. Even the lowest level functions still are made of function calls, system calls, or inside the kernel, device driver calls. Even though at some point a function turns into voltages and a circuit,  from the programmers point of view it's functions <em>all the way down</em>.</p><p>A process is always <em>started </em>by calling a single function. A thread is created <em>by calling a function</em> in a way that gives it a new flow of control of its own. As the initial callee, it's now "controller" for everything that it calls, and everything called by the functions it calls, everything beneath it in the stack. In principle, all these subfunctions are "under it's control". However, it has temporarily given up control, giving it to the callee. Though it will eventually return to it's caller, for now, it decides when to return or just loop forever, and it's caller is dormant. It can do things to never return to the controller, such as call process exit, or throw an exception which <em>may</em> skip the caller on the way up the stack. Note: in most  if not all languages and systems the caller always has ways to intercept such attempts to never return control, such as catching the exceptions or similarly intercepting a process exit event.</p><p>All programmers will know what I'm saying, but probably have not narrated it this way to themselves. I hope you understand my perspective and can see how it fits  with or against your own way of decomposing programming. For example, you may not want to consider the caller technically "dormant" b/c maybe that's a poor synonym for "paused". Perhaps you see functions as conceptually properly objects, so everything is objects to you is a lower level decomposition. I'm eager to hear such feedback. A large part of my dedication to my own decomposition techniques is the pragmatic value it's generated for me in my work, allowing me to understand anything throughout the stack of tools in distributed systems.</p><p>When a message is  sent to another server, the sender is <em>calling </em>the receiving routine that will process that message. There is always a routine that accepts that message after all. Generally it will be a routine that knows how to dispatch the message further. Obviously there may be many functions handling many messages. Somewhere after delivery is a function that has essentially been called by the caller in the other process. The caller and callee still share understanding of the input data schema, but what they don't share, is a common flow of control. The sender does not have to be paused/dormant/blocked. </p><h2 id="loose-vs-tight-coupling">Loose vs Tight Coupling</h2><p>Functions have <em>callers</em>. The relationship between the caller and the function is a <em>coupling</em>. The coupling can be <em>loose </em>or <em>tight</em>. A loose coupling is easier to deal with. There is give and take in it. In some cases a tight coupling is needed, where two systems each have orthogonal purpose, but still cooperate closely to implement the features of a complete system. Tight coupling can be more computationally efficient, use-of-memory efficient, that is, <em>optimized</em>. It's fair to say when possible we prefer loose couplings, for they can more easily be made to degrade gracefully. </p><p>There are two factors contributing to the tightness of the coupling, <strong>shared data schema</strong>, and <strong>shared flow of control</strong>.</p><p>Functions calling each other in a single thread are tightly coupled in flow of control. The advantage of this coupling is they know they are not fighting each other to access data, and so no mutual exclusion systems are needed. Things run efficiently with zero race condition collision between the functions. Also, it's unavoidable that many functions are run with the same control flow and from the same scope, as functions are made of function calls.</p><p>A function sending a message to a function in another thread is more loosely coupled to it. Because of the intermediary messaging system, little is known about the other function's flow of control. It may be in another thread or even another process. It could even be executed later in the same thread such as with async functions. It may be broken up into a number of messages that fan out and are handled by multiple functions across multiple processes, coupling the caller indirectly to multiple callees simultaneously. </p><p>The caller and callee, wherever is runs, are still directly coupled by the <em>shared data schema </em>of the data passed between them. Both <em>must </em>understand the data schema with some degree of compatibility. If they both have to have <em>the exact same understanding about the whole body of data passed</em>, that would be more <em>tightly</em> coupled. If each only had to understand small parts of the data passed, the functions are more <em>loosely</em> coupled. An example of the partial schema would be a caller that passes a whole object, such as a user object, to a function that only understands one part of the schema, such as where in the shema the user's name located. Thus the callee doesn't care about the rest of the schema, just so long as the user's name is in the expected location.</p><p>A good example of the tightest possible data schema would be two functions communicating by a unique binary protocol. In cases like this a list of long integers stored as bytes may not be compatible when the same code is run on different processors with different byte ordering.</p><p>In general, the more one function has to know about its caller's or callee's data schema the more tightly they are coupled by data schema. For example, if a calling function must call specific other functions to prepare the data to pass to function G, that's a tighter coupling than if it can just call G without preparation, given the data it started with. If function A called function B and B calls C with the same input A gave it. This couples A to C in that case, but ironically, A and C might be only very loosely coupled to B! If B's job is passing data from A to C, then all it has to know is enough to pass the data, which even in the binary data example, means a pointer and length.</p><p>You can empirically test how tightly coupled functions are, in a real system, by trying to change one of the functions, and seeing how many other functions <em>have </em>to change with it. Therefore, a general concept of coupling is to ask, "if I change function G, is it likely I will have to change functions that call G?" and "if I change function G, is it likely I will have to change functions that G calls?". The more function that have to be changed along with G, the more tightly coupled the functions are. </p><p>Another way of looking at the same issues is to ask "how easy is it to refactor this set of functions?" To the first few orders of accuracy, <em>the looser the coupling, the easier it is to refactor the whole set.</em> However, taken to extreme, the looser coupling will not actually make refactoring easier. This is because the loosest coupling evolves toward highly configurable systems, which are useful in reducing direct coupling. This can become overgeneralization which actually introduces configuration complexity which might in fact make refactoring difficult due to too much indirection. This simply reminds us that in spite of "preferring" loose coupling, in fact, what is desired is optimal coupling. The preference for "loose coupling" comes historically from the era of mostly-only tight coupling, which was inevitable before general data encodings were available.</p><p>The ideal design suggested by this interpretation is one in which functions perform well isolated responsibilities, and thus don't have change because another function changes. They are ideally plugged into the system in such a way that changes that don't change their responsibility don't affect them.  If adding a new feature, only callers that want to use the new feature have to change. If changing how a feature is accomplished (or fixing a bug), then callers don't have to change how they call the function.  </p><p>Optimized systems often use tight coupling to solve complex problems and present loose couplings to the rest of the system (e.g. to other processes in a distributed system).  A point I'm trying to make clear is that there are potential reasons to do any conceivable type of possible coupling, via control flow and data schema planning, given a problem domain where it's advantageous. But at the same time, there is a general case for the vast majority of software in which an array of mostly loose couplings is used between functions regardless of if they are subroutines, are in the same thread, in another thread, or in another process, on another machine.</p><p>Every software system is a set of choices made about functions and how they are coupled by data and flow of control sharing. For me all the answers to questions about the swarm of needed functions and their optimal coupling come from the problem domain itself. Certain patterns are called for, and the problem domain is what calls for them.</p><!--kg-card-begin: html--><small style="font-variant:small-caps">Note: This article is subject to further editing<small><!--kg-card-end: html--></small></small>]]></content:encoded></item><item><title><![CDATA[Javascript Coroutines]]></title><description><![CDATA[How Coroutines work in javascript, with a working simplified demonstration of how to set up a nested system for executing coroutines sequentially for data processing pipelines.]]></description><link>http://blog.novem.technology/javascript-coroutines/</link><guid isPermaLink="false">5e6d4181e89fcb0001d1c974</guid><category><![CDATA[Programming]]></category><dc:creator><![CDATA[Craig B Allen Jr]]></dc:creator><pubDate>Tue, 10 Mar 2020 00:47:00 GMT</pubDate><media:content url="http://blog.novem.technology/content/images/2019/08/horizontalCoroutine.gif" medium="image"/><content:encoded><![CDATA[<img src="http://blog.novem.technology/content/images/2019/08/horizontalCoroutine.gif" alt="Javascript Coroutines"><p><strong><em>"Subroutines are special cases of ... coroutines." -- Donald Knuth.</em></strong></p><p><a href="#novem-coroutine-approach"><em>tldr; version with the example is below</em></a></p><p>Recently I was adding a minimalist "recipe system" to an existing code base with the intention of refactoring it into a full system over time. A "recipe system" is a data reduction system driven by a "recipe", which is a series of steps. It's a concept, as far as I know, first envisaged at UKIRT in Perl by Paul Hirst et al. It was further developed at Gemini Observatory, adapted to a pyramid of python coroutines which filled the role of the recipe steps. I'll go into that pattern more in some other blog.</p><p>In this case I just needed to execute a list of coroutines, in JavaScript. Think of the steps on the list as executing business logic or data reduction, as coroutines they are functions that can yield values, like returning a value, but also be re-entered where they left off. </p><p>These steps are atomic units of interest to the problem domain. They can be written single mindedly since they are mostly decoupled from their control system. The control system in contrast is pure software artifact, problem domain neutral, while all problem domain behaviors are within the steps. To execute the list I needed to write a parent <strong>coroutine</strong>. </p><p>This routine provides the foundation of a control loop, since coroutines are presented to the callers as functions returning iterators. The iterator will iterate once each time coroutine it's calling calls <strong>yield</strong>. A coroutine can thus be written like an ordinary function but still cooperate with a control loop.</p><p>The calling function will always be a custom control loop. The body of the loop has control over continued execution. It can trap all errors. It can inspect output data and augment input data. It is able to perform services in order to offload them from the routines themselves, such as database modifications, to further purify the steps as atomic units concerned only with a specific step of relevance purely from the problem domain. It will obtain the recipe's initial input and dispatch the output as appropriate.</p><p>I was adding this directly into the existing code base because I've used generators and coroutines for a long time in python. I have also used them in javascript. I had a good idea of how I wanted it to work. However, the added issue of async functions and passing around promises got me confused and went in circles for a bit. I suffered cyclic off by one paralysis.</p><p>I did what I always prefer to do in such a situation; I stepped back and made a small stand-alone demonstration for myself, outside the real world code base I was working on. The demonstration is minimal, as they should be, with just the parts needed to demonstrate the structure of the design. It's a small software tool, meant to help the developer visualize concepts in isolation, so they can be better visualized when deployed in concert together. </p><p>In this case that is just the required two level nesting of coroutines. It's often true that code written for the demonstration is subsequently helpful in pieces, if not in the whole. The clarity of isolation a demonstration project provides can also prived the base interfaces which will be clear in practice. Also, such demonstrations can evolve over time as the design concept is enhanced and forks in the road are taken. In the long run they become the ideal implementation of the design originally demonstrated, and demonstrate if that is or is not actually a good thing. </p><p>These type of projects demonstrate useful patterns to team members and are to be encouraged. Time should be put aside for them. In this case I put my own time aside, rather than my clients. </p><!--kg-card-begin: markdown--><div style="margin:1em; padding:.5em; float:right; width:45%;border: solid gray 1px ">
<h4 id="asyncawait">async/await</h4>
<p>I've found the simplest way to understand async and await is that:</p>
<ol>
<li><em>async</em> functions return Promises. So the <code>return retVal;</code> statements in a function marked <em>async</em> will really be a function wrapped in a Promise, which when resolved will become <code>retVal</code>. A promise is an object promising to eventually emit a return value.</li>
<li><em>await</em> is a keyword that can be used inside of <em>async</em> functions to wait on promises. Thus <code>await someAsyncFooFunction(arg)</code> will essentially pause at the given point in the function until the promise resolves. It also means you can <em>not</em> await an async function and pass the return value around as a promise, resolving it whenever you like.</li>
</ol>
<p>The whole scheme is to allow us to write functions that look like functions, and let the caller control when functions block or when they can run in parallel. Since the entire concept is single-threaded, mutual exclusion is not needed, but real parallelism happens due to I/O blocking. The low level functions don't have to cooperate with the schemes of their control systems.</p>
<p>Notably this means try/catch blocks can be used, an essential thing. I would say that the use of await and async obviates the desireability of most Promise handling. However, there are certain cases where it's very convienient, for example to start execution of a number of functions and awaiting <code>Promise.all(..)</code> of them to avoid sequentializing I/O.</p>
</div><!--kg-card-end: markdown--><p>As I said, in addition to coroutines, the system also uses the async/await syntax. It's worth noting that async functions are implemented under the hood as generators, and are a great example of what generators can do, and how linguistic sugar and like the async/await keywords can expose how expressive the concept is. At the time the coroutine itself was required to be synchronous by node. This was slightly unfortunate. (Now in 2021 async generators are supported in node and all browsers).</p><p>Given that, the stack will be like this: </p><ol><li>An <em>async control loop</em> function calls...</li><li>a <em>synchronous coroutine</em> that calls...</li><li>an <em>async "primitive" function</em>.</li></ol><h3 id="brief-on-terminology">Brief on Terminology</h3><ul><li>the list of functions is a <em>recipe</em></li><li>the functions in the list are <em>primitives</em></li><li>the <em>control loop</em> is the caller iterating over the coroutine</li><li>the  input or output data is the <em>document; </em>think of it as a complex data type, a JSON-serializable pure object.</li><li>for a bit more on <em>coroutines</em>, see Wikipedia contrasting them with subroutines <a href="https://en.wikipedia.org/wiki/Coroutine#Comparison_with_subroutines">here</a></li></ul><h3 id="the-goal">The Goal</h3><p>I wanted the ability call an <em>async</em> function (the <em>run</em> action) which would loop over a coroutine (the <em>steps</em> action) that itself iterates over a sequence of functions (the <em>primitive</em> functions). The coroutine is used to weave the infrastructure into the execution of the pipeline while also isolating the primitives from the details of the execution context. The primitives just look like basic functions, input and return value with statements in between. The yield statement just allows returning values to the caller early, and seems to continue right away after from the point of view of this primitive function performing the "step".</p><p>This allows the primitives to be<em> lightly constrained functions</em>. They <em>only </em>worry about the data transformation they perform. This is good isolation of concern in general but is also especially useful in data pipelines since scientists and data science programmers, who will be programming the <em>primitives</em> and authoring <em>recipes </em>in principle, don't have to know the underlying execution system. They save time not knowing it, and that also enables evolving the control system and having more than one control system for different execution environments. </p><p>A data scientist writing an advanced data processing step might very likely not be skilled in the very different kind of infrastructural programming that is heavy with software artifacts from a whole different domain of abstractions. Their expertise is the discrete mathematics and physics involved in the step itself. In the business domain it's similar, the person that can implement a specified step in a business process is not particularly likely to find the abstraction of the control system easy to comprehend, even if it's kept minimal and with few lines of code. In fact, the few lines of code can make it very fragile, which a business step can often be conceived of an written by even a junior programmers, since it will have been specified in advance, and just be a simple function (albeit with yields). </p><p>Even when the same people write both the primitives and the control system, it's better to separate expertise with the control system from expertise in data transformation logic. They're simply two different domains that do not want to be married, but rather business partners.</p><p>I wrote two versions, one in which the primitives were regular functions, and another in which they are <em>async</em> functions. I had the impression maybe the promises were impacting my confusion so I excluded them on the first pass of my demonstration. Turns out that wasn't my problem. As it turns out, the only change required was that the control loop awaits the primitive function. As far as what the problem <em>was, </em>it was just getting the ideas straight. </p><p>In this blog I'll just go through the version with async primitives. The source code for the demonstration is at the bottom.</p><h3 id="operation-of-the-control-loop">Operation of the Control Loop</h3><p>The coroutine needs to pass an <em>input document </em>to a <em>primitive </em>which will return a Promise. The Promise, when resolved, will provide the <em>output document</em>. In the demonstration I just pass the output received from one step into the next step as input (by passing it as the argument to <code>next(..)</code>), but in real systems the control loop will also perform other actions. These can include a wide variety of services, such as validating the document, saving it, normalizing it, annotating it with workflow information, providing debug output to logging systems, interpreting the document as an instruction, performing some service before the next step of the recipe, and a very wide and unrestricted array of possible and appropriate services.</p><p>This makes a recipe system built this way very good at integrating external systems into the data reduction process. </p><h3 id="description-of-coroutines-and-generators-for-a-coder">Description of Coroutines and Generators for a Coder</h3><h4 id="generators">Generators</h4><p>A <strong>generator</strong> is a type of function that <em>yields</em> return values instead of just <em>returning</em> them. The difference is that a <em>return</em> statement exits the function whereas a <em>yield </em>statement merely <em>pauses</em> a function. Execution can re-enter the function from the paused point, the function keeps running from there. What?!</p><p>The function scope is saved, preserving all local variables, and the controller (whoever called the function) takes over after the <em>yield</em>, until re-entering the routine. Obviously there has to be some syntax for re-entering just as there is a syntax for <em>yield</em>ing, and it's possible to imagine a few.</p><p>Instead of calling the generator once, like a regular function ("subroutine"), you have to somehow call it multiple times, once for every time it yields. The caller also has to know when the coroutine is done yielding in order to stop reentering it. Fortunately, languages have long had an idiom for this, iteration, and convenient syntax for iterating, such as the for loop. </p><p>Classically one could easily iterate over an array, but using an iterator objects abstracts this. Any series of values can be yielded, linked lists, tree traversals, or a sequence of function calls. Indeed, the latter is the most general case, and generators are functions that, using in-language syntax, are packaged as an iterator compatible with all other types of iterators from the point of view of the runtime engine.</p><p>To the caller a generator looks like a function returning an iterator object. Iterator objects can always be repeatedly called until done using a <code>for</code> loop (<code>for .. in</code> in python and <code>for .. of</code> in javascript). The function return value behaves just as an iter<em>able</em> does, such as a built in iterator such as an array or list iterator, as well as custom iterator object such as database query iterator. </p><p>Therefore you simply iterate over the generator in a loop. The generator call goes where an array variable (etc.) would go (e.g. <code>for i of arrayVar</code> becomes <code>for i of arrayGen()</code>). This is the first really compelling thing about generators, at least it's why I started using them.  You can replace a giant array variable with a small  and efficient generator that "generates" the values that would be in the array. For example, at one time the common idiom in python (<code>for i in range(1000)</code>) would create an array of integers from 1 to 1000, the return value of the <code>range(..)</code> function. That's a lot of memory for no a good reason. It's tolerable for small ranges but becomes totally unworkable for millions. It's annoying at all sizes, although the syntax would otherwise be eloquent, what they call pythonic in the python world. The use of generators allowed this desirable syntax without that cost. The generator replacement (originally <code>grange(..)</code>, but eventually this replaced  the <code>range(..)</code> function itself) can create the values one at a time as they are needed. A range of 1000000 is not less efficient than a range of 10.</p><p>Another particularly useful application is the use of generators in database queries where there may be a large number of rows or documents returned. A generator allows you to hide all paging and cachine logic in the iterator itself, while the calling loop is able to concieve of the query as returned one at a time. This makes the code that's processing documents (or 'rows') blissfully ignorant about where the "rows" are coming from, or even if any batching and caching is going on. Coroutines are really amazing for isolating special purpose code, business routines, from control systems which are general purpose. </p><p>Outside the generator (to the caller) it looks like any other continuous iteration. Each iteration of the loop runs the generator function from the last <em>yield </em>to the next one.</p><pre><code class="language-javascript">for (yieldedVal of generatorFunction(arguments)) {
  // do something or break to abandon generator
}
</code></pre><h4 id="coroutines">Coroutines</h4><p>In the case of a <strong>coroutine</strong>, in addition to yielding values outward, upward in the stack, to the control loop, it has a way to <em>receive</em> values. In both javascript and python this is accomplished by the <em>yield</em> statement itself acting as an <em>rvalue</em> which returns a value, an <em>lvalue</em>, specifically the variable being set within the coroutine.</p><p>Unlike with a generator there isn't a built in language syntax for this, and we hav to use the iterator as an object and call it's <em>next function, </em>a part of the given languages iterator interface. Thus:</p><ul><li><code>next(injectedValue)</code>  is called by the loop which is driving the coroutine with a control loop.</li><li>an <code>injectedVal = yield outputDoc</code> statement inside the coroutine receives the value. The coroutine variable, <em>injectedVal,</em> ends up being set to the control loop's argument to <code>next(..)</code>, <em>injectedValue</em>. </li></ul><p>The variable <code>outputDoc</code> is what the previous call to <code>next(..)</code> returned. This is a source of confusion. The routine executes <code>yield someVal</code> and pauses. When re-entered it resumed first by accepting the injected value, the "return value" of the yield, and applying it as appropriate, e.g. setting a variable.</p><p>As mentioned above, the "for loop" syntax has no way to send in these new values. Instead, use of the coroutine has to be done in two steps, instantiating vs iterating. We are doing manually what the "for loop" does under the hood, calling the iterator's next method explicitly.</p><ol><li><strong>instantiate</strong>: you call the coroutine as a function to instantiate it, the function returns the iterator. The coroutine is automatically in the yield state at the top of the function. </li><li><strong>iterate</strong>: you repeatedly call the instantiated object's <code>.next(..)</code> member, usually in a loop. The end of the function is communicated the way any iterator is, with some sort of end of iteration return value or exception.</li></ol><p>Each call to <code>.next(nextVal)</code> returns whatever value the coroutine <em>yield</em>s. The yield inside the coroutine "accepts" whatever the argument is to the  <em>subsequent</em>  <code>.next(..)</code> call. This little exchange is one of the things that originally make coroutines confusing from my point of view. Even after I inevitably think I've got them understood, I can find myself getting off by one. The yield statement pauses the code, and the return value is really whatever the control loops sends as an argument to (next). It should be thought of as a message.</p><!--kg-card-begin: markdown--><div style="margin:1em; padding:.5em; float:right; width:45%;border: solid gray 1px ">
<h4 id="lvalueandrvalue"><em>lvalue</em> and <em>rvalue</em></h4>
<p>To put this simply for purposes of this blog, which is to say grossly simplified:</p>
<ul>
<li>an <em>lvalue</em> is something that can go on the <em>left</em> side of an equals statement</li>
<li>an <em>rvalue</em> is something that can go on the <em>right</em> side of an equals statement</li>
<li>e.g. <code>lVariable = rStatement</code></li>
</ul>
</div><!--kg-card-end: markdown--><h3 id="why-it-s-odd">Why it's odd</h3><p>In the coroutine you have:</p><pre><code class="language-javascript">const injectedVal = yield yieldedValue;
</code></pre><p>The <code>injectedVal</code> can be anything the controlling loop sends in as an argument to <code>next(...)</code>. Strictly speaking it bears no particular relationship to the <code>yieldedValue</code>. This is a weird thing to me. What I'm used to with a statement in any language is that the <em>lvalue</em> bears a <em>direct </em>relationship to the variables, constants and arguments in the <em>rvalue</em>. It would be odd if <code>parseDate(dateStr)</code> returned a value of no relation to the <code>dateStr</code> passed in. But <code>yieldedValue</code> is just a value the coroutine is sending to its caller. And <code>injectedVal</code> is just a value the caller is sending to the coroutine. Coroutines cooperate in cooperative multitasking, which is why they are "co"-routines. It's specifically a cooperative multitasking model.</p><p>Normally <code>y = x+2</code> means that <code>y</code> now has a relationship to <code>x</code>. It's a transformation of <code>x</code> by 2. Deep in the mind, I think I usually consider the "return value" as <em>made from </em>the "argument", and I suppose most programmers do as well. I mention it now because this was one of the things that has confused me in this case while adding async to the equation. </p><p>When this <em>is</em> the case, the function is a "pure function", but even impure function generally emit a return value related somehow to the arguments sent in.</p><p>With coroutines it's absolutely a message exchange going on, between the controlling function and the coroutine. The coroutine is cooperating with cooperative multitasking by saying only when is a good time for it to yield, at a minimum. Beyond that it is sending and accepting "messages" with yield statements. It passes the control flow back to the caller, and the caller passed control flow back to it. </p><p>The <code>yeildedValue</code> was <em>sent</em> to the calling routine. The calling routine <em>sent</em> the coroutine the <code>injectedVal</code> when it wanted it to run again, thus controlling it. Design-wise, the yield statement is a handoff point between two separate routines that are cooperatively multitasking, thus "co"-routines. The control routine can stop early but the coroutine is authority over when it's done. </p><h3 id="step-one-the-coroutine-object-instance">Step One, The Coroutine Object Instance</h3><p>To instantiate the coroutine object:</p><pre><code class="language-javascript">const cor = coroutine(inDoc);
</code></pre><p>At this point the body of <code>coroutine</code> <em>has not run at all</em>. Slightly confusing is the fact that the arguments to the coroutine have, however, been added to the coroutine's scope (so arguments that are function calls, for instance, will have been called). That's all that's happened. It's as if calling the function has executed only the creation of the stack and the opening brace, pausing before the first statement, with the function arguments declared but not yet used. The coroutine will only start to actually execute when <code>next(..)</code> is called for the first time.</p><h3 id="extra-next-extra-yield">Extra <code>next()</code>, extra <code>yield</code>?</h3><p>Most instructions on making a coroutine in both python and javascript suggest that you call <code>next()</code> immediately after instantiating the coroutine. This acts as a sort of initiation that "starts up" the coroutine. This use of next is outside the actual use of the coroutine as an iterator. This means an extra yield in the coroutine, acting as something like an initialization ack (acknowledgement). To me, since a generator 'generates' a 'virtual' array in my mind, it also feels like having a phantom member at element -1 in the abstract array the coroutine generates. I don't prefer it.</p><p>It's worth understanding the issue, for example Harold Cooper's <a href="https://x.st/javascript-coroutines/">blog post</a> on coroutines is still quite interesting and useful although it suggests using a wrapper function that does the above. This wrapper both instantiates the coroutine and makes an initial next call with no arguments. Absolutely no offense is intended to Harold Cooper, as I say, the suggestion is standard and his blog is nicely informative, so I once again suggest reading it. I reference it as proof that I didn't not make the issue up just to solve it :)</p><p>Here's Harold's coroutine wrapper. Notice of course it's a function that is called 'coroutine' which "starts" the argument "f". The function "f" is the actual coroutine.</p><pre><code class="language-javascript">function coroutine(f) {
    var o = f(); // instantiate the coroutine
    o.next(); // execute until the first yield
    return function(x) {
        o.next(x);
    }
}
</code></pre><p>Rather than this I want to call the coroutine with every <code>next()</code> being called exactly the same way inside the iterative part of the execution loop, as done with the generator. I don't want to use the iteration function "next" in a special way. To do so imposes a constraint on the generator that it "begins" with an initial <em>yield</em> statement, and anything before the yield statement has special status as to what must or must not go there.</p><p>I want the coroutine entirely compatible with a generator, because the only difference is a generator needs only initial argument, not a series of them. If a control loop doesn't care about the values being emitted, it can use it just like a generator since a generator is just a coroutine that's not accepting other non-initial arguments. </p><p>I also want to call the primitive only with data it needs to do it's job, not a communication ack. </p><p>In my version each <code>next(..)</code> call will always send in the <em>current document</em> and each <code>yield</code> statement will return the document in its possibly intermediary states. In general one will also have a way to pass out requests for the control system to perform a service before the primitive is resumed. This is how you offload tasks to the control loops making them loosely coupled, so the control system control what databases or other services are used, and how, while business logic in routines specifies only that this data ought to be saved, or emailed, etc, at a high level. For the demonstration it is a "document" which is passed in and out, giving the control loop and the caller the chance to manipulate the document. An example use could be the control loop performing validations, logging, or sending messages to clients regarding the status of processing.</p><p>Most explanations of coroutines in Python are similar to the above. I think the apparent need for the extra <code>next()</code> call is like the natural occurrence of the one-off error, coming from the structure of the tool mixed with our prior habits. It's why there is no year 0 AD but there <em>is </em>year zero in <a href="https://en.wikipedia.org/wiki/ISO_8601">ISO 8601:2004</a>. There's always various solutions available. </p><p>The cost of this co-operation is that while it simplifies writing the routines, the control system needs to handle the baton handoff of messages clearly and as expected. Changes to the control loop can cause changes in behavior, obviously. For a likely example, if you have a loop <em>inside </em>the coroutine, you end up with a very different idiom if your yield is at the end of the loop rather than the beginning, because you, the coroutine, might be expecting the control system to do something for you, and it changes when that is. </p><p>It can always be sorted out, but t can be confusing. At the start, before the body, it's one removed from if it's at the bottom of the body. What it means to "finish" changes by one. This subtly changes the relationship between the calling code and the coroutine. Thus the structure of the control loop should be known and fixed for any coroutines written to be executed by it.  Done correctly it will be clear when the control loops performs services, validation or logging.</p><h3 id="novem-coroutine-approach">Novem Coroutine Approach</h3><p>The idiom demonstrated here allows the caller to be a control loop with no initiation of the loop prior to the iteration. The coroutine function in my demonstration is not a wrapper but the actual coroutine:</p><pre><code class="language-javascript">function *coroutine(inputDoc)
{
    let doc = inputDoc;
    for (let i = 0; i &lt; 6; i++)
    {
        doc = yield primitive(doc);
    }
}
</code></pre><p><strong>Note</strong>: the '<strong>*</strong>' before the function name is how you declare a generator/coroutine in JavaScript.</p><p><em><strong>Simulation</strong></em><strong>:</strong><em> </em>Above I'm simulating the "sequence" of functions from a list that I mentioned as <em>the recipe</em> with a loop repeatedly calling the same function. This is a simplification that doesn't affect the demonstration b/c it's grammatically  equivalent to the loop over a list. Leaving it out saves me some standard plumbing the deployed system will need since there is no need for more than one routine. The target app where I started this will have a list in this pace, and also a wrapping object to help the control system handle the routine. Using this idiom, all the caller ever communicates to the coroutine is input documents and all it receives back is output documents.</p><p>In this pattern iteration immediately follows after construction with no handeshake, no "extra" <code>next()</code> call is used to get the coroutine "started".</p><h3 id="why-use-a-coroutine-for-this">Why use a coroutine for this?</h3><p>If you give it some thought, you will see in this simple example, already, the type of flexibility the control loop achieves in this arrangement. The primitive transformations in the leaf coroutine do not care if they are called using a for loop. They don't care if the control loop dynamically modifies context. They don't care if any other primitive will or has been called. They don't care if they finish, even though it's up to them to decide when to finish in principle. The primitives don't even care if they are being called on the same machine as other primitives. In principle, they might even be resumed on an entirely different machine, though that's rarely economical so far. In practice, a primitive lives within a single thread, for the lifetime of the recipe, sharing memory with the rest of the thread. </p><p>On the control side, the infrastructure don't care what primitives do with data. They don't care if it's business information being "processed" or scientific data being "reduced" or anything else about domain logic. All it cares about is that the data going in and out is recognizable enough to identify, handle, and store it by itself. In this demonstration, that they're javascript objects. In the target application that they are readilly JSON-serializable javascript objects. If there are services, the control loop cares about the request-for-service messages, and shares knowledge of its schema with the coroutines.</p><p>The control system sees the primitive as "just an iterator", but the primitive itself sees itself not as an iterator at all, but as a "data transformation". I love this idea because I think it's the perfect isolation between domain logic (businessness logic, scientific logic, etc.) and control infrastructure.</p><p>The control loop doesn't <em>have to</em> care what's done to the data, but it <em>can</em> care. Routines don't have to be in a list, they can be in a tree, selected by datatype of command structures. It is available as a location for hooks that can, for example, validate data on it's way through the system, trigger messages to emit on a message bus, and provide system command and control features. A lot of actions can be performed on the control side that help make the system robust against badly behaved primitives, where at the least they are quickly isolated as the source of a failure in the data pipeline.</p><h3 id="the-control-loop">The control loop</h3><p>For me, calling the coroutine from the top control loop is also cleaner and easier to understand without an initializing <code>next()</code> call. Here is the control loop:</p><pre><code class="language-javascript">    const inDoc = { type: "testdoc" };

    const cor = coroutine(inDoc);   // Instantiate coroutine
    let done = false;
    let doc = inDoc;

    while (!done)
    {
        console.log(" input doc", doc);
        const iterVal = cor.next(doc); // call next(..)

        done = iterVal.done;
        if (!done)
        {
            doc = await iterVal.value; // resolve Promise
            console.log("output doc", done, doc);
        }
        else
        {
            console.log("done");
        }
    }
</code></pre><p>The coroutine is called with the input data to process, which is its purpose semantically, so that's good. The <code>next(..)</code> function in javascript returns an object with <code>done</code> and <code>value</code> keys. The <code>done</code> member becomes true when iteration is over and the <code>value</code> property is the value yielded by the coroutine. In this case that value is a promise to deliver the output document. The control loop awaits this document before proceeding because its output is needed as input for the next step.</p><p>Note that if the control loop has a way to know what routines can be run in parallel, it could start multiple routines and await using <code>Promise.all(..)</code>.</p><p>A big part of why these two tightly interleaved systems won't interfere with each other is that the inter-operation is cooperative multitasking, they share a thread. Though the primitive is "controlled" by the control loop, the primitive also 'controls' the control loop insofar as it decides when it's willing to pause and let the control flow pass back to the control loop. The control loop has the <em>greater</em> control only because it does not have to resume the primitive, but the primitive has no choice but to release control back to the control loop, eventually, even if there is an error.</p><p>Here's the whole demonstration script:</p><pre><code class="language-javascript">"use strict";

async function primitive(doc)
{
    if (typeof (doc.increment) === "number")
    {
        doc.increment++;
    }
    else
    {
        doc.increment = 1; // undefined means 0 so 0+1
    }
    return doc;
}


function *coroutine(inputDoc)
{
    let doc = inputDoc;

    for (let i = 0; i &lt; 6; i++)
    {
        doc = yield primitive(doc);
    }
}

(async() =&gt;
{
    const inDoc = { type: "testdoc" };

    const cor = coroutine(inDoc);
    let done = false;
    let doc = inDoc;

    while (!done)
    {
        console.log(" input doc", doc);
        const iterVal = cor.next(doc);
        done = iterVal.done;
        if (!done)
        {
            doc = await iterVal.value;
            console.log("output doc", done, doc);
        }
        else
        {
            console.log("done");
        }
    }
})();
</code></pre><p>Yes, that's where I like the braces. In fact, eslint polices that.<br><br><code>"brace-style": ["warn", "allman", {"allowSingleLine": true}]</code>.<br><br>I find that it's easier to match braces visually that way. </p><p><em>Source code likes being anthropomorphized.</em></p><p>Craig Allen © 2019, 2020</p><p>PS: If you think about it, the "extra" next is in fact required but the coroutine implementation itself already handles that initial yield, stopping right at the opening brace, the real start. No value is yielded, just like the examples above. I'm just leveraging this implicit yield.</p>]]></content:encoded></item><item><title><![CDATA[MCWCAM Blog Being Reconstructed]]></title><description><![CDATA[Time to build a new online HQ!]]></description><link>http://blog.novem.technology/mcwcam-novem-inc-blog-being-reconstructed/</link><guid isPermaLink="false">5e37b7fea4b8690001e3e32b</guid><category><![CDATA[Getting Started]]></category><dc:creator><![CDATA[Craig B Allen Jr]]></dc:creator><pubDate>Mon, 03 Feb 2020 06:11:22 GMT</pubDate><media:content url="http://blog.novem.technology/content/images/2020/02/abandoned.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://blog.novem.technology/content/images/2020/02/abandoned.jpg" alt="MCWCAM Blog Being Reconstructed"><p>With a new version of ghost and a new way of running it, this blog is being reconstructed. The only old content being migrated is the blog on coroutines, for which the format didn't survive, so I'm going to edit and improve it in general.  To go along with a rewrite of novem.technology site to React, and to go along with plans for the future currently in the works.</p><p>I hope you enjoy the new blog as much as we plan to ourselves.</p><!--kg-card-begin: markdown--><img src="https://blog.novem.technology/content/images/2020/02/files.jpg" alt="MCWCAM Blog Being Reconstructed" style="float:left; width:35%; margin:1em;">
<p>Pardon the dust as we go through our files. You can see an edited version of the coroutine blogs as we experiment with the new blog in plain view, <em>and</em> edit the content so it better serves it's intended purpose.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Refactoring as Programming Philosophy]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>The subtitle on the cover of Martin Fowler's book <em>Refactoring</em>, Second Edition 2019, originally published in 1999, implies that Refactoring is about &quot;<em>improving the design of existing code</em>&quot;. Further inside, in the preface, he says refactoring is &quot;<em>the process of changing a software system in a way</em></p>]]></description><link>http://blog.novem.technology/refactoring-as-design-2/</link><guid isPermaLink="false">5e6d4169e89fcb0001d1c963</guid><dc:creator><![CDATA[Craig B Allen Jr]]></dc:creator><pubDate>Wed, 29 Jan 2020 06:37:28 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>The subtitle on the cover of Martin Fowler's book <em>Refactoring</em>, Second Edition 2019, originally published in 1999, implies that Refactoring is about &quot;<em>improving the design of existing code</em>&quot;. Further inside, in the preface, he says refactoring is &quot;<em>the process of changing a software system in a way that does not alter the external behavior of the code yet improves it's internal structure</em>&quot;. A couple paragraphs further on he provides the motivation, &quot;<em>with refactoring we can take a bad, even chaotic, design and rework it into well structured code</em>&quot;. He argues that as we build a system, we simultaneously learn how to improve its design. We can alter the code to the shape of the improved design using a catalog of reusable refactoring patterns. Each refactoring pattern is a code change pattern which is &quot;<em>almost simplistic</em>&quot;. The point being that these are <em>safe</em> steps. For example, we move the body of a case statement into a function, and call the function in the case statement. Or we move code that is part of a method into its own method, or we move code snippets up or down the stack, addjusting isolation of responsibility.</p>
<p>From my perspective there is an extra issue however. My definition of &quot;refactoring&quot; is <em>any alteration of existing code</em>. If a subsystem of any type (be it a complete server or just a library) is working correctly, and it doesn't require alterations, then refactoring is not an issue, it does not require alteration.  Making things pretty or even less chaotic for no reason is not the goal of refactoring. But if code has to change, you are refactoring as well as adding code.</p>
<p>Fowler mentions &quot;not altering external behavior&quot;... then why would we alter the internal mechanism? The answer is so that we can subsequently alter behavior. The better design means more flexibility, prepared for future changes which are blocked by the current design. A better design means better prepared for refactoring, better prepared to cooperate with future alterations required not by the code base, but by the users of the code base. So it's best to remember that it is about altering external behavior, ultimately, especially when arguing for application of the principle.</p>
<p>It's quite possible the reason it's hard to argue with the business side of software development for the time to refactor is because we have not made clear the external behavior benefits a software system will display when continually refactored in key areas. Software made with refactored growth gets more powerful as it ages, insteal of becoming lumbersome and decaying.</p>
<p>Change is continuous in software. Any exceptions are not of concern, all the systems we work on are undergoing change. Software developers are by defintion dealing with the systems that <em>are</em> being changed. A reason to &quot;refactor&quot; is that if you do not <em>consciously</em> refactor, the code will naturally deteriorate, from the law of entropy as applied to information, and <em>bit rot</em> will result. Change is unavoidable, but navigating change with refactoring plans allows us to direct that change so it's not just wandering. If you are touching code, you are changing it, and you are affecting systems that rely on it, and you should keep the project refactoring plan in mind. Thus you should always chose to<br>
incrementally improve that code at an opportune moment, which is always the moment you find yourself changing it.</p>
<p>The lean startup concepts of first, building an mvp, and then, working sprints with scrum, doing kanban, or some other agile methodology, is essentially equivalent to thinking of software development as constant refactoring. The waterfall method was based on the attempt to consider all factors up front, prior to implementation, which is impossible. Thus initial design creates the initial factors, which are subsequently refactored.</p>
<p>Even so called &quot;greenfield&quot; work includes refactoring, first there will be some proof of concept code, and a pre-mvp core, and subseqently those will be refactored to meed the needs of the mvp. Fowler's definition including not changing external behavior still applies, it's just important to realize that pure refactoring is followed by making use of the new abilities of the system, and so practically both things will often be thought of as the same issue. In this case, it's better to think of the change as a refactoring that adds behavior, than and issue that requires changes to support.  Refactoring means the design is better, but &quot;chage to support&quot; something new is where hacks come from.  Refactoring requires thinking about not only the current change, but the next changes after that.</p>
<ul>
<li>refactoring as a development philosophy
<ul>
<li>Good design should make it safe to refactor.</li>
<li>The purpose of testing is to make it safer to refactor.</li>
<li>Don't refactor accidentally, do it intentionally.</li>
<li>Over time, even short periods, there are compound time savings.</li>
<li>Over time, even medium periods, there are exponential configurability<br>
and system ability.</li>
</ul>
</li>
</ul>
<h3 id="healthycode">Healthy Code</h3>
<p>Personally, I don't like the term &quot;code smell&quot;, it seems mean hearted to code that must be of value somehow or else it would be thrown out. Also, &quot;smell&quot; implies that you and sense something bad but don't know exactly where it's coming from, or that it's rotten. Really, if you see a bad idiom at play, or a dangerous one, or a misused one, like a case statement a thousand lines long, it's a bad idiom. It's analagous to network or power cables that are tangled and countless. It's not a smell, it's a mess. Instead, I like to say that <em>my favorite type of software is software that works</em>, and <em>this is a problem and an opportunity</em>.</p>
<p>When you have a bunch of professionals complaining about how terrible and chaotic a system is, it can only be because some business is using it for some vital business process, so it's indespensible. It has some mission critical purpose that <em>in itself</em> proves there is something worthwhile in there. Software engineers should respect that as an emperical fact. That aslo means that <em>with refactoring</em> it can be conserved and eventually embeded, its flaws removed, and coexist as a good citizen within a well designed software system.</p>
<h3 id="targetdesigns">Target Designs</h3>
<ul>
<li>refactoring is not a design
<ul>
<li>you need a <strong>target design</strong></li>
<li>you use &quot;backward compatibility&quot; techniques to create your new design<br>
such that at any point in time it coexists with existing code</li>
<li>coexistence ensures legacy <em>features</em> are not refactored away as<br>
happens with a &quot;rewrite&quot;</li>
<li>often, refactoring patterns are reversible b/c sometimes it's the<br>
specific target design that defines which direction is &quot;better&quot;</li>
</ul>
</li>
</ul>
<p>To make progress via refactoring you have to have an idea of where you want to go. Examples of refactoring in Fowler's book often show both directions of a refactoring step, his <em>simplistic steps</em> are often bi-directional code transformation primatives.</p>
<p>Below are less than simplistic steps from my own experience.</p>
<h3 id="refactoringnobrainers">Refactoring No Brainers</h3>
<p>To talk about refactoring that is specific to the target design of your code base would require a whole reference project, like provided in Fowler's book. For the purposes of this blog I will merely mention some from my own experience that are patterns which immediately call for refactoring. I would like to note that I respect disagreement on any of these just as I disagree with multiple of Fowler's. They are mostly not machine executable transformations however, because they require the goals and motivation of the engineer. To collect some code in a function together, and move it to another function is simple enough to be carefully done by a human, but a machine lacks the semantic power to choose which code needs to be collected, what to call the new function, or where to put it.</p>
<h4 id="youhavecutanpastecodethroughoutyourcode">You have cut an paste code throughout your code</h4>
<p>You need to make the copied code into a shared function.</p>
<ol>
<li>Review the cut and paste code fragment where-ever you know it's used. You can use variable names to grep for examples. Compare the fragments in detail across a variety of examples to get an idea of how conformant they are to each other, to the most general idea in the code. Often pasted code will have been modified or intersperced with other code for reasons that might be subtle. Some versions will have attempted to be general, but proved not general enough and someone made a special version for themselves. This version may be more general, or more specific with the scars of attempted generality.  It's always better to make the copied code <em>more general</em>, then used for the new special purpose, because then it might be backported to the previous page.</li>
<li>To make your general case function, choose the most general case you find and write the function by modifying it. If it's an extreme mess, and none are general enough, create your own generalization and write it from scratch with the (generalized) characteristics of the complete set of similar code.</li>
<li>With your starter code, in a new function, compare to other copies, generalizing to accomodate the second version.</li>
<li>Add arguments as needed to pass variable that had been available in scope of the other function. It's tempting to combine arguments when you find the copy has a similar variable. Don't, fix that later.  If the starter function had <code>goodDate</code> and the other has <code>niceDate</code> and they seem the same, wait, they are likely not handled exactly the same, and you don't know the dependencies on that difference. Here is where we are thinking, &quot;don't change behavior&quot;. Combining the two variables in the same function, each with their own handling will not affect behavior. Normalizing the use might.</li>
<li>Repeat with other fragments, and when they are different, support the difference with an additional argument.</li>
<li>As you go replace each incorporated copy with the new generalized function. Confirm the software works and is passing tests, but also do targeted manual tests with small scripts to exercise the generalized function and ensure it's answers are the same as the original copy.</li>
<li>Look at the generalized argument list. It might be a mess, with overlapping arguments (e.g. &quot;state&quot; and &quot;stateCapitalized&quot; and &quot;stateCode&quot; and &quot;stateId&quot; and so on) and it's not clear which are interchangeable or merely overlap.</li>
<li>Find the generalizations for this data. For example, if you have a canonical &quot;stateId&quot;, then the generalized function can take that, and look up the rest. If <code>niceDate</code> and <code>goodDate</code> are mostly similar, they can be replaced with <code>displayDate</code> serving the purpose of both.</li>
<li>If you want callers of the original copies to not have to change, and use their unique argument lists or names, you can create thin thunk functions that continue to accept those arguments and call the new generalized function. In fact, this is something you can just set up an the begining if you want to make it easy to swap functions around while you work, ensuring it's easy to move backward if the generalization fails.</li>
</ol>
<p>Using named arguments for functions is very useful in this regard since ordering doesn't matter, allowing parts of the code to ignore changes to the arguments.  This means when generalizing by adding new arguments that are needed for generalization won't interfere with the function signature or other code within the function.</p>
<h4 id="youhavea1000linefunction">You have a 1000 line function</h4>
<ol>
<li>Collect the lines of code within the function.  All the lines that refer to the same variable should be bunched together. If the language supports it, hopefully, put the variable declaration at the top of these lines.</li>
<li>Move that code to a function, decide what it's responsibility is and name it appropriately.</li>
<li>Organize the new functions into subsystems of isolated responsibility.</li>
<li>As the function is collected this way, you will start to have functions that call the first round of code, and these go into a library of a higher layer relative to the first round of functions.</li>
<li>The perfect stopping point is when the function reads like an engineer explaining what the functions job is to another engineer.</li>
</ol>
<h4 id="youhavea1000linenestedswitchstatement">You have a 1000 line nested switch statement</h4>
<ol>
<li>Create an abstraction for a command</li>
<li>Create an abstraction for a command executor</li>
<li>Create and abstraction for a command context</li>
<li>The end result is all cases encapuslated in command objects that accept command     contexts</li>
<li>The end result is the switch repaces by a command executor call</li>
</ol>
<p>The situation a giant case statement is taking advantage of is generall the global context. That should be placed in the context. The function will now get their inputs from the context. The commands will have names/ids that are stored in a command executor configuration. The switch statement is replaced by a command executor call, new commands can easily be added, and the commands can be executed by alternate executors, which is often useful.</p>
<h4 id="gooddesignpatternsandrefactoring">Good design patterns and Refactoring</h4>
<ul>
<li>in general good design is that which is easy to refactor
<ul>
<li>OOD encapsulates so that solutions can be replaced</li>
<li>OOD encapsulates so that multiple solutions can be retained and swapped in/out</li>
<li>refactoring is enabled by code comprehensibility</li>
<li>breaking things into units of responsibility makes things easy to refactor</li>
<li>testing makes it easy to refactor, if unintended consequences are detected (regression testing)</li>
</ul>
</li>
<li>modern methodology, Agile, Lean, Kanban, Scrum... are partly about refactoring or assume it
<ul>
<li>making an MVP is getting a starting point to subsequently refactor</li>
<li>Sprints are interpretting all work as time boxed refactoring</li>
<li>Kanban is delta-ticket tracking refactor patches</li>
<li>All agile sees development as iterative in nature, where you have a &quot;continuous&quot; development methodology, trying to be as granular.</li>
</ul>
</li>
<li>If you start with something running and end with something running, you refactored.</li>
</ul>
<!--kg-card-end: markdown--><p>To really explain refactoring though I want to harken back to before it was a word, when we had alternate words for refactoring. For one, we didn't admit to refactoring or have a word for it. We 'worked' on code and sometimes if it became unworkable, we "rewrote" it, or "started over".</p><p>My introduction to the term, but not the concept, of "refactoring" was from the book <em>Refactoring: Improving the Design of Existing Code, </em>by Martin Fowler in 1999. I might have heard the term earlier, I think I had, but the book cemented it all together. I had loved object oriented design, not as a purist but because it allowed me to change code in and out. It was inherently like a plug in system, not a run-time one, but one for developers, to have classes and object instances working together to achieved desired behavior. The part of object oriented design I liked happened to make refactoring easier.</p><p>What I and others were calling iterative development, that now we call agile, or closely related, is all about assuming you are refactoring. You achieve a MVP, and after that, you run sprints refactoring. Even new features are interpreted as a refactoring b/c the system needs refactoring to accomodate the new feature, if it really is <em>new</em>. </p><p>Refactoring steps are doable chunks of change, it works at the start, if considered non-optimal or even buggy. It also works when your done, even if considered far from finished. Code that is easy to change is easy to test. Code that's easy to change is easy to understand. Granted, these are tautologies in that... if you don't make it easy to understand, it'll be hard to change, if you don't make it easy to test, you'll make it hard to change. The point is these things go together. Learning how to make code easy to change leads to how we make code easy to understand and easy to change, and the points all reinforce each other.</p><p>What's interesting about Martin Fowlers book is that it has many examples of code problems you often see, and how to refactor them. I find that in the decades since reading this book my entire  programming approach has been formed into refactoring techniques. In that time, even green field work has to work with old systems or have some sort of backward compatibility. Refactoring is key.</p><p>I am always refactoring. Even green-field is refactoring. I start with scripts to prove concepts, I refactor that into a script calling reusable useful libraries, then that into classes using those libraries and then into a command line tool that performs services, first, especially, that are useful in development, and then into servers and client software.</p><p>What's neat about refactoring is getting used to turning <em>the kind of thing you run into </em>that might haunt and afflict you, into what you want it to be. You can't do it right away, but just the knowledge reveals how to isolate your new code from the horrors of the code debt surrounding it. It's not a magic wand but it is possible to refactor code as you work so that your job working with it slowly gets better.</p><p></p><p></p>]]></content:encoded></item></channel></rss>