Scala Futures and Stack Traces

I’ve been digging into a real Scala codebase for a while now and I’ve been enjoying a lot of it. The trait system in practice works way better than it looks like it would, mostly since all the pre-research I’d done involved people talking about the difficult bits because the normal use cases work out easily (and are therefore uninteresting). The integration with tools and libraries worked out great in most ways; however, the error message you get when a Java class and a Scala class have conflicting names wasn’t ideal even if it worked. The import rename syntax (ex. import scala.collection.mutable.{Map => MMap}) fixed the problem easily enough.

The big gripe I’ve had so far is with debugging future-based programs. The big issue is that when an exception gets thrown in a future, the stack trace doesn’t give any idea of what scheduled the future. The problem has been recognized as a Scala bug, but it doesn’t seem to be getting dealt with since it was opened in 2014 and hasn’t been updated since 2015. This is also partly a tooling issue since the step in functionality doesn’t work the way you’d want it to. Stepping into a method that returns a future doesn’t actually step in. It just schedules that action to occur, it doesn’t actually happen yet and will happen on another thread when it does.

A possible solution would be if the step-in action in the debugger put a breakpoint inside the method being scheduled with some sort of conditional. Not sure what the downside would be to this particular solution. I don’t see a reasonable way to add this as a plugin or a script in some other way. Forking IntelliJ itself doesn’t seem like a good idea either since that’s the community edition, and that doesn’t support all of the plugins we are using plus all of the ongoing support issues with that.

The one gripe against the stack doesn’t out weigh all of the positive aspects. The concise syntax is great. While I haven’t had any opportunity to really dig into the performance aspects of working with futures yet, I expect they will hold up as expected. The type system is expressive and safe. Higher order functions aren’t as much of a differentiating factor over Java with lambdas in Java 8 but they aren’t integrated into the libraries the way they were in C# or are in Scala. Overall, I’m excited with my choice and will keep digging in.

Flow and Learning

Since I recently changed jobs, I’ve been learning a ton of new things. Moving from Windows/C#/Visual Studio/ASP.Net/SQL Server to OS X/Scala/IntelliJ/Play/MongoDB is a lot of change, normally you’d have some sort of strong point to leverage off of, but for me it is all new. I’ve always had an introspective personality, and the introspective part of me is looking at this and thinking that I got in over my head. The logical portion of my brain says the learning curve is expected and I’m working my way up it, but it is difficult to reconcile the two perspectives.


I had found the above diagram describing how challenge and skill interact and can cause boredom or frustration. The context of this diagram was how games try to stay in the flow channel, and the player response on either side of the channel. The more immediately relevant version was the one where it described the experience of starting a new job.


This diagram matches with my experience here, especially since I took a bigger hit to my applied skill level due to the radical change in the technical stack. This puts me further into the frustration section than other similar job change experiences, and causes the sort of anxiety that I had been grappling with.

I know I’m making sure to keep an eye on my stress levels and everyone at work understands the challenges that are being encountered since they went through most of the same ones at some point. I changed some of my habits around what I’ve been reading, less dense material more fiction. I changed some other habits, since I cut my commute down significantly I’ve been trying to make sure to use that time wisely and get some additional exercise to deal with the stress in a positive fashion.

By putting together the rationalization of what is happening I hope to assuage my own insecurities. The mental load of the insecurities can take attention away from learning and doing your best, making the insecurities a self-fulfilling prophecy. I hope this account of the feelings I’ve been encountering helps others to recognize that they aren’t anything abnormal to feel, but that you can’t let the negative feelings control your mind.

Reactive Manifesto

I ran across the Reactive Manifesto while I was doing some reading on Scala. I touched on this idea back in the Virtual Conference post with the presentation What does it mean to be Reactive? by Erik Meijer. His 45 minute presentation tried to explain the nuances of this concept. The manifesto is all about taking the basic concept of what reactive programming is and making the big ideas accessible.

The four aspects of reactive applications – responsive, resilient, elastic, and message-driven – all come together to reinforce one another. Responsive is straightforward: the application should return results quickly. Resilient is that the system is designed to resist faults and remain responsive. Elastic means the system can react to the changing input rate and add or remove resources to keep up with demand. Message-driven is that the system operates in an asynchronous manner. These four aspects work together to build a cohesive style of application.

The message-driven nature of a reactive application allows the system to utilize the concept of back pressure. Back pressure allows the system to control the flow of requests to ensure that the system remains responsive while the elastic aspect kicks in and applies additional resources. The message-driven nature also means that the resiliency has additional options since the services are decoupled further.

The reactive name may be new but the concepts are old. HTTP could be described as reactive. It is responsive since you can guarantee the timeout settings. The HTTP server is designed to be resilient and able to fail fast, with descriptive error codes that indicate how to react. A 404 is different from a 503 and the caller can react differently to the two of them. The system is elastic since you have ways available to scale horizontally. HTTP is clearly message-driven with the request and response paradigm.

This ties into the Scala ecosystem via Scala.react and other libraries to enable reactive programming on the platform. Scala is a good fit for reactive programming because the functional paradigm makes it easier to work in a reactive manner. Martin Odersky, the designer of Scala, also was an early proponent of reactive programming so that created a fertile breeding ground for working on reactive concepts.

Using this paradigm at a smaller scale seems like a great way to create modular systems. This pattern also compliments the microservices architecture. I’m looking forward to working with these concepts as I get more experience with Scala.

Thinking Back and Looking Forward

I’m writing this after my last day at my previous job. It has me reflecting a lot on the three years I was there. I learned some interesting things and met a lot of great people. There were aspects of the job I really loved, and there were the aspects of the job that I would love to never think about again. I was reflecting back on my accomplishments there and I was surprised how much I had done in some aspects and how little I had done in others.

One of the memories that stuck out to me was the response to some production performance problems we had in July of 2014. I was new to the organization, which made it my first chance to see how it responded to a crisis. I learned a lot about the organization then. It was great to see how disparate teams came together and worked the problem. It also gave me an opportunity to better understand the organizational structure, good and bad. While investigating, I ended up digging into something that wasn’t the cause of  the problem, but demonstrated numerous other little problems that had been festering. There, I managed to make a big impact with different higher-ups once I showed them all of the hidden problems I dug out. It was especially interesting for me to handle from a workplace navigation perspective, since all of the problems were outside of things my team was nominally responsible for.

An area where I tried to make an impact and spent a lot of effort was the build pipeline. The ‘continuous integration’ that was set up by the configuration management team had numerous problems. The basic workflow was that they would – on request or on a timer – take C# code, compile it, and commit the DLLs back to SVN. When I first saw this, I noted that using source control to store the binary artifacts that were created from the repo was odd. The configuration management team didn’t have any interest in changing this, since the entire deployment process was based around deploying DLLs from SVN; it’s understandable they were resistant since changing this piece would require changing everything. This limited a lot of my options on how to change the build pipeline without getting involved in deployment as well. I spent a long time trying to convince the configuration management team to run tests before committing back to SVN, but the server they were building on failed a number of the tests when they tried that. It turned out that the team that owned the code under test didn’t even know those tests existed. This led into an effort to find all of the tests in the whole system and get them passing again. We made progress on these goals but there ended up being a functional area nobody owned, and the rest of my team didn’t feel like we had the capacity to take ownership of it. This left the effort in a sort of stalemate: progress had been made and we could run a lot of tests, but there couldn’t be a clean build unless we started making exceptions. We held in limbo for months, where management continued to debate  who owned that functional area. This eventually led to the effort dying off. That was a massive blow to my morale, since to me it implied a lack of focus on quality; that wasn’t at all their intent, but that doesn’t reduce the frustration after I had gotten so far and made so much progress. I recognize that I may have taken it too personally or read motivation into it on management’s part that wasn’t there, which is an important lesson I’m taking away. I also learned a great deal about how to navigate the corporate environment and how to use soft power to influence change, but most of that was too late to make this change successful; now I know better how to approach this type of major change management from the start.

I don’t want to give the impression that everything was bad – a lot of aspects of the work were great and interesting. I had a great experience working with a system that is much larger than anything I had worked with before. The whole system was hundreds of times larger in terms of computational resources than anything I had worked on before. The codebase itself was approaching ten million lines of code across 10+ different programming languages. Digging into all of this was an amazing adventure to understand how it all went together. Very few people were looking at the system as a whole and I got to come in, learn and understand all of this and help those who were trying to build other pieces of it.

I also had the opportunity while there to mentor some junior engineers and it was quite rewarding. I helped them get up to speed on the code base, which is an easy enough activity. But I also spent a great deal of time working with them on code reviews and helping them understand how to build better software. Helping them to understand the difference between something that works and something that is truly good was really rewarding as they started to see the difference.

My new job is a much different situation than my last job. At the last job I was there to help them clean up the technical mess they knew they had; their issues are common to large organization that have grown through acquisition, and I do appreciate that they wanted to improve. The technical mess wasn’t the whole problem; as you can see from these two anecdotes above there were multiple groups who weren’t in sync and a lack of understanding of each other. The new place is much smaller so it’s unlikely that I’ll have to navigate as many different competing groups, or be assigned such a narrow portfolio. My new company is also much newer so there hasn’t been the time to build up the layers of technical debt. From a technical perspective, at the new job I hope to master a new language and stack and build out some RESTful web services. I’d also like to help build a high performing team and mentor some junior developers, since I found that  really rewarding The person who mentor me to see that difference between “works” and “good” happens to be working at the new place, so that will be a great relationship to renew now that I’ve had an opportunity to play that role. Sometimes the journey is the destination afterall.

More Scala

I’ve been doing a ton of reading on Scala and jotting down some observations on what I’ve learned. Some of it is simple but not immediately obvious; some of it is those places where the reading left a desire for more information. Hopefully this will save some time for others trying to pick this up. If not, at least it will be a reference for me.

Some notes from going through Scala School

  • The relationship between partial application and currying is still not totally clear to me; it seems like you curry to create a series of functions then partially apply them in sequence to achieve the full result.
  • The differences between methods and functions are unclear; the tutorial assures me that’s okay but I don’t like it. It seems that functions are strictly things that inherit from function.
  • Type aliases seem like a great way to build new types that imply a collection of existing types.
    • type SocketFactory = SocketAddress => Socket
  • I need a better understanding of objects in scala. Not the normal OO object, the Scala object seems to be closer to the singleton pattern or a static.
  • Guard matching syntax seems interesting, e.g.,
    • case i if i == 1 => “one”
    • I wonder what syntax you can use in that expression. Hopefully function calls are legal.
  • Tuple Accessors are 1 base not 0 based.
  • Destructuring bindings to decompose tuples is awesome, they let you break down tuples quickly and neatly.
    • val (char, digit) = tuple
  • I’m a big fan of GetOrElse on Option, very concise and clear.
  • Partial functions are another idea I haven’t seen before.
    • It is a function that knows it can only produce results for a subset of inputs.
    • They’re the underlying implementation in case statements which allows case statements to be used like functions!
    • Not sure what else I could do with them.
  • I think I’ve figured out F-bounded polymorphism, essentially you define that the generic type must implement the type you are defining. This is so that you can constrain the generic type to pass it into the base class.
  • Structural types look like duck typing but uses reflection so we should avoid using them.😦
  • Manifests are compiler generated code to counter type erasure. I wonder how much code bloat this causes.
  • Found the DecorateAsJava trait, nice usage of implicit conversions to make interop with java easier.
  • Spies seem like a nice feature of the testing framework. Seems like you could build inconsistent behavior in an object like a list that says it has some number of objects but doesn’t have an entry at that point.
  • The section on traits did not make the mixin functionality clear. You can mixin a trait as part of the constructor of an object not just as part of the class declaration! That’s not quite C# extension methods but close enough for some usages.
    • Found implicit classes elsewhere that can be used almost exactly like extension methods.

Notes from Scala Exercises

  • The operator, ie fat arrow =>, shows as one character in some of the examples which is confusing.
    • Similar problems with the skinny arrow ->
  • Backticks in pattern matching allow matching against other variables.
    • def patternEquals(i: Int, j: Int) = j match {
       case `i` ⇒ true
       case _ ⇒ false
  • There seems to be usages of implicits that work like extension methods, but you need more syntax.
    • class KoanIntWrapper(val original: Int) {
       def isOdd = original % 2 != 0

      implicit def thisMethodNameIsIrrelevant(value: Int) = new KoanIntWrapper(value)
  • The section on for expressions did not really help my understanding.
    • val xValues = 1 to 4
      val yValues = 1 to 2
      val coordinates = for {
       x ← xValues
       y ← yValues
      } yield (x, y)
    • In this example it isn’t clear why the two lists are evaluated in any particular order.
  • Scala Fiddle was a great help for running some of the examples and being able to try some variations.
  • I’m not sure how I feel about the conversion between methods and operators where certain kinds of methods can be used as prefix/infix/unary operators. Having seen a C++ codebase with off operator implementations I realize the pain it can cause; maybe since you can name them however you want they’ll read better.

I ended up going through the Play Framework Tutorial as well since it’s part of the stack I’ll be using.

  • Looks a lot like ASP.Net MVC.
  • Session data signed to prevent tampering.
  • @With annotation and allowing composition of actions.
  • Twirl temples look a lot like razor templates except that you add dynamic elements in Scala not C#.
  • Play seems like it just composites together best practices from various other JVM libraries bringing together JPA, Twirl, Jackson, Akka, Guice, and logback.
  • The WithApplication class seems like a way to make building testable controllers easier.
  • Similarly with WithServer class will help test some fully remote calls.

Overall I’m feeling pretty psyched. At this point I feel pretty comfortable reading the sample code. The exercises were more about reading it and understanding it rather than writing your own code.

Since the language is so big I’m not sure which parts are where I should be focusing. I feel like I need to start building something with it at this point to understand how to decompose a class into traits. I’m not sure the Project Euler problems will supply the appropriate domain to try and build these more complex inheritance hierarchies. I’m also not certain if I’ll be building good Scala code or just mashing together different styles in a way that wouldn’t scale. Maybe Scalastyle can help with that, but the rules don’t seem to be the kind of thing I’m looking for.

I’m going to forge ahead with this list of Scala problems since I hope that being able to contrast my solutions with the provided ones will give me some level of feedback on what I’m doing. Then probably move into the Project Euler problems afterwards.

Starting Scala

I’m starting a new job soon which is going to be entirely Scala programming. I’m trying to dig in a little bit and get started with a leg up. I’m going to outline my basic plan here and post updates as time goes on. I’ve done a tiny bit of Scala before when learning some about Spark. I’ve done some Java work in the past as well so the ecosystem is a little bit familiar. So I’m not coming in from nothing.

The place I’m going to be working uses Macs so getting off of Windows seems like the right way to get started. I had previously used Eclipse when working on JVM based languages. The last time I had used Eclipse though it seemed like more had changed than was the same as I remembered. So I’m going to take a different tack this time and try IntelliJ. So the overall development environment is going to be an Ubuntu VM and use IntlliJ on it.

I plan to start with Scala School to make sure I’ve got all the basics down. Once I feel I’ve got that put together I’ll try Scala Exercises for some more guided exercises. Then I’m going to do some of the Project Euler problems I had done in F# since I understand the problems and can focus on learning the idiomatic Scala way of doing things.

I figure this should get me up to speed on Scala pretty quickly. We’ll see how well it goes.

ChatOps and ChatZero

Inbox Zero was always a concept I never fully understood the need for before I moved to a big company. You get some email every day and you read it, what’s the problem? Now that I’ve been in a big organization for a while, I think I understand the problem better: you eventually end up on email lists that are about things that are only tangential to what you do. I’m on one particular email list about communications from partners we integrate with; I’m not involved in those integrations at all, but can’t unsubscribe from the list. Inbox Zero both helps you stay focused on doing real work and makes sure you don’t miss anything important.

Chat and ChatOps has been replacing email usage across the industry, since it is an easier way to collaborate in real time and the chat histories make it easier to share information asynchronously. As ChatOps has picked up in my office I will get to the office and see there are hundreds of new messages spread across the roughly 20 channels I’m in. I used to read all of them every morning, but some of the channels had been getting chatty, which made it harder to keep up. I first dealt with this by muting or leaving channels that I was less interested in, though apparently leaving channels in Slack is considered bad etiquette in some circles. This hasn’t helped, since I keep getting involved in more and more channels, no matter how many I drop.

I had started skimming some of the channels I am in rather than really reading all of it. This helped keep up with the increased flow, but deciding which channels to skim was hard. I recently listened to Arrested DevOps talk about ChatOps, which was an interesting because they came from multiple different backgrounds and chat usage styles. They made a couple of suggestions, one of which was counterintuitive but has been working great for me since I’ve implemented it – make more channels, especially short-term channels for intense conversation. More channels helps keep the content of each channel more focused so instead of having four semi-related conversations in one channel, you have four channels each with one conversation. With each of those breakout conversations being linked as it moves out you can either go read it or skip it freely. One of the other great but more obvious suggestions was the use of dedicated update channels for notifications from automated systems.

The switch to chat from an email based system has been a great experience overall in my opinion, but it will take a while for all of the productive patterns of how to use chat to get established. The great part is that the Chat system is open and pluggable and not centrally controlled. This ability to innovate on how the platform works brings about hubot and all of the other bots and integrations that make ChatOps an amazing tool.

Agile Signalling

It seems like agile has become a signal in software development, particularly Scrum. Everyone feels the need to say that they’re up on how “things are done,” and being allegedly “agile” seems to be how they’ve decided to show it. From an executive perspective, to remain competitive in the hiring market, you must be “agile.” And indeed, the teams may be working in sprints and doing all of the prescribed activities, but they aren’t actual building software any differently than they were before they called themselves an “agile” organization.

I don’t mean here that an organization has truly implemented waterscrumfall where you have an agile cycle in the middle of a waterfall process, which I’ve never seen in person. Instead, you’ve taken how you worked before and rephrased everything in agile terminology without embracing agile theory. You don’t have releasable software at the end of an iteration; you still have a two-year roadmap where dates are promises inside and outside of the organization. You are still producing reams of documentation about software that may never exist. For every principle on the agile manifesto there are a myriad of ways that principle can be half-assed.

Scrum has a bad reputation in relation to half-assed implementations. I think part of it is the ubiquity of scrum offerings and commercially-available training where the sales pitch overpromises the results. Scrum is more accessible since, at first glance, it can just be interpreted as doing the same things you are doing now, just in smaller pieces. If the scrum implementation isn’t achieving it shows up in the retrospective. The team identifies their impediments but if they can’t deal with them it becomes an exercise in futility. If the organization doesn’t want to help resolve the impediments then the team’s morale can easily collapse.

Among the twelve principles of agile, I think there is one in particular that, if you follow it, best represents doing the right things (and can’t be half-assed cheaply). I think that the principle “Business people and developers must work together daily throughout the project” is the definitive signal of being truly agile in spirit. The daily interaction is a specific measurable objective that can be monitored.

From the developer’s point of view, this gets you answers to questions when you need to clarify intent. This helps the developers to understand why the product should be doing something and produce additional insights into what the product could do. This insight can be invaluable to the business people since it produces ideas of how the software can better meet objectives  through solutions that are not apparent to those looking at the problem from the outside. Even this benefit can be dwarfed from the morale benefit of everyone trusting everyone else to do their best.

Without the organization being wholly aligned in embracing agile theory, the business stakeholders would never have the incentive to put in the time investment to provide this level of involvement. The business stakeholders wouldn’t be inclined to put that sort of investment into the process practice if they don’t see the value. If they see the value of this one principle, they will hopefully understand the rest of the intertwined processes of the agile manifesto.

The signal that the strong businessperson-developer interaction sends is that the whole of agile practices are valued. Compare that to the signal of someone stating “we’re agile,” which just indicates that the speaker thinks you want to hear them say that. Usually those that say those things are doing some agile things, but the difference between a half-assed agile implementation and a  true one is the difference between night and day when you are working in it. By looking for the strong signal that the business stakeholder involvement represents, hopefully you can find those that are truly agile and weed out those who are just posing. It is true here that actions signal louder than words.

Backfires of Agile Coaching

I was recently listening to episode 39 of Agile for Humans, which is all about how to become an agile coach, featuring several guests who are professional agile coaches. During the episode, one of the guests indicated that while consulting as an agile coach with various teams, he noticed that some team members picked up on the agile ideas very quickly while some did not. Likewise, he saw that in some engagements he succeeded at transforming the organization to agile, and in other engagements he didn’t produce a lasting organizational change. After the attempt, in those organizations that didn’t succeed at the transformation, all of the programmers who took strongly to the agile lessons quit. The other coaches on the episode all had similar experiences of their own, where once a transformation backslides, people would leave.

I had never put this idea into words, but it makes sense intuitively. Once you understand agile ideas, working using other methodologies is less satisfying. I know I have left a job due to a backslide in the project management practices at the organization. The backslide was the difference between how the team was operating and how the organization was operating. The team was operating in an agile way but the management of the team moved to a new executive who wasn’t with the transition and it created undue friction in the organization.

An agile team does their work in small iterations and produces workable changes. An agile organization must therefore be capable of accepting changes from the team at the same rate. An agile organization can make decisions about what it wants in order to keep up with the team. It understands that building comprehensive documentation doesn’t benefit you if there is no working software. An agile organization does status reporting to match the structure and cadence of the team, whether that is sprint-based or continuous flow.

Considering the specific example raised by the podcast, on one hand, the coach succeeded at influencing someone in a way that moved them to action and that is a great success. On the other hand, the organization that brought in the coach lost valuable talent because they were exposed to ideas that the organization wasn’t ready to implement fully. If a coach does right by the individual they may do wrong by the organization in the process.

In my experience, an agile transition starts at the team level with the team learning the agile processes without much focus on the theory . Sometimes the theory is explained, but since the team doesn’t actually need to understand the “why” for the transformation to continue, it’s not a point of emphasis. Therefore, the change to the team processes happens pretty quickly, but the individuals may or may not understand the rationale behind the situation fully even though the processes often resonates on their own with some team members. Meanwhile, the greater organization has its own transition where each part of the organization adapts related processes to the respond to the faster movement driven by the agile processes.

But, the theory matters much more to the organization, since the same processes that resonate with individual agile team members are a much more significant procedural change at higher levels, wherein it often feels like control is being lost. If the broader organization doesn’t really respond to the agile ideals, it creates an impedance mismatch between the happy agile teams and the rest of the organization. Most people aren’t ready to handle being of a different mindset than the organization, or inclined to personally be change agents to pull the organization forward. They prefer that the organization match their level of understanding of how things “should” work; if they have not responded to the agile ideal then they will resist it. This friction is what happens when you have an agile transition at the level of how the work is done but budgeting and planning still happen at a radically different cadence. The desire to resolve this friction leads into ideas like Beyond Budgeting and open allocation which try to push the agile ideals out into the rest of the organization.

I’ve been places where individual teams had a strong agile tradition but the higher levels of the organization and other departments did not embrace the concepts. Being on those teams was harder than being at an organization where everyone was working from a similar mindset – even when those organizations weren’t using agile. Just being on the same page is a huge benefit to morale because you don’t feel like you’re swimming against the current. At my current workplace, all of the development teams across the organization are working in an agile fashion but the executive level hasn’t fully changed their reporting processes to be aligned with the team’s agile structures. The friction this causes is mostly absorbed by mid-level management and kept away from the developers, but if we were more strongly aligned at all levels of the organization, there would be further efficiencies gained.

Ultimately, a half-hearted agile transition is just like any situations where you are uncomfortable with how things are being done – you want to resolve that discomfort, and the simplest way to do that is often to leave. If a particular person transitions to the new way of thinking you’ve started a clock on when they will be unable to put up with the difference and will, if it doesn’t seem like real change is being made, leave. At my current organization the agile coaches we have are working with the teams but we don’t have any coaches for the executive level, to meet its different needs. In my opinion, the transition as a whole would be well served if there were coaches at that level as well to ensure things continue to evolve toward a more agile situation. I’m sure that’s true for other organizations as well.

Book Chat: The Phoenix Project

The Phoenix Project is a novelization of an agile transformation at an autoparts company. It is written to show how the transformation helps the whole company and not just the IT department. There is also a resource guide to provide additional details for those inspired to implement agile after having read the book. The novel itself is about Bill, an IT manager who gets promoted up the chain during a series of crises.

Over the course of the novel, Bill learns – through a series of interactions with a guru who had previously helped the company resolve issues with their production lines – how to deal with a failing software development project, a complex system outage, and mundane day-to-day IT tasks like replacing a dead laptop, and he thereby gains control over his work life. Being a novel rather than a normal technical or business book allows it to introduce concepts and show how they are applied. This is beneficial too in breaking a major concept into digestible pieces, since if you look at the entire set of agile practices being suggested, some of them are designed to solve problems that the reader hasn’t necessarily seen yet. The book goes through the learning and rollout processes in a company that was very close to having a complete IT meltdown.

Showing the concepts in action seems to be a powerful way to assist in visualizing for those who have been exposed to the concepts but not necessarily put together what they mean in practice. I found the depiction of the work in progress lesson particularly intriguing since it is always somewhat difficult to understand in the abstract. The work in progress situation was shown through Bill finding that there was one person who was involved in almost everything going on even though most of those things don’t seem related to what the team was doing. Most of the examples are made in a physical production analogy rather than directly discussing the ideas in the software context. It seems to me that the structure was to keep the book from being a single monologue from the guru who is mentoring Bill, but I also think it makes the story more interesting by letting Bill discover the steps on his own. The author shows a bit of self-aware humor, as Bill gripes about the guru’s oblique descriptions in the text.

The target audience seems to be upper management, which makes the story more about leading the change and telling people to do it rather than how the change works for the actual developers. This makes sense to a certain degree, since a bottom-up agile transition is more difficult to do. The management perspective is especially enlightening in the section discussing change control; the company is looking at all of the scheduled changes that aren’t getting done. Bill then asks the insightful question: if we are failing to make hundreds of supposedly important changes a day, why isn’t it causing a problem? It helped them recognize there was a lot of work being considered that, while useful, was not resolving their major issues.

If you are already up on agile stuff from an individual contributor role I would probably pass on the book in favor of something else more immediately relevant. As an agile coach, scrum master, or executive it seems like a useful perspective to add to your portfolio. As a standalone novel it is somewhat dry, since other than Bill and the CEO the characters lack depth and there isn’t much dramatic tension.