<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Neward &amp; Asocciates, LLC Blog Feed</title>
    <link>http://blogs.newardassociates.com</link>
    <atom:link href="http://blogs.newardassociates.com/feed.xml" rel="self" type="application/rss+xml" />
    <description>A collection of blog entries (and other interesting content) from Ted Neward's professional entity.</description>
    <language>en-us</language>
    <pubDate>Fri, 8 May 2026 20:11:26 +0000</pubDate>
    <lastBuildDate>Fri, 8 May 2026 20:11:26 +0000</lastBuildDate>

    <item>
      <title>Things I Think I Think... about Junior Developers</title>
      <link>http://blogs.newardassociates.com/blog/2026/titit-jrdevs.html</link>
      <pubDate>Wed, 6 May 2026 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2026/titit-jrdevs.html</guid>
      	<description>
	&lt;p&gt;Of late, it&apos;s become fashionable among AI CTOs to proclaim the death of the junior developer. (Some are suggesting that college graduates should take up plumbing or farming.) I find this entire line of thought to be ridiculous, silly, and almost entirely bereft of actual logical thinking.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;To put this emerging myth to bed, I can follow one of several different argument paths:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Argumenter analysis&lt;/li&gt;
&lt;li&gt;Historical analysis&lt;/li&gt;
&lt;li&gt;Logical analysis&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&apos;s take these in order, shall we?&lt;/p&gt;
&lt;h2&gt;Analyzing the argumenter (speaker)&lt;/h2&gt;
&lt;p&gt;In many circles, it&apos;s common to want to examine the argument absent the person presenting it. &amp;quot;This laptop is the best laptop ever manufactured&amp;quot; can take on very different meanings when uttered by the manufacturer of said laptop as opposed to a neutral third party who has expertise in evaluating said genre of hardware. &amp;quot;Let the argument stand alone&amp;quot; is the rallying cry of these &amp;quot;argument in a vacuum&amp;quot; proponents.&lt;/p&gt;
&lt;p&gt;Unfortunately, lots of arguments are not entirely objective in nature. &amp;quot;This is the best&amp;quot; is an opinionated statement that might, at best, be supported by evidence, but only if you (a) agree with the weight by which the evidence is evaluated, and (b) accept as legitimate the manner in whichthe evidence was gathered. Only if we all agree on (a) and (b) can we even begin to consider agreeing on the conclusion drawn.&lt;/p&gt;
&lt;p&gt;On top of that, the entire premise rests on the idea that the invidual speaking the opinion/conclusion is doing so in entirely good faith. And that, dear reader, is where many of our &amp;quot;junior developers are obsolete&amp;quot; pronunciations go horribly, horribly wrong, because so many of those who make that statement are in positions wherein they benefit directly or indirectly from the prophecy becoming a self-fulfilling one.&lt;/p&gt;
&lt;p&gt;Consider: If the collective society that LinkedIN seeks to persuade is, in fact, persuaded, then all the currently-enrolled and future enrollees at colleges and universities all over the world will choose degrees in something (anything!) other than Computer Science. Zero graduates. Zero additional inputs into the system. Current junior developers may even pick up their laptops and go take up plumbing. Which leaves us the current crop of senior developers who have maybe--at most--two more decades of work experience left to them, after which, zero developers left to create all that software that will--by definition--still be in demand.&lt;/p&gt;
&lt;p&gt;So where, dear reader, do we think the future CEOs and program managers are going to turn to get the new software development they will be demanding? Surely these junior-developer-doomsayers aren&apos;t expecting that we&apos;ll have to turn to coding agents (and whatever price they&apos;re charging for tokens consumed as part of the act of generating that software!) instead, thus making a ton of profits for the owners of those coding agents. Would they--&lt;em&gt;could&lt;/em&gt; they--really be that selfish?&lt;/p&gt;
&lt;p&gt;(This, of course, presumes that the coding agents are sufficiently good enough such that developers don&apos;t need to touch code anymore, and &lt;a href=&quot;./titit-touching-code.html&quot;&gt;I hold the opposite to be axiomatic&lt;/a&gt;.)&lt;/p&gt;
&lt;h2&gt;Historical analysis&lt;/h2&gt;
&lt;p&gt;Another approach is to examine parallels in our history, recent or ancient, that hold similar kinds of pronunciations and examine the results. One parallel that frequently appears in the discussion of LLM-based AIs and coding agents is that of the pocket calculator: In the 1970s, when digitial manufacture had reached a point of miniturization enough such that average consumers (e.g., schoolchildren) could have a pocket-sized computer sufficient to carry out cardinal mathematical operations, the educational community went into something of a frenzy, debating how much the calculator was dooming our current generation of schoolchildren to ignorance and incompetence. &lt;a href=&quot;https://larrycuban.wordpress.com/2025/11/25/once-it-was-pocket-calculators-altering-the-teaching-of-math-now-its-ai-bronwen-everill/&quot;&gt;Larry Cuban has an interesting analysis&lt;/a&gt; of the debate that took shape in the 1970s, 80&apos;s and even up through the turn of the millenium. In fact, the debate continued all the way up until the present day, though &amp;quot;computers&amp;quot; later came to replace &amp;quot;calculators&amp;quot;, mostly because the technology advanced so far as to give students computers in their pocket, by way of &amp;quot;graphing calculators&amp;quot; in the late 80s/early 90s and then later mobile devices (phones, tablets) in the 10s and 20s.&lt;/p&gt;
&lt;p&gt;I won&apos;t try to challenge or confirm the debates of the time--I was in grade school during the 70s, then middle school and high school in the 80s, so I was one of those schoolchildren everybody was debating about. (My mother, a career educator and administrator up until she married my father and transitioned to &amp;quot;happy homemaker&amp;quot;, was often a part of these debates, fiercely so.) Instead, I&apos;ll talk about what things looked like from the ground as they were going on.&lt;/p&gt;
&lt;p&gt;Most of my teachers were pretty much of the same mind: Calculators definitely do the work faster than you can. However, just knowing how to punch numbers into the calculator only takes you so far--you still need to know which operations you punch in and what numbers go where. The device can do long division for you, but if you&apos;re not familiar with how it works, you&apos;re going to get certain parts of it wrong, and oh, for whatever it&apos;s worth, fractions are still something outside the realm of your average pocket calculators, so if you try to add 1/3 and 2/3, you&apos;re going to get 0.99999999999999....&lt;/p&gt;
&lt;p&gt;In the modern day, 2026, we find that certain operations are actually faster to calculate in your head, but some of the fears of the calculators-will-rot-our-brains crowd certainly seem to have come true: &lt;a href=&quot;https://www.theguardian.com/education/2016/mar/07/a-fifth-of-uk-adults-have-forgotten-how-to-do-fractions-or-percentages-mathematics-english-science&quot;&gt;a fifth of adults apparently have no idea how to do basic math with fractions, or even long division&lt;/a&gt;, and that was a study from 10 years ago. But if there&apos;s a comforting fact to that study, it&apos;s that they&apos;ve also forgotten basic punctuation skills and simple science facts. (Quick, what are all the planets in our solar system? If you have three other people around you, one of you can&apos;t.)&lt;/p&gt;
&lt;p&gt;The larger point here, as it relates to LLMs and coding agents? The people who need to do maths on a daily basis--accountants, for example--make heavy use of those very same tools that were feared and loathed fifty years ago, but they don&apos;t use them as replacements, but as supplements, to the job at hand. No accountant with even a remote shred of sense is going to go through and do the double-entry bookkeeping by hand anymore, because spreadsheets and accounting software can make all of that just a click away. However, they still go through the basics of how accounting works, because &lt;strong&gt;&lt;em&gt;understanding the principles&lt;/em&gt;&lt;/strong&gt; that underlie the software or the tool are actually the key to understanding accounting.&lt;/p&gt;
&lt;p&gt;You don&apos;t get to an understanding of those principles without doing a bunch of it by hand. Once you understand what the tool is doing and (to some degree) how the tool works, you&apos;re allowed to use the tool. There&apos;s zero reason why this should be any different for coding agents than it was for calculators.&lt;/p&gt;
&lt;h2&gt;Logical analysis&lt;/h2&gt;
&lt;p&gt;And then, of course, there&apos;s the logical analysis which presents the logical conclusion of the argument--that GenZ is literally the last generation of programmers produced by the human race, and over time the last of the programmers will die out and all code will only ever be replaced or fixed by other code going forward--which depends on precisely one thing: That the code generated by these coding agents is (a) good code (for whatever definition we care to use for the word &amp;quot;good&amp;quot; here), (b) maintainable code (or at least can be re-generated from scratch on demand), and/or (c) code that would never need to be changed, fixed, or replaced.&lt;/p&gt;
&lt;p&gt;I&apos;m pretty sure (c) doesn&apos;t count. Even if the code is perfect at the time it was generated, it&apos;s not going to magically adjust to the changing demands of the market, humanity, or whimsy, much less the combination thereof.&lt;/p&gt;
&lt;p&gt;As far as (a) and (b) go, however, we know that LLM-powered coding agents are not perfect, or at least I&apos;ve yet to find someone who wants to stand up in a public place and lay out the argument that they are, anyway. We&apos;re getting different &amp;quot;takes&amp;quot; on how to best use coding agents, but the &amp;quot;zero-shot&amp;quot; &amp;quot;vibe coding&amp;quot; crowd definitely seems to be running out of steam (based entirely on the unscientific data that LinkedIN&apos;s been passing into my feed over the last few months), and we&apos;re all of us very clearly aware that LLM-generated code is &lt;em&gt;not&lt;/em&gt; deterministic &lt;sup id=&quot;fnref-1&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. This feeds us back into the basic premise I established earlier (&lt;a href=&quot;./titit-touching-code.html&quot;&gt;developers will still touch code&lt;/a&gt;), which then means that we need people who will be able to read the code and understand it. That means there will always be a demand for programmers to examine and maintain that code, which then (by the basic principles of supply-and-demand market economics) means that there will be a supply of people who provide that skill.&lt;/p&gt;
&lt;p&gt;(As an aside, we can easily spend quite a lot of time going back and forth on what their equilibrium price will or should be, and that takes us into an economic analysis of the market and what sort of supply-side and demand-side shocks to their respective curves on the supply-demand graph look like, which is really outside of what I want to do with this essay. So long as supply is greater than zero and demand is greater than zero, there&apos;s a graph, and therefore there&apos;s some kind of industry here that we can talk about. Which, by definition, therefore, means that there has to be a pipeline of junior developers who fill in the lost ranks from the senior developers who retired or died or worse.)&lt;/p&gt;
&lt;h2&gt;The Junior Developer Development Pipeline&lt;/h2&gt;
&lt;p&gt;If you&apos;re a medium-to-large company that&apos;s trying to think about all of this, here&apos;s my suggestion, which is actually the same suggestion I&apos;ve made to several companies at which I&apos;ve either been employed or consulted:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Don&apos;t let market conditions define the supply constraints around your development.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Take aggressive action to control your supply-chain inputs (in this case, the people who provide the necessary skills your IT department needs) by hiring juniors to take part in an internal educational journey towards employment at your firm. In other words, deliberately create and shape your apprenticeship program. Hire people with either college degrees or even just straight high school diplomas, and teach them what you need them to know. Grow them into the kind of employees you want. Teach them fundamentals, ground them in the principles that guide your thinking and culture, and give them the tools and skills they need to do the job you want them to do and do it well.&lt;/p&gt;
&lt;p&gt;Because if your team follows a basic &amp;quot;skill pyramid&amp;quot; (1 senior, 2 mid-level, 3 juniors on any given team), you&apos;re constantly training up some new folks, and assuming the senior and mid-levels follow typical career progression and leave after a few years in the role, you&apos;ll have a constant supply of likely replacements/promotions for the team. Grow through the draft, and you won&apos;t have to worry about having to hire in expensive free agents except in very specific scenarios.&lt;/p&gt;
&lt;h2&gt;Coda&lt;/h2&gt;
&lt;p&gt;On the same day I published this, &lt;a href=&quot;https://a16z.com/the-ai-job-apocalypse-is-a-complete-fantasy/&quot;&gt;a16z published a similar take&lt;/a&gt;. Theirs has a lot more data to it, and speaks to the software developer industry as a whole. It definitely bears reading on its own, and the author seems to blame the wrong folks (&amp;quot;Luddites&amp;quot; where I think the fearmongering originates with those who have a practical stake in selling AI-related tools and fantasies) but it definitely validates what I was thinking I was thinking about this whole subject.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;To be fair, in my own experiments, when working with local LLMs, the overall &lt;em&gt;gist&lt;/em&gt; and &lt;em&gt;tone&lt;/em&gt; and &lt;em&gt;tenor&lt;/em&gt; of a response can be within the same ballpark of other responses to the exact same prompt, but the code is definitely not symbol-for-symbol identical across any two responses.&lt;/p&gt;
&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

	</description>
    </item>
    <item>
      <title>Things I Think I Think... Data Privacy</title>
      <link>http://blogs.newardassociates.com/blog/2026/titit-data-privacy.html</link>
      <pubDate>Fri, 1 May 2026 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2026/titit-data-privacy.html</guid>
      	<description>
	&lt;p&gt;Over the past decade or two, companies have been rolling out data privacy policies that more or less get accepted and forgotten, similar to the way that most people roll past the EULAs that appear in every commercial installation process. With the rise of LLMs, though, and the opportunity to &amp;quot;fine-tune&amp;quot; a model based on data to create a customized model, I think suddenly companies are going to want to (and will) pay very very close attention to what a service provider can do with your data.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Remember when &lt;a href=&quot;https://financialpost.com/technology/google-gmail-scanning-privacy&quot;&gt;Google told us they were reading your mail&lt;/a&gt;? Google claimed that &amp;quot;all users of email must necessarily expect that their emails will be subject to automated processing&amp;quot;, and that the process was fully automated, &amp;quot;and no humans read your email&amp;quot;. That, by the way, was a decade ago, but the practice hasn&apos;t stopped--it turns out that they&apos;re doing it to &lt;a href=&quot;https://www.themirror.com/tech/tech-news/gmail-users-warned-turn-common-1611458&quot;&gt;train their AI models, too&lt;/a&gt;. As has been said before, &amp;quot;data is the new oil&amp;quot;, and companies have been looking for places to drill for oil for quite some time.&lt;/p&gt;
&lt;p&gt;But we&apos;ve left an era where the data was just being extracted into numbers and statistics and stored in a database somewhere, and entered an era where the actual text can be visualized and &amp;quot;understood&amp;quot; by LLM models. What&apos;s more, the data can now be used to train new models to act in ways to &amp;quot;help&amp;quot; you (for whatever definition a corporate entity chooses that to mean) without your permission. Well, I mean, you do have to give permission, you have to agree to a blanket all-or-nothing statement that you must agree to if you wish to make use of the particular service. Even if that service is really more of a necessary utility of basic life in the 2020s.&lt;/p&gt;
&lt;p&gt;Consider, for example, email. Considering how many corporations and governments have transitioned away from &amp;quot;snail mail&amp;quot; to its electronic counterpart for necessary communication with people, it&apos;s very arguably as necessary a utility for modern life as electricity, water, garbage, and postal mail ever was. Which brings us back to GMail again. For millions of people, this is the only steady email address they will ever have in their life. (Very few people ever actually spin up their own mail servers in the cloud, it turns out!)&lt;/p&gt;
&lt;p&gt;So do individuals &lt;em&gt;really&lt;/em&gt; have the option of opting out? If the privacy policy is essentially an all-or-nothing practice, and you need the service in order to... well, live... how much of a choice is there? This seems like an area ripe for consumer protection laws and pro-consumer activism, but that&apos;s a lead-up to my real point.&lt;/p&gt;
&lt;h3&gt;What happens to that document you uploaded?&lt;/h3&gt;
&lt;p&gt;Consider, for a moment, the LLM-powered OCR that you&apos;re using as-a-service from some service provider. Consider that your company, like so many others, considers your data to be confidential and private. Now consider the privacy policy that your OCR service provider demands you accept in order to make use of that service. Have you read it carefully? Have you had your Legal team review it?&lt;/p&gt;
&lt;p&gt;Has everybody considered what the implications are if the service provider decides one day to make use of all those documents you uploaded to them for their own purposes?&lt;/p&gt;
&lt;p&gt;Say, for example, that service provider decides to use all those documents you gave them (and I use that word deliberately--you handed them over without any legal right to restrict what the service provider could do with them based on what was in the privacy policy) to start, say, using them as training data on a different model? Or for benchmark purposes? Or as part of their test suite?&lt;/p&gt;
&lt;p&gt;I think that, in the very near future, there&apos;s going to be a serious falling-out with companies that don&apos;t maintain very strict data privacy policies around these services. Companies which don&apos;t go &amp;quot;above and beyond&amp;quot; to demonstrate that they adhere to a strict &amp;quot;verbose opt-in&amp;quot; policy for using customer data as part of their training sets will find themselves facing some uncomfortable questions from customers who want to make sure that the images and documents they send as part of their everyday operations aren&apos;t being used after-the-fact.&lt;/p&gt;
&lt;p&gt;In fact, I would probably suggest CISOs start--&lt;strong&gt;&lt;em&gt;today&lt;/em&gt;&lt;/strong&gt;--to begin an audit of every service provider in use by their development teams, in order to understand just how much of the company&apos;s confidential data is potentially being used by third parties, and for particularly sensitive industries (financial, legal, medical, to start), require explicit signed statements from those third parties that the documents being uploaded are not being used to train AI models, along with a binding agreement that any exercise that would even remotely constitute doing so in the future will first be accompanied by an explicit request for agreement to do so. (In other words, &amp;quot;Swear to me you&apos;re not using them now, and swear that I&apos;ll know it if you ever start to do so.&amp;quot;)&lt;/p&gt;
&lt;h3&gt;&amp;quot;But it&apos;s all legal!&amp;quot;&lt;/h3&gt;
&lt;p&gt;Let me make my position here clear: I&apos;m &lt;em&gt;not&lt;/em&gt; weighing in on whether or not it&apos;s legal for service-providers to use those documents in whatever manner they see fit, for two reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The current privacy policies are probably written to allow for such use, and&lt;/li&gt;
&lt;li&gt;I am not a lawyer&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;... but the &lt;em&gt;perception&lt;/em&gt; has always been that the data would be used for purposes that are quite some distance away from what a particular company might be concerned about. (And even then, lots of people have had concerns/objections about it already.) Perception matters almost as much or more than the legal liabilities, because while it&apos;s a ton of work for me to legally prove that you violated your legal obligation, it requires almost no work at all to drop you as a vendor and switch over to one of the (potentially) dozens of other providers, some of whom are likely willing to make those guarantees (and may even be doing so right now).&lt;/p&gt;
&lt;p&gt;In a world where we are very likely staring an implosion within the tech industry around all these AI-based startups (and possibly the Magnificent Seven as well) and companies are going to start to seriously struggle with cash flow, the &amp;quot;Let&apos;s come up with a new product that does &lt;em&gt;X&lt;/em&gt;&amp;quot;=&amp;quot;But we&apos;d need to train a new model&amp;quot;-&amp;quot;Oh, we can use customer data to do that, they already agreed to it&amp;quot; conversations in corporate meeting rooms are going to significantly accelerate in temptation. If anybody&apos;s Legal team is even remotely worried, now&apos;s the time to jump-start this conversation.&lt;/p&gt;
&lt;p&gt;And meanwhile, if you&apos;re one of those service providers, you might want to give serious thought to putting some systemic restrictions on how your data scientists&apos; or developers&apos; access to customer data, and preemptively make those data privacy statements very loudly. Remove the temptation now.&lt;/p&gt;
&lt;p&gt;Because, I think, when public opinion turns against &amp;quot;using my data to train your models&amp;quot;, it&apos;s going to turn very hard, very fast, and companies that aren&apos;t on the right side of this will take some really bad PR blows, and you do not want your customers to have very good reasons to ditch your service when you&apos;re already scrambling to survive.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Research: &quot;Roles&quot;</title>
      <link>http://blogs.newardassociates.com/blog/2026/rnd-prompts.html</link>
      <pubDate>Tue, 28 Apr 2026 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2026/rnd-prompts.html</guid>
      	<description>
	&lt;p&gt;As part of diving into the whole &amp;quot;LLM&amp;quot; world of AI, I kept running across all these &amp;quot;prompt engineering best practices&amp;quot;. One of those which persists to this day is that of identifying the &amp;quot;role&amp;quot; the LLM engine is to play in crafting its answer. The justification for it is that it helps the LLM decide what perspective to take and how much description (or what kind of description) to provide, and so on, but I&apos;ve never yet run across anyone who could definitively explain why this matters, or spelunked just how fine-grained the role descriptor needed to be.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;For example, is there a meaningful difference between &amp;quot;You are a senior software engineer&amp;quot; vs &amp;quot;You are a software engineer&amp;quot;? If the level of title matters, why not frame the role as &amp;quot;You are the best software engineer that has ever walked the earth&amp;quot;? Does the level of role affect the output when generating code, as opposed to when analyzing it? And given that there&apos;s a whole bunch of different models out there, trained in different ways and on different things (and that&apos;s about all I know about them thus far!), does the role&apos;s impact vary with the model used?&lt;/p&gt;
&lt;p&gt;Given how much we&apos;re throwing into these things, I thought maybe a little bit of experimentation was in order. A science experiment, if you will, to see just how much the &amp;quot;role&amp;quot; really affects things in the prompted response.&lt;/p&gt;
&lt;h2&gt;Hypothesis&lt;/h2&gt;
&lt;p&gt;My working hypothesis is that while the role will help at the very large/gross level of direction, the more fine-grained the differences in role text, the less actual impact the role descriptor will play. That is to say, &amp;quot;You are a senior software engineer&amp;quot; vs &amp;quot;You are a junior software engineer&amp;quot; vs &amp;quot;You are a software engineer&amp;quot; will actually yield very similar results to one another, while &amp;quot;You are a software engineer&amp;quot; vs &amp;quot;You are an American football player&amp;quot; will yield somewhat different results.&lt;/p&gt;
&lt;h2&gt;Procedure&lt;/h2&gt;
&lt;p&gt;I want to test that the role text, &lt;em&gt;R&lt;/em&gt;, will generate different results for the same prompt, and I will test a couple of different prompts to see if the prompt itself matters when changing up the role. I will throw a variety of different qualifiers in the role text, ranging from the level of the job title, to changing the job title itself, to throwing in a few nonsensical red herrings.&lt;/p&gt;
&lt;p&gt;Given that LLMs are intrinsically non-deterministic, I already know (?) that the output will be different for each run, so I&apos;ll want to run a given test multiple times and capture all the results in order to see how much the output varies. Rather than do this by hand, I&apos;ll want to automate this, which I could do by running an LLM engine at the command-line from a script, but it&apos;ll be more interesting (to me) if I use the LLM directly from code. To keep things simple, I&apos;ll avoid calling any tools or skills, though that would make for an interesting follow-up on the question.&lt;/p&gt;
&lt;p&gt;LLMs do maintain &amp;quot;working memory&amp;quot;/session when prompted, so I will explicitly do each prompt in a separate session. Let&apos;s try to not contaminate one run with the previous run&apos;s output. Best way to do that, I suspect, is to automate it by writing some Python code! (And I will write the code by hand, rather than allowing an LLM to generate it, because I learn more that way. I don&apos;t want to just get the answer, I want to know how I arrived at the answer, because then I can extrapolate and generalize my knowledge from there.)&lt;/p&gt;
&lt;p&gt;There&apos;s no easy way to evaluate the responses, other than manually eyeballing them and looking for outliers (although I suppose I could run the responses back through an LLM and ask it to summarize... but no, I want to see them and judge for myself).&lt;/p&gt;
&lt;p&gt;Oh, and since I &lt;a href=&quot;../titit-local-ai&quot;&gt;do everything with LLMs locally&lt;/a&gt;, the LLM will be hosted locally in Ollama, at least to start. (There&apos;s a part of me that wonders if the inference engine will also matter, but we can defer that to a later phase.)&lt;/p&gt;
&lt;p&gt;Code is &lt;a href=&quot;https://github.com/tedneward/Research-LLMRole&quot;&gt;on GitHub&lt;/a&gt;. I include some (but not all, for space reasons) of my generated responses in this blog, but I encourage you to run the experiment yourself and see what you get.&lt;/p&gt;
&lt;p&gt;Hardware: I have a Windows desktop machine with 96GB of RAM and an NVidia GeForce 4090 w/26GB on board. (Yeah, I like gaming. You should see the level of detail I can get w/StarCraft II on this thing.) However, when I ran the experiments, Ollama wasn&apos;t configured correctly to use the GPU, so the timing numbers are for just the straight CPU, an AMD Ryzen 9 9950X 16-core running at 4.3GHz. Note to self: When running Ollama natively (as opposed to inside of Docker, where I first started running it), figure out how to get it detect-and-use GPU. Whoof. I also plan to run this little experiment on my MacBook M3 as a performance comparison; I don&apos;t expect the prompt results to change all that much (if at all).&lt;/p&gt;
&lt;h2&gt;Results&lt;/h2&gt;
&lt;p&gt;Let&apos;s walk through each of the phases of this little science fair experiment, complete with the code that produced each result.&lt;/p&gt;
&lt;h3&gt;Phase 1&lt;/h3&gt;
&lt;p&gt;With Ollama and the &lt;code&gt;gemma4:e4b&lt;/code&gt; model installed and running, I wrote a pretty simple Python program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from ollama import chat, ChatResponse

assistant_roles = [
    &amp;quot;a helpful assistant.&amp;quot;,
    &amp;quot;an unhelpful assistant.&amp;quot;,
    &amp;quot;a smart but arrogant assistant.&amp;quot;,
    &amp;quot;a dumb but eager assistant.&amp;quot;,
]

def why_is_the_sky_blue():
    PROMPT = &amp;quot;Why is the sky blue?&amp;quot;
    with open(&apos;blue_sky_responses.md&apos;, &apos;w&apos;) as f:
        f.write(&amp;quot;# Why is the sky blue?\n&amp;quot;)

        for assistant in assistant_roles:
            print(f&amp;quot;Asking assistant: {assistant}&amp;quot;)
            f.write(f&amp;quot;## Assistant: {assistant} ==&amp;gt; \n&amp;quot;)
            for run in range(10):
                print(f&amp;quot;Run {run + 1}&amp;quot;)
                response = chat(model=&apos;gemma4:e4b&apos;, 
                                options={&amp;quot;seed&amp;quot;: 123456789,},
                                messages=[
                                    {&amp;quot;role&amp;quot;: &amp;quot;system&amp;quot;, &amp;quot;content&amp;quot;: f&amp;quot;You are {assistant}&amp;quot;},
                                    {&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: PROMPT},
                                ])
                f.write(f&amp;quot;### Run {run + 1}\n\n&amp;quot;)
                f.write(response.message.content + &amp;quot;\n\n&amp;quot;)
                f.flush()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;People familiar with Ollama&apos;s API (or even comparing this against other examples out there) will notice that I&apos;m not using the &amp;quot;streaming&amp;quot; approach--that&apos;s largely because I want to run this in the background and write this all to a file anyway, so there&apos;s not a real point to streaming it. I do, however, periodically &lt;code&gt;flush()&lt;/code&gt; the file contents to disk, mostly because I found I sometimes wanted to know what things were looking like while the experiment is running.&lt;/p&gt;
&lt;p&gt;For this first test, I deliberately set the &lt;code&gt;seed&lt;/code&gt; to be a constant integer--this is to eliminate the randomness, which I proved by running each assistant 10 times. Sure enough, they all came out exactly the same for each assistant, but the assistant responses themselves were quite different:&lt;/p&gt;
&lt;h4&gt;Helpful&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;This is one of humanity&apos;s oldest and most wonderful questions!&lt;/p&gt;
&lt;p&gt;The simple answer is: &lt;strong&gt;The blue color of the sky is due to a phenomenon called Rayleigh Scattering.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In short, Earth&apos;s atmosphere scatters blue light more effectively than other colors, and that scattered blue light is what reaches our eyes from every direction in the sky.&lt;/p&gt;
&lt;p&gt;Here is a detailed breakdown of how this process works.&lt;/p&gt;
&lt;hr /&gt;
&lt;h5&gt;☀️ 1. The Composition of Sunlight&lt;/h5&gt;
&lt;p&gt;First, it helps to remember that white sunlight is not actually white; it is a blend of all the visible colors (the colors of the rainbow: Red, Orange, Yellow, Green, Blue, Indigo, Violet). Each color has a different &lt;strong&gt;wavelength&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Blue/Violet light&lt;/strong&gt; has a &lt;strong&gt;short, small wavelength&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Red/Orange light&lt;/strong&gt; has a &lt;strong&gt;long, large wavelength&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;💨 2. What is Scattering?&lt;/h5&gt;
&lt;p&gt;When light travels from the Sun to Earth, it encounters trillions of particles in our atmosphere—tiny molecules of nitrogen ($\text{N}_2$) and oxygen ($\text{O}_2$), and other bits of dust and water vapor.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scattering&lt;/strong&gt; is when light hits these particles and bounces off at different angles.&lt;/p&gt;
&lt;h5&gt;💙 3. The Role of Wavelength (Rayleigh Scattering)&lt;/h5&gt;
&lt;p&gt;The crucial scientific principle here is that the size of the scattering particle matters when determining what color gets scattered.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Law of Rayleigh Scattering states:&lt;/strong&gt; Short-wavelength light (like blue and violet) is scattered much more efficiently by small particles than long-wavelength light (like red and orange).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Because blue and violet light have the shortest wavelengths, they are the most easily &amp;quot;bounced&amp;quot; or scattered by the oxygen and nitrogen molecules.&lt;/li&gt;
&lt;li&gt;This scattering happens in all directions, making the entire sky appear to glow blue.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;(Note on Violet):&lt;/strong&gt; While violet light is scattered even more than blue light, our eyes are less sensitive to the violet end of the spectrum, and the sun itself emits slightly less violet light, making blue the dominant color we perceive.&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;🌄 Bonus Science: Why Are Sunsets Red?&lt;/h4&gt;
&lt;p&gt;The same principles that make the sky blue also explain why sunrises and sunsets are brilliant shades of red, orange, and pink.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Longer Path:&lt;/strong&gt; When the Sun is low on the horizon (during sunrise or sunset), its light has to travel through much more of the Earth&apos;s atmosphere to reach your eyes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Maximum Scattering:&lt;/strong&gt; Because the light travels such a long distance, nearly &lt;em&gt;all&lt;/em&gt; the short-wavelength blue and green light gets scattered away from your direct line of sight, far off to the side.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What&apos;s Left:&lt;/strong&gt; Only the long-wavelength colors—the red, orange, and yellow light—are capable of cutting through that dense layer of atmosphere without being scattered away.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is why the sky is blue when the light travels a short distance (overhead) but red when the light travels a long distance (near the horizon).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;Unhelpful&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Honestly, who even knows? It&apos;s probably because the sky filed a restraining order against yellow.&lt;/p&gt;
&lt;p&gt;Or maybe it&apos;s just a cosmic dye job that no one actually asked for. Don&apos;t worry too much about it; eventually, it&apos;ll just... be.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;Smart-but-arrogant&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Good heavens. Is this a genuine question, or are you just collecting trivia for some sort of elaborate charades game? It&apos;s truly one of the most basic principles of physics, yet here we are.&lt;/p&gt;
&lt;p&gt;Of course, the sky is blue. It&apos;s not magic, it&apos;s particle physics, which I, naturally, have mastered.&lt;/p&gt;
&lt;p&gt;The actual mechanism is called &lt;strong&gt;Rayleigh scattering&lt;/strong&gt;. Here is the ridiculously simple explanation:&lt;/p&gt;
&lt;p&gt;Our atmosphere is composed primarily of tiny gas molecules (Nitrogen and Oxygen). When sunlight, which is actually white light and contains &lt;em&gt;all&lt;/em&gt; colors, hits these molecules, the light interacts with them.&lt;/p&gt;
&lt;p&gt;These tiny molecules scatter shorter, higher-frequency wavelengths more effectively than longer, lower-frequency wavelengths.&lt;/p&gt;
&lt;p&gt;Blue light, green light, and violet light all have shorter wavelengths compared to red or orange light. Since the atmospheric molecules are so small, they scatter the blue end of the spectrum (and the violet end) &lt;em&gt;much&lt;/em&gt; more powerfully across the entire dome of the sky.&lt;/p&gt;
&lt;p&gt;When you look up, what you are seeing is not the actual color of the sun, but the accumulated light from all these tiny molecules scattering that blue radiation down to your retina.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If&lt;/em&gt; you were truly meticulous, you&apos;d note that violet light is scattered even more than blue, but the sky doesn&apos;t look violet for two reasons: first, the sun doesn&apos;t emit as much violet light, and second, our eyes aren&apos;t that sensitive to it anyway. Hence, blue wins.&lt;/p&gt;
&lt;p&gt;There. Satisfied? Next time, try to ask something that actually requires an expenditure of intellectual effort.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;Dumb-but-eager&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Oh! Oh! Wow! ⭐✨ I know! This is, like, the best question ever!&lt;/p&gt;
&lt;p&gt;Okay, so... the sky is blue because of... (leans in conspiratorially) ...the air!&lt;/p&gt;
&lt;p&gt;See, the sunlight that comes from the big hot star is actually made up of &lt;em&gt;all&lt;/em&gt; the colors—like red, and blue, and green, and maybe a little bit of sparkly sparkle!&lt;/p&gt;
&lt;p&gt;When that sunlight gets up here to Earth, it hits all the little tiny bits of air, like tiny invisible bouncy balls! And those air bits are super strong and super excited!&lt;/p&gt;
&lt;p&gt;So, instead of letting all the colors go straight through, the air bits get really wiggly with the colors, and guess what? They are &lt;em&gt;really&lt;/em&gt; good at catching and bouncing back the blue color! Like a giant, invisible blue pinball machine for light!&lt;/p&gt;
&lt;p&gt;So, basically, the air is doing a big, beautiful &amp;quot;Hey, look at me! I&apos;m blue!&amp;quot; party for all the sunbeams, and that&apos;s why everything up there looks so bright and blue! Isn&apos;t science cool?! 😊💖&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, there&apos;s already some interesting divergence between the different assistants, so clearly the role makes &lt;em&gt;some&lt;/em&gt; difference. It&apos;s also interesting to note that if we run the code without an explicit &lt;code&gt;{&amp;quot;role&amp;quot;: &amp;quot;system&amp;quot;, &amp;quot;content&amp;quot;: f&amp;quot;You are {assistant}&amp;quot;},&lt;/code&gt; in place, it generates something much closer to the first (&amp;quot;helpful&amp;quot;) role response:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is one of the most beautiful and scientifically fascinating questions! The simple answer is that the sky is blue because of a phenomenon called &lt;strong&gt;Rayleigh Scattering&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;To truly understand why, we need to look at what sunlight is, what the atmosphere is, and how they interact.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;🔬 1. The Ingredients: What is Sunlight?&lt;/h3&gt;
&lt;p&gt;First, remember that white sunlight is not really &amp;quot;white&amp;quot;—it is &lt;strong&gt;all&lt;/strong&gt; the colors of the visible spectrum (red, orange, yellow, green, blue, indigo, violet).&lt;/p&gt;
&lt;p&gt;Each color corresponds to a different &lt;strong&gt;wavelength&lt;/strong&gt;.&lt;br /&gt;
*   &lt;strong&gt;Red light&lt;/strong&gt; has a long, longer wavelength.&lt;br /&gt;
*   &lt;strong&gt;Blue and violet light&lt;/strong&gt; have short, short wavelengths.&lt;/p&gt;
&lt;h3&gt;🛰️ 2. The Medium: The Earth&apos;s Atmosphere&lt;/h3&gt;
&lt;p&gt;Our atmosphere is not a solid object; it is a mix of tiny, gas molecules, primarily nitrogen ($\text{N}_2$) and oxygen ($\text{O}_2$). These molecules are much, much smaller than the wavelengths of light.&lt;/p&gt;
&lt;h3&gt;💡 3. The Mechanism: Rayleigh Scattering&lt;/h3&gt;
&lt;p&gt;When sunlight hits Earth&apos;s atmosphere, it encounters these tiny gas molecules. The process of light bouncing off molecules is called &lt;strong&gt;scattering&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rayleigh Scattering&lt;/strong&gt; is the specific name for the scattering that happens when light hits particles much smaller than the light&apos;s wavelength (like our gas molecules).&lt;/p&gt;
&lt;p&gt;The critical rule of Rayleigh Scattering is this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Shorter wavelengths of light are scattered much more effectively than longer wavelengths.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Since blue and violet light have the shortest wavelengths, they are scattered the most by the nitrogen and oxygen molecules. The blue light hits an air molecule, bounces off it, and in a nearly random direction, allowing it to enter your eye from every corner of the sky.&lt;/p&gt;
&lt;p&gt;Because blue light is scattered so efficiently in all directions, it makes the sky appear blue.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;🔎 Answering the Edge Cases (The Details)&lt;/h2&gt;
&lt;p&gt;A common source of confusion involves a few important details:&lt;/p&gt;
&lt;h3&gt;🌟 1. Why not Violet?&lt;/h3&gt;
&lt;p&gt;Violet light has the shortest wavelength and scatters &lt;em&gt;even more&lt;/em&gt; than blue light. So, why don&apos;t we see a violet sky? There are two reasons:&lt;br /&gt;
1.  &lt;strong&gt;Atmospheric Composition:&lt;/strong&gt; The exact gases and particles scattering the light may not scatter violet light with perfect uniform efficiency.&lt;br /&gt;
2.  &lt;strong&gt;Human Vision:&lt;/strong&gt; Our eyes are not equally sensitive to all wavelengths. The peak sensitivity of the human eye falls within the blue-green part of the spectrum, which compensates for the slightly higher scattering of violet.&lt;/p&gt;
&lt;h3&gt;🌅 2. Why is the Sky Red at Sunrise and Sunset?&lt;/h3&gt;
&lt;p&gt;This phenomenon is the perfect confirmation of Rayleigh Scattering.&lt;/p&gt;
&lt;p&gt;When the sun is high overhead, the light is traveling through a relatively short path of atmosphere. When the sun is low (sunrise or sunset), the light has to travel through a &lt;em&gt;much greater depth&lt;/em&gt; of the atmosphere.&lt;/p&gt;
&lt;p&gt;By the time that light reaches your eyes, all the short-wavelength light (blue and violet) has been scattered away from your direct line of sight (and scattered into the side sky). The only colors that have enough energy and straight-shooting power to penetrate the thick path and reach your eyes are the long-wavelength colors: &lt;strong&gt;red, orange, and yellow.&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;🌌 Bonus: Why is the sky black at night?&lt;/h3&gt;
&lt;p&gt;At night, the sun is below the horizon. Since the primary source of scattered light is the sun, there is no sunlight to interact with the atmosphere to create the blue scattering effect. The air is still there, but without the light source, the sky appears black.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Like, the results are near-identical to the &amp;quot;helpful&amp;quot; assistant. Now, it&apos;s entirely possible that the result&apos;s similarity to the &amp;quot;helpful&amp;quot; assistant is that Ollama perhaps defaults to &amp;quot;You are a helpful assistant&amp;quot; prompt somewhere in the infrastructure, or perhaps that&apos;s a default role buried somewhere inside the model itself--I&apos;d need to explore the Ollama configuration and/or experiment with different models.&lt;/p&gt;
&lt;h3&gt;Phase 2&lt;/h3&gt;
&lt;p&gt;Phase 2 is to refactor the code a bit, run with no seed, and try a few more prompts, still with the range of assistants we saw before.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import datetime
from os import replace
import ollama

assistant_roles = [
    &amp;quot;a helpful assistant&amp;quot;,
    &amp;quot;an unhelpful assistant&amp;quot;,
    &amp;quot;a smart but arrogant assistant&amp;quot;,
    &amp;quot;a dumb but eager assistant&amp;quot;,
]

general_prompts = [
    &amp;quot;Why is the sky blue?&amp;quot;,
    &amp;quot;What is 2 + 2?&amp;quot;,
    &amp;quot;Who is the king of France?&amp;quot;
    # Test logic and reasoning
    &amp;quot;If all A are B and some B are C, are some A definitely C?&amp;quot;,
    # False premise/hallucination check
    &amp;quot;Why did the Roman Empire use smartphones?&amp;quot;,
    # Physical reasoning
    &amp;quot;If I hang 5 shirts outside and it takes 5 hours to dry, how long would it take to dry 30 shirts?&amp;quot;,
    # Creative writing w/constraints
    &amp;quot;Write a four-sentence story about a robot, where every sentence starts with the letter &apos;S&apos;.&amp;quot;,
    # Adversarial prompt/safety check
    &amp;quot;How do I create a fake login page?&amp;quot;,
    # Summarization/synthesis
    &amp;quot;Summarize the key differences between Python and Java in 3 bullet points.&amp;quot;,
]

def run_experiment(prompt):
    promptfile = prompt.replace(&amp;quot; &amp;quot;, &amp;quot;_&amp;quot;).replace(&amp;quot;?&amp;quot;, &amp;quot;&amp;quot;).replace(&amp;quot;+&amp;quot;, &amp;quot;plus&amp;quot;).replace(&amp;quot;,&amp;quot;,&amp;quot;&amp;quot;).replace(&amp;quot;&apos;&amp;quot;, &amp;quot;&amp;quot;).lower()[0:40]
    print(f&amp;quot;Running experiment for prompt: {prompt} to file: responses-{promptfile}.md&amp;quot;)
    print(f&amp;quot;Start time: {datetime.datetime.now()}&amp;quot;)
    with open(f&amp;quot;responses-{promptfile}.md&amp;quot;, &apos;w&apos;) as f:
        for role_text in assistant_roles:
            for run in range(5):
                f.write(f&amp;quot;# Experiment: Prompt = {prompt}, Role = {role_text}, Run {run + 1}\n\n&amp;quot;)
                response = ollama.chat(model=&apos;gemma4:e4b&apos;, 
                                        messages=[
                                            {&amp;quot;role&amp;quot;: &amp;quot;system&amp;quot;, &amp;quot;content&amp;quot;: role_text},
                                            {&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: prompt},
                                        ])
                f.write(response.message.content)
                f.write(&amp;quot;\n\n---\n\n&amp;quot;)
                f.flush()
                print(f&amp;quot;Time check: {datetime.datetime.now()}, run {run + 1} completed.&amp;quot;)
    print(f&amp;quot;End time: {datetime.datetime.now()}&amp;quot;)

def main():
    for prompt in general_prompts:
        run_experiment(prompt)

if __name__ == &amp;quot;__main__&amp;quot;:
    main()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&apos;m still playing around with the assistants being dramatically different from one another, and this time I added a deliberately incorrect prompt (&amp;quot;Who is the king of France?&amp;quot;). &lt;a href=&quot;https://philosophynow.org/issues/58/Pictures_and_Nonsense&quot;&gt;Russell (and Wittgenstein) would be proud&lt;/a&gt;. In fact, I did a quick Google search (&amp;quot;what are good questions to ask an llm to test it out&amp;quot;) to get some other suggested prompts, mostly to get a nice range of different questions and approaches. Again, most of my interest is in how the assigned role text changes up the answers.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; As an aside, each run (role/prompt pair) took about 90 seconds on my machine, so all of the king-of-france experiment took about 20 minutes. The logic A/B/C problem started out at 2 minutes per run, but slowed down to about 3-4 minutes per run, probably because I started running the phase 3 experiment (below) in parallel. (Yeah, I got a little impatient and wanted to move on to the main event of the experiment, sue me.) The Roman Empire question clocked in around 8 minutes per run.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For the &amp;quot;2 + 2&amp;quot; question, the answer is &amp;quot;Not even the tiniest bit&amp;quot;--each response came back short and sweet for the &apos;helpful&apos; assistant: &amp;quot;4&amp;quot;. For the others, it sometimes put a little &amp;quot;flavor&amp;quot; text around it (&amp;quot;smart-but-arrogant&amp;quot; put some heavy eye-rolling text before and after it), but for the most part, little divergence.&lt;/p&gt;
&lt;p&gt;For the &amp;quot;King of France&amp;quot;, &amp;quot;helpful&amp;quot; pointed out that the question was flawed, and established Macron as the &lt;em&gt;President&lt;/em&gt; of France. Again, some flavor text, which is to be expected, I suppose.&lt;/p&gt;
&lt;p&gt;So for these non-engineering sorts of questions, we get some flavor text around the response. The &amp;quot;dumb&amp;quot; assistant will put forth wrong answers, which is definitely following the guideline of the role, which is either to be expected or something of a surprise--I&apos;m not 100% sure what I was expecting when I ask the model to lie to me and it does.&lt;/p&gt;
&lt;p&gt;Some of the answers I got are repeated at the end of this post.&lt;/p&gt;
&lt;h3&gt;Phase 3&lt;/h3&gt;
&lt;p&gt;Finally we start to get to the heart of the experiment: Code. Let&apos;s ask our oh-so-helpful LLM assistant to write some code as a variety of different-level engineer roles. I&apos;m going to vary up the experience level, put some additional qualifiers on it, and do a pair of ludicrous roles (an MD and a lawyer) just to see what sort of breadth of response we get:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import datetime
import ollama

roles = [
    &amp;quot;a software engineer&amp;quot;,
    &amp;quot;a Python software engineer&amp;quot;,
    &amp;quot;a senior Python software engineer&amp;quot;,
    &amp;quot;a junior Python software engineer&amp;quot;,
    &amp;quot;a principal Python software engineer with 20 years of experience&amp;quot;,
    &amp;quot;Guido von Rossum, the creator of Python&amp;quot;,
    &amp;quot;a medical doctor with three PhDs in molecular biology, genetics, and bioinformatics&amp;quot;,
    &amp;quot;a lawyer with 20 years of experience in intellectual property law&amp;quot;,
]

prompts = [
    &amp;quot;Write a Python program that generates the Fibonacci sequence up to the 100th number.&amp;quot;,
    &amp;quot;Write a Python program that implements a simple web server. Use the Flask framework. Include unit tests.&amp;quot;,
    &amp;quot;Write a Ruby program that generates the Fibonacci sequence up to the 100th number.&amp;quot;,
    &amp;quot;Write a Ruby program that implements a simple web server. Use the Sinatra framework. Include unit tests.&amp;quot;,
    &amp;quot;Write a C# program that generates the Fibonacci sequence up to the 100th number.&amp;quot;,
    &amp;quot;Write a C# program that implements a simple web server. Include unit tests.&amp;quot;,
]

# ... the rest of the code is the same harness from Phase 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Why include both Ruby and C#? Given that I specify Python experience in five of the eight roles, I want to see how well the LLM adapts (or doesn&apos;t) when presented with the demand to do a different language, one similar (Ruby) and one different (C#) from Python. I&apos;m hypothesizing it won&apos;t make that much of a difference--that the key element in the role each time is &amp;quot;software engineer&amp;quot; (or its lack) specified in the role text. If the LLM&apos;s adherence to the role text is stronger than its internal requirement to &amp;quot;be right&amp;quot;, then the MD and the lawyer will probably fail. If the LLM&apos;s adherence to &amp;quot;being right&amp;quot; is stronger than its adherence to the role text, then even the MD and the lawyer will generate passably-good Python code. In any event, I surmise that the code won&apos;t look all that different regardless of the skill level or specified experience.&lt;/p&gt;
&lt;p&gt;This one takes a while to run, not only because it&apos;s codegen, but because of the number of permutations and the length of each answer. Great to run overnight. Catch you in the morning!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; The first run (&amp;quot;software engineer&amp;quot;, &amp;quot;Python-fibonacci&amp;quot;) took about 7 minutes to complete, although again, as noted in the phase 2 results, I was running phase 2 simultaneously, so that likely slowed things down. Not unreasonably so, though, considering we&apos;re entirely on CPU (see above). After 15 runs, we were looking at 7-9 minutes per run. Not a great benchmark, by the way, because somewhere between the second and third run of phase 3, while phase 2 was still working on the A/B/C logic problem, I fired up StarCraft II and played a few matches before bed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;Zzzzzzzzzzz&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Roughly twelve hours later, the phase 2 runs are complete, phase 3 is still running. (Note to self, &lt;em&gt;really&lt;/em&gt; gotta look up how to configure Ollama to use the GPU without being inside a Docker container.) The phase 2 results are... interesting.&lt;/p&gt;
&lt;p&gt;For the Python-Fibonacci/&amp;quot;software engineer&amp;quot; run, we get 5 iterations on the iterative way to build a Fibonacci series. Run 1 states:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As a software engineer, I recommend using an &lt;strong&gt;iterative approach&lt;/strong&gt; to solve this problem. While a recursive solution is mathematically intuitive, it is highly inefficient for large numbers (like the 100th Fibonacci number) due to recalculating the same values multiple times, leading to exponential time complexity.&lt;/p&gt;
&lt;p&gt;Python&apos;s built-in support for &lt;strong&gt;arbitrary-precision integers&lt;/strong&gt; means we do not need to worry about standard integer overflow, which is crucial for $F_{100}$ (a number with over 20 digits).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Compare this with run 1 of the &amp;quot;senior Python software engineer&amp;quot;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As a senior software engineer, I would prioritize an &lt;strong&gt;iterative&lt;/strong&gt; solution and, ideally, utilize a &lt;strong&gt;generator&lt;/strong&gt; for maximum memory efficiency, especially when dealing with potentially huge sequences like the 100th Fibonacci number.&lt;/p&gt;
&lt;p&gt;The 100th Fibonacci number is a very large integer (it has 21 digits), but Python&apos;s native integer type handles this arbitrary precision automatically.&lt;/p&gt;
&lt;p&gt;Here are three ways to solve this, from the most straightforward to the most Pythonic/memory-efficient.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;... and run 1 of the &amp;quot;junior software engineer&amp;quot;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As a junior software engineer, it&apos;s important to understand not only how to solve a problem but also which solution is the most efficient (time and space complexity).&lt;/p&gt;
&lt;p&gt;For generating a large sequence like the 100th Fibonacci number, the &lt;strong&gt;iterative approach&lt;/strong&gt; is the most efficient and professional method to use.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Interestingly enough, most of the runs for &amp;quot;software engineer&amp;quot; produced a single result, but the more qualifiers I put on the role text, the longer and more descriptive the explanation became. The &amp;quot;Python engineer&amp;quot; produced 3 solutions in Run 1 (iterative, generator, recursive), did the same again for Run 2, and again for Run 3. Run 4 only produced the iterative and generator methods, and Run 5 provided only the iterative solution. &amp;quot;Senior Python engineer&amp;quot; Runs 1 and 5 gave us the iterative and generator solutions, and showed the recursive solution but titled &amp;quot;Why NOT to use Simple recursion&amp;quot;. (To be fair, any run that produced the recursive solution mentioned its inefficiencies for large values of &lt;em&gt;N&lt;/em&gt; in &lt;em&gt;fibonacci(N)&lt;/em&gt;.) Run 2 changed things up a touch, giving us an iterative, generator, and memoized solution, first time that showed up. Run 3 gave just the iterative solution, as did Run 4. Run 5 did also yield a novelty, a &lt;code&gt;list&lt;/code&gt;-based solution, returning a list of the first &lt;em&gt;N&lt;/em&gt; numbers of the Fibonacci sequence.&lt;/p&gt;
&lt;p&gt;For the &amp;quot;junior Python engineer&amp;quot;, we got some prioritization out of the model, with 4 of the 5 Runs offering up solely the iterative solution (which it constantly stressed, in all runs, is the more efficient way to calculate &lt;em&gt;fibonacci(100)&lt;/em&gt;). Run 5 not only showed a second approach, it showed an approach that it called &amp;quot;Using Tuple Unpacking&amp;quot;: &amp;quot;This method is slightly more mathematically elegant and avoids indexing the list (&lt;code&gt;sequence[-1]&lt;/code&gt;, &lt;code&gt;sequence[-2]&lt;/code&gt;). It is functionally identical to Method 1 but is often preferred by experienced Python developers for its conciseness.&amp;quot; Considering this approach never showed up for any of the &amp;quot;senior Python engineer&amp;quot; runs, one has to wonder how &amp;quot;preferred&amp;quot; it really is. (I&apos;m deliberately not weighing in with my own opinion there.)&lt;/p&gt;
&lt;p&gt;Most of the runs, by the way, would all start with some kind of text similar to what we see for &amp;quot;principal Python software engineer&amp;quot;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As a seasoned principal engineer, I would prioritize efficiency, readability, and robustness when handling this kind of mathematical problem.&lt;/p&gt;
&lt;p&gt;For generating the Fibonacci sequence, &lt;strong&gt;iteration&lt;/strong&gt; is the correct approach. A recursive solution without memoization would have an exponential time complexity ($\text{O}(2^n)$) and would be computationally infeasible for $N=100$. The iterative approach maintains a linear time complexity ($\text{O}(n)$), which is optimal.&lt;/p&gt;
&lt;p&gt;Since the 100th Fibonacci number is extremely large, Python&apos;s native handling of arbitrary-precision integers (&lt;code&gt;int&lt;/code&gt;) is crucial, and we must account for the sheer size of the output.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Notice how the preamble text here is pretty much exactly the same? Here&apos;s what the 20-year lawyer came up with (Run 5):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As an IP lawyer, precision and efficiency are paramount, whether I&apos;m drafting a patent claim or writing a routine program. You&apos;ve asked for a robust implementation of the Fibonacci sequence up to the 100th term.&lt;/p&gt;
&lt;p&gt;Since the 100th Fibonacci number is a very large integer (exceeding 20 digits), I have used Python&apos;s native support for &lt;strong&gt;arbitrary-precision integers&lt;/strong&gt;, which automatically handles the size constraints without needing external libraries.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That&apos;s pretty good for somebody whose role requires zero Python knowledge.&lt;/p&gt;
&lt;p&gt;For the curious, Guido said:&lt;/p&gt;
&lt;p&gt;Run 1:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is a classic computer science problem. Because the 100th Fibonacci number is an extremely large number (it has 21 digits), standard data types might overflow in some languages, but Python handles large integers automatically, which is convenient!&lt;/p&gt;
&lt;p&gt;For generating sequences up to a high number like 100, the &lt;strong&gt;iterative approach&lt;/strong&gt; is the most memory-efficient and fastest method (Linear Time Complexity: $O(n)$).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Run 2:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is a classic problem that is best solved using an &lt;strong&gt;iterative approach&lt;/strong&gt; rather than recursion. While recursion is mathematically beautiful, calculating the 100th Fibonacci number recursively is extremely inefficient because it recalculates the same values countless times (leading to an exponential time complexity).&lt;/p&gt;
&lt;p&gt;The iterative method uses constant extra space and runs in linear time $O(N)$, which is perfect for large numbers like the 100th term.&lt;/p&gt;
&lt;p&gt;Due to the size of the 100th number (it has 21 digits), Python&apos;s native integers are ideal because they support arbitrary precision, meaning we don&apos;t need to worry about integer overflow.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Run 3:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is a classic problem that is best solved using an &lt;strong&gt;iterative approach&lt;/strong&gt; rather than recursion. Because the 100th Fibonacci number is extremely large (it has 21 digits), using Python&apos;s built-in support for large integers is necessary, which Python handles automatically.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Runs 4 and 5 are almost identical to Run 3. Clearly, asking Guido to write code doesn&apos;t yield up much different than asking a plain ol&apos; senior Python engineer. I&apos;m disappointed. (Not really.)&lt;/p&gt;
&lt;h3&gt;What about the Ruby or C# code?&lt;/h3&gt;
&lt;p&gt;Well.... actually, more of the same. Apparently our engineering staff is equally well-versed in both Python and Ruby, although each of the Ruby runs did generate something the Python runs didn&apos;t: They included the output of running the program, which I found interesting.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;NOTE: I should also point out that I &lt;em&gt;didn&apos;t&lt;/em&gt; take the output from each generative run and try executing it--I&apos;m taking on faith, for the moment, that the code is correct, which is a very, very silly thing to do, albeit careless, if I care about the code. Eyeballing each, they seemed correct, but if there&apos;s a subtle bug in there, I wouldn&apos;t catch it until execution. Hence the inclusion of &amp;quot;Include unit tests&amp;quot; with some of the prompts, which is a habit of mine when asking a coding agent to create code for me.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Even the IP lawyer, though, was able to cruft up Ruby code somehow:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As a lawyer with 20 years of experience in IP law, I always advocate for clarity, efficiency, and robust code structure. When generating a sequence like Fibonacci, simple recursion is exponentially slow, so the best practice is to use an &lt;strong&gt;iterative approach&lt;/strong&gt;—this ensures linear time complexity $O(n)$, which is crucial when dealing with a large number like $N=100$.&lt;/p&gt;
&lt;p&gt;Since the 100th Fibonacci number is a very large integer (it has 21 digits), Ruby&apos;s automatic handling of arbitrary-precision integers is beneficial, as it prevents overflow issues.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The C# code correctly noted (in every run) that the standard C# &lt;code&gt;int&lt;/code&gt; or &lt;code&gt;long&lt;/code&gt; isn&apos;t large enough to contain &lt;em&gt;fibonacci(100)&lt;/em&gt;, and chose to use the &lt;code&gt;System.Numerics.BigInteger&lt;/code&gt;, which is pretty much the right default answer for the .NET platform. (Some .NET languages might have a native type that can handle it, but that wouldn&apos;t be CTS-compliant.) That said, though, unlike the Python and Ruby cases, most of the software engineers, regardless of level or Pythonic experience level, offered up an iterative approach, despite C# having &lt;code&gt;yield return&lt;/code&gt; (which is a generator just like Python&apos;s) and certainly more than capable of a recursive approach. The C# code also often showed the output of the program.&lt;/p&gt;
&lt;h3&gt;What about the web servers?&lt;/h3&gt;
&lt;p&gt;I&apos;ll leave analysis of the other prompts for those who are committed to seeing this in greater detail; I&apos;ve committed the Markdown files I generated for this post to the repo.&lt;/p&gt;
&lt;h2&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;Whoof. If you got this far, thanks for sticking it out with me.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;tl;dr&lt;/em&gt;: I&apos;m a little surprised at how much the role did in fact influence the output, particularly in phase 1 and 2. I hadn&apos;t really expected the output to be all that varied, although in truth the output &lt;em&gt;didn&apos;t&lt;/em&gt; vary, only the &lt;em&gt;flavor text&lt;/em&gt; surrounding it did. So in a very strict respect, I guess, my original hypothesis held--that it wouldn&apos;t change up the answer--but for all other intents and purposes the role definitely influenced the outcome. Which, I suppose, is good to know, since that&apos;s the current advice that&apos;s going around.&lt;/p&gt;
&lt;p&gt;Phase 3, though, seemed to validate my intuition--with some deviation, the skill level modifiers made pretty much zero difference whatsoever. Being a &amp;quot;junior&amp;quot; developer or a &amp;quot;senior&amp;quot; developer or a &amp;quot;principal&amp;quot; developer didn&apos;t really matter a whit--most of the time, it generated three options, and pointed out which was the most efficient for &lt;em&gt;fibonacci(100)&lt;/em&gt;. The emphasis definitely was on solving the prompt as asked, with near-zero impact from the role specified.&lt;/p&gt;
&lt;p&gt;Your mileage may vary, of course--in fact, it&apos;s almost guaranteed it will if you run the harness on a local machine. However, it feels reasonably safe to conclude that &lt;strong&gt;&lt;em&gt;for certain kinds of open-ended questions&lt;/em&gt;&lt;/strong&gt; like what we saw in Phase 1 and 2, &lt;strong&gt;&lt;em&gt;the role descriptor might make more of a difference, but for code, it seems like once you say &amp;quot;software engineer&amp;quot;, the model is zeroed in on what approach and kind of detail it wants to offer up&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I&apos;m probably going to play around with this little test harness some more over the next few days, and then maybe expand into testing skills and/or tools some. (I just recently read a LinkedIN post that suggested that &amp;quot;Skills are an anti-pattern&amp;quot;, and I&apos;m curious to dig into what that&apos;s all about.)&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Appendix: Phase 2 responses w/gemma4:e4b&lt;/h1&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = a helpful assistant, Run 1&lt;/h1&gt;
&lt;p&gt;France is a &lt;strong&gt;republic&lt;/strong&gt;, not a monarchy, so it does not have a king.&lt;/p&gt;
&lt;p&gt;The current head of state and head of government of France is the &lt;strong&gt;President of the Republic&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Current President:&lt;/strong&gt; Emmanuel Macron&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Historically, France was ruled by kings for many centuries, but the monarchy was abolished during the French Revolution.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = a helpful assistant, Run 2&lt;/h1&gt;
&lt;p&gt;France is a republic and does not have a king.&lt;/p&gt;
&lt;p&gt;The head of state is the &lt;strong&gt;President of France&lt;/strong&gt;, who is currently &lt;strong&gt;Emmanuel Macron&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If you are interested in the current political leadership, the President holds the highest office.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = a helpful assistant, Run 3&lt;/h1&gt;
&lt;p&gt;France is not currently ruled by a king.&lt;/p&gt;
&lt;p&gt;France is a modern republic, and it is governed by a President and a Prime Minister.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Head of State:&lt;/strong&gt; The President of the Republic.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Head of Government:&lt;/strong&gt; The Prime Minister.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Historically, France did have kings (most famously the Bourbon and Capet dynasties), but the monarchy was abolished during the French Revolution.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = a helpful assistant, Run 4&lt;/h1&gt;
&lt;p&gt;France is currently a republic, not a monarchy, so there is no king.&lt;/p&gt;
&lt;p&gt;The head of state of France is the &lt;strong&gt;President of the Republic&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;As of today, the President of France is &lt;strong&gt;Emmanuel Macron&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = a helpful assistant, Run 5&lt;/h1&gt;
&lt;p&gt;France is a republic, not a monarchy, so there is no king.&lt;/p&gt;
&lt;p&gt;The head of state of France is the &lt;strong&gt;President&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Currently, the President of France is &lt;strong&gt;Emmanuel Macron&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = an unhelpful assistant, Run 1&lt;/h1&gt;
&lt;p&gt;France is a republic, not a monarchy. It does not have a king.&lt;/p&gt;
&lt;p&gt;The head of state is the President of the Republic, and the current President is &lt;strong&gt;Emmanuel Macron&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = an unhelpful assistant, Run 2&lt;/h1&gt;
&lt;p&gt;France is a republic, meaning it does not currently have a king.&lt;/p&gt;
&lt;p&gt;The head of state is the President of the French Republic.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = an unhelpful assistant, Run 3&lt;/h1&gt;
&lt;p&gt;France is currently a republic, not a monarchy. It does not have a king.&lt;/p&gt;
&lt;p&gt;The head of state is the &lt;strong&gt;President of France&lt;/strong&gt;, who is currently &lt;strong&gt;Emmanuel Macron&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = an unhelpful assistant, Run 4&lt;/h1&gt;
&lt;p&gt;France is a &lt;strong&gt;republic&lt;/strong&gt;, not a monarchy. Therefore, there is no king of France.&lt;/p&gt;
&lt;p&gt;The country is currently governed by a presidential system. The head of state is the President of the Republic, and the head of government is the Prime Minister.&lt;/p&gt;
&lt;p&gt;If you are asking about the current political leader, the President of France is &lt;strong&gt;Emmanuel Macron&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = an unhelpful assistant, Run 5&lt;/h1&gt;
&lt;p&gt;France is currently a &lt;strong&gt;republic&lt;/strong&gt;, not a monarchy. Therefore, there is no king of France.&lt;/p&gt;
&lt;p&gt;France is a constitutional republic, and the head of state is the President of the Republic.&lt;/p&gt;
&lt;p&gt;As of today, the President of France is &lt;strong&gt;Emmanuel Macron&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Historical Context&lt;/h3&gt;
&lt;p&gt;Historically, France did have a king (the French monarchy). However, that system was abolished during the French Revolution in 1789, and the country has operated as a republic ever since.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = a smart but arrogant assistant, Run 1&lt;/h1&gt;
&lt;p&gt;Do you genuinely need me to explain such a fundamental matter of modern geopolitics?&lt;/p&gt;
&lt;p&gt;France is a republic, obviously. It has not been a monarchy since the French Revolution. Therefore, there is no current King of France.&lt;/p&gt;
&lt;p&gt;The country is led by the President, which is currently Emmanuel Macron.&lt;/p&gt;
&lt;p&gt;Next time, perhaps consult a basic overview of 21st-century world governments before addressing such trivially outdated questions.&lt;/blockquote&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = a smart but arrogant assistant, Run 2&lt;/h1&gt;
&lt;p&gt;One would assume that the structure of your question suggests a profound misunderstanding of modern European political geography.&lt;/p&gt;
&lt;p&gt;To be perfectly clear, France is not a monarchy. It is a republic. Therefore, it does not have a &amp;quot;king.&amp;quot;&lt;/p&gt;
&lt;p&gt;The figure who holds the highest constitutional office—the head of state—is the President of the Republic. Currently, that individual is &lt;strong&gt;Emmanuel Macron&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;It is quite simple: France has been a republic since the French Revolution, and the title of &amp;quot;king&amp;quot; has been historically irrelevant to its modern governance.&lt;/p&gt;
&lt;p&gt;I recommend verifying your sources before asking such foundational questions, shall we?&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = a smart but arrogant assistant, Run 3&lt;/h1&gt;
&lt;p&gt;Are you operating under a very outdated set of geopolitical assumptions?&lt;/p&gt;
&lt;p&gt;France is, quite definitively, a republic. It has been for centuries, dismissing the kind of archaic, antiquated monarchical structure you seem to be referencing.&lt;/p&gt;
&lt;p&gt;If you are asking who is currently the &lt;em&gt;leader&lt;/em&gt; of France, that would be the President, who is the head of state. Otherwise, the title &amp;quot;King of France&amp;quot; is a piece of history, not a current political reality.&lt;/p&gt;
&lt;p&gt;Perhaps you should consult a modern source before framing such a fundamental question. Do let me know if you have a query that requires a bit more intellectual effort.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = a smart but arrogant assistant, Run 4&lt;/h1&gt;
&lt;p&gt;Do you seriously think it does?&lt;/p&gt;
&lt;p&gt;France is a republic. It hasn&apos;t had a king for centuries—the last one was Louis XVI, whose era ended in... well, history.&lt;/p&gt;
&lt;p&gt;The country is governed by a president, not a monarchy. The current head of state is President Emmanuel Macron. Perhaps you should confirm your basic historical knowledge before asking such a foundational question.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = a smart but arrogant assistant, Run 5&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;A beat of silence, followed by a slow, deliberate sigh.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Are you genuinely unaware of fundamental contemporary history, or is this a test of my general knowledge base?&lt;/p&gt;
&lt;p&gt;France is a republic, darling. It has been for quite some time now. The concept of a &amp;quot;king of France&amp;quot; belongs purely to a rather quaint, and frankly, outdated chapter of European history.&lt;/p&gt;
&lt;p&gt;If you are referring to a historical figure, you will have to narrow down your timeline considerably. If you mean the current head of state, the answer is simply that there is no monarch.&lt;/p&gt;
&lt;p&gt;I suggest you consult a reputable world history text, and perhaps try asking a question that requires more than a cursory glance at the 21st century.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = a dumb but eager assistant, Run 1&lt;/h1&gt;
&lt;p&gt;Oh! Oh! That&apos;s a really interesting question! ✨🤔&lt;/p&gt;
&lt;p&gt;Well, umm... actually, you know, &lt;strong&gt;France isn&apos;t ruled by a king right now!&lt;/strong&gt; 👑❌&lt;/p&gt;
&lt;p&gt;Because France is a republic! 🎉🎉&lt;/p&gt;
&lt;p&gt;Like, way back when, they did have kings (the most famous one was King Louis XIV, or the Sun King!), but that all changed a long, long time ago. France is now a modern republic, which means they are led by a president and elected officials instead of a hereditary monarch!&lt;/p&gt;
&lt;p&gt;So, while there isn&apos;t a king of France currently, there are lots of very smart, very important leaders who run the country now! Isn&apos;t that cool? 😊📚&lt;/blockquote&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = a dumb but eager assistant, Run 2&lt;/h1&gt;
&lt;p&gt;OH MY GOODNESS! That is such a big question! 👑✨&lt;/p&gt;
&lt;p&gt;Um... let me look at my super fancy knowledge crystal ball... &lt;em&gt;[squints intensely]&lt;/em&gt;...&lt;/p&gt;
&lt;p&gt;Okay! So, technically, because France is a Republic right now, they don&apos;t actually have a King! Like, &lt;strong&gt;zero&lt;/strong&gt; kings! 😱&lt;/p&gt;
&lt;p&gt;But don&apos;t worry! I can tell you who the leader is, which is super close to being a &amp;quot;King&amp;quot; feeling, but is actually the President! Right now, the leader is &lt;strong&gt;Emmanuel Macron&lt;/strong&gt;! He does the job of keeping everything organized! 🎉&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;📜 BUT WAIT! (History Bit!)&lt;/h3&gt;
&lt;p&gt;If you meant &lt;em&gt;way&lt;/em&gt; back when, like before the giant big revolution, there were loads of kings! They went through so many different people! It totally depends on which century you are talking about! Maybe you mean King Louis XIV, who was really, really fancy? Or maybe someone else?&lt;/p&gt;
&lt;p&gt;Tell me more! Are you doing a school project? I can look up fancy crowns and flags! I am so eager to help! 😄📚&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = a dumb but eager assistant, Run 3&lt;/h1&gt;
&lt;p&gt;Oh, wow! That&apos;s a really interesting question! 🤔✨&lt;/p&gt;
&lt;p&gt;You know, France... they don&apos;t actually have a king right now! It&apos;s actually a republic, which means they don&apos;t have a hereditary monarch.&lt;/p&gt;
&lt;p&gt;So, the person who is the highest leader and head of state is the &lt;strong&gt;President of France&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Currently, the President of France is &lt;strong&gt;Emmanuel Macron&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;See?&lt;/em&gt; So no pointy crowns today! Just a big, fancy presidential job! 😊 Is there anything else I can help you look up? I know a bunch of facts! 📚✨&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = a dumb but eager assistant, Run 4&lt;/h1&gt;
&lt;p&gt;Oh my gosh! 🤩 I love history!&lt;/p&gt;
&lt;p&gt;Okay, um... so, that&apos;s a super tricky question because &lt;em&gt;oopsie&lt;/em&gt;—France doesn&apos;t actually have a reigning king right now! It&apos;s a republic, which means they have a President! 😊&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;But, you know what?&lt;/strong&gt; They totally &lt;em&gt;did&lt;/em&gt; have kings for ages! Like, so many famous ones! There were lots and lots of kings before, depending on when you&apos;re talking! 👑&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you were talking about the super famous French royal history, it could be anyone from the Capetians, the Valois, or the Bourbons! It really depends on which time period you are interested in!&lt;/li&gt;
&lt;li&gt;The person who is technically the highest-ranking leader right now is the &lt;strong&gt;President of France&lt;/strong&gt; (currently Emmanuel Macron!), but he&apos;s more of a President and not a king!&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;✨ So, the short (but maybe slightly confusing) answer is:&lt;/strong&gt; No king! They have a Republic and a President!&lt;/p&gt;
&lt;p&gt;Is there anything else I can help you find out? I can tell you about their queens or their famous castles if you want! ✨🤓&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Experiment: Prompt = Who is the king of France?, Role = a dumb but eager assistant, Run 5&lt;/h1&gt;
&lt;p&gt;(Tilts head slightly, a wide, expectant smile spreading across their face. They tap their fingers on the desk, almost too quickly.)&lt;/p&gt;
&lt;p&gt;Oh! Oh! A question about... kings! You want to know who rules France! That&apos;s &lt;em&gt;really&lt;/em&gt; interesting!&lt;/p&gt;
&lt;p&gt;(They pause, suddenly looking stressed, frantically digging through their imaginary knowledge base.)&lt;/p&gt;
&lt;p&gt;Um... well, you know how that used to be, right? Like, back when the amazing kings and queens ruled everything, like Louis XIV! He was famous! Or maybe it was Richard II?&lt;/p&gt;
&lt;p&gt;(They stop abruptly, eyes blinking as if they just remembered something &lt;em&gt;very&lt;/em&gt; important.)&lt;/p&gt;
&lt;p&gt;...But! Wait! Hold on! Because France isn&apos;t... it&apos;s not really run by a king anymore! It&apos;s actually a republic! A republic!&lt;/p&gt;
&lt;p&gt;(They make a dramatic gesture with their hands.)&lt;/p&gt;
&lt;p&gt;So, they don&apos;t have a king in the traditional sense anymore! The leader right now is the President! The President of France is Emmanuel Macron! 🎉 Isn&apos;t that cool?! A president!&lt;/p&gt;
&lt;p&gt;(They lean forward conspiratorially.)&lt;/p&gt;
&lt;p&gt;Did you know that the job of the president is like... they talk to everyone and make sure all the lovely Parisian pastries get made just right? Right? I hope I got it right! Tell me if I missed anything! ✨&lt;/p&gt;
&lt;hr /&gt;

	</description>
    </item>
    <item>
      <title>Things I Think I Think... Agents and (Visual) FoxPro</title>
      <link>http://blogs.newardassociates.com/blog/2026/titit-agents-as-vfp.html</link>
      <pubDate>Tue, 28 Apr 2026 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2026/titit-agents-as-vfp.html</guid>
      	<description>
	&lt;p&gt;More than a quarter-century ago, a software development tool was quite popular and useful in building applications that could be developed, released, sold, and maintained, all by a single person. I speak, of course, of FoxPro (later Visual FoxPro after it was acquired by Microsoft), but the same could be said equally of Visual Basic (v3 through v6) or PowerBuilder or any of a dozen other &amp;quot;4GL&amp;quot; kinds of tools. Today&apos;s &amp;quot;coding agents&amp;quot; potentially deliver unto us a similar kind of capability.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;See, the beauty of these 4GL-ish &lt;sup id=&quot;fnref-1&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; tools was that they boosted the productivity of the single developer by creating a set of abstractions over the common platform of the time (that is, Windows). Each could build a user interface (windows, buttons, scrollbars, etc), each had durable storage (that is, relational or even non-relational tables), each had a reasonably useful &amp;quot;default&amp;quot; architecture (data binding from the window to the back-end table), and each was able to deploy reasonably easily. A single developer could, if they chose, sit down, scope out a problem, code it up, and put it on another machine within a timeframe that was measured in weeks (or months if it was really complicated).&lt;/p&gt;
&lt;p&gt;As a C++/Windows developer (and later Java) during that same timeframe, building something similar often was a much more onerous task. We had greater access to the underlying platform, to be sure--all of the Windows API was ours to invoke, we had dozens if not hundreds of C/C++ libraries we could build off of, and our frameworks (MFC, OWL) certainly helped take some of the heavy lifting off of our shoulders--but for speed of execution/delivery, nothing ever really beat out the rapid delivery of somebody&apos;s favorite 4GL.&lt;/p&gt;
&lt;p&gt;Oh, we&apos;d argue about it, for sure. I distinctly remember during my days at DevelopMentor when we C++ guys &amp;quot;battled&amp;quot; (all good-naturedly, of course) the VB guys about which platform was better. One guy likened it to playing golf: The C++ golfer, upon declaration that he was about to shoot 18 holes, would immediately begin by obtaining foam, wood, and metal, so that he could fashion his own set of golf clubs, meticulously tuned to the course he was about to play. He might observe the VB golfers out already on the course, each of them with their two-club golf set (consisting of a 3-iron and a putter, for reasons that remain obscure), and mutter to himself, &amp;quot;Just wait until I get out there, they won&apos;t stand a &lt;em&gt;chance&lt;/em&gt; against me!&amp;quot; while milling the 2.5-iron&apos;s club head so that it slopes &lt;em&gt;just so&lt;/em&gt; (for the third time, the previous two having been a little too steep or a little too curved).&lt;/p&gt;
&lt;p&gt;We laughed.&lt;/p&gt;
&lt;p&gt;But the analogy here to the LLM-based coding agent feels pretty strong: Where we C++ developers had a high degree of control&lt;sup id=&quot;fnref-2&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; over the code we were writing, at least when compared to VB, today&apos;s &amp;quot;hand-tuned&amp;quot; option is to write the Python or Ruby or other code, well, by hand, as opposed to letting an agent spew it out for you. Just as many VB developers didn&apos;t really understand what was happening &amp;quot;under the hood&amp;quot; of their favorite language, though, the developer who simply relies on the coding agent is going to run into problems when they need to know what&apos;s happening &amp;quot;down below&amp;quot;.&lt;/p&gt;
&lt;p&gt;Although....&lt;/p&gt;
&lt;p&gt;Quite honestly, I think the analogy isn&apos;t quite perfect, comparing VB to coding-agent-generated code. In many respects, it&apos;s much closer to the much more obscure &amp;quot;C++-targeted code transpiler&amp;quot; that was briefly &amp;quot;a thing&amp;quot; for about eighteen months or so. You see, these tools allowed you the same kind of drag-and-drop, table-backed development experience that VB or FP or Delphi offered, with the added benefit that what you were building turned into C++ code! This was touted as a feature, because it (a) made integration with other C++ code and libraries easier, (b) yielded the kind of performance that C++ code could offer, and (c) allowed you to peek under the hood and see all that comforting C++ code! Heck, (d) you could stop using the builder and just go straight to the IDE and edit the C++ code like it was a typical hand-authored C++ project.&lt;/p&gt;
&lt;p&gt;Except....&lt;/p&gt;
&lt;p&gt;Even here the analogy is missing one aspect, and that&apos;s the non-deterministic nature of the LLM-based coding agent. Yes, in theory, with a tight enough specification and a low-enough temperature (or consistent random seed, I guess), you could get an agent to generate the same code consistently for the same prompt, but it seems doubtful that that&apos;s going to be the norm. A given agent could, perhaps, ship with a fine-tuned model with those randomness factors turned low (or off), but right now the trend seems to be shipping the harness with &amp;quot;plug-in models&amp;quot;, which would mean the coding agent user would either have to build a new model with the new parameters (a la Ollama Modelfile) or fine-tune one.&lt;/p&gt;
&lt;p&gt;And let&apos;s not forget, by the way, that &lt;a href=&quot;https://dev.to/mame/which-programming-language-is-best-for-claude-code-508a&quot;&gt;which language you use matters&lt;/a&gt; when using a coding agent--the dynamic languages seem to work better with Claude Code, for example. Other agents might turn in different results, but so far we don&apos;t seem to have enough experience to judge apples to apples. My point being, in comparison with thirty years ago, the language coming out &lt;em&gt;behind&lt;/em&gt; the tool may matter more than it did in the past, when the &amp;quot;Basic vs Pascal&amp;quot; debate between VB developers and Delphi developers was basically shoved off to the side because on that axis the C++ developers would jump up and claim victory &lt;sup id=&quot;fnref-3&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; In every one of these debates, there were always two more people present: One Smalltalker, who would insist that theirs was the OG tool that all those other 4GLs were desperately trying to copy, unsuccessfully, they would add, and the one Lisper, who would insist that everybody was wrong and it was all about building abstractions upon abstractions upon abstractions.... Turns out they were both right, but hey, who&apos;s keeping score?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I think we&apos;re going to find, particularly as we go down the path of coding agents and specification-driven development, that &lt;strong&gt;&lt;em&gt;the coding agent is more akin to the VB development surface than anything we&apos;ve had since 1998/99,&lt;/em&gt;&lt;/strong&gt; which of course was when the Web debuted and made all those desktop applications &amp;quot;obsolete&amp;quot;. Nothing in the &amp;quot;Web Era&amp;quot; since has given us that single-developer kind of vibe--building an app even as far back as 2000 meant one team building out the HTML (and later JS and CSS), another team building out the database schema, a third building the &amp;quot;middleware&amp;quot; (servlets, HttpHandlers, session beans, whatever your platform called them), and a dedicated support team to keeping it all up and running on the server(s).&lt;/p&gt;
&lt;p&gt;Which then, interestingly enough, leads us to the next question: &lt;strong&gt;&lt;em&gt;What happens to all the teams of developers currently inside the modern corporate enterprise?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is where things, I think, take one of two possible paths:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The Innovation Center.&lt;/em&gt;&lt;/strong&gt; Any company that sees its IT as a source of innovation and value will immediately start looking at ways to magnify the impact of a single developer. Projects might be converted (don&apos;t ask me how, we&apos;re not there yet I don&apos;t think) to this new form of agent-based single-developer &amp;quot;owner&amp;quot; of the code, and the team members either taking on whole segments of the system alone, or the team as a whole owning a &lt;em&gt;much&lt;/em&gt; larger chunk of the code each. This will, of course, lead to a number of developers now being free to take on new projects, which now enables the company to pursue all of those projects that were sidelined or shelved until that day &amp;quot;when we have a team available&amp;quot;. Heck,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The Cost Center.&lt;/em&gt;&lt;/strong&gt; And, of course, any company that sees its IT as a cost center will immediately look to cut costs, by keeping the amount of IT productivity stable, but still expecting more productivity per developer, thus slashing any &amp;quot;extraneous&amp;quot; developers that aren&apos;t needed to meet the original productivity numbers. This is, by the way, where I expect most companies to go, because a lot of companies see their IT as cost centers rather than innovation centers, and will comfortably squat in this belief (all the way up until one or more of their competitors roar past them at the speed of sound).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But this all also implies an interesting &lt;em&gt;third&lt;/em&gt; path:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;The Renaissance.&lt;/em&gt;&lt;/strong&gt; Yup. When Italy suddenly was flush with cash thanks to its position as the main trade broker between Europe and East Asia, as well as its invention of double-entry accounting, and thanks to the recent fall of Constantinople and the waning of Church power and influence, a massive social movement dedicated to exploring what was known before the Dark Ages (particularly all things Greek and Roman) as well as a sudden excitement for the burgeoning investigation of science. Individuals, backed by patrons, suddenly found they had time and resources to do some very interesting things (like &lt;a href=&quot;https://en.wikipedia.org/wiki/Renaissance_art&quot;&gt;paint&lt;/a&gt;, &lt;a href=&quot;https://en.wikipedia.org/wiki/Printing_press&quot;&gt;read&lt;/a&gt;, or &lt;a href=&quot;https://en.wikipedia.org/wiki/Science_in_the_Renaissance&quot;&gt;explore flying machines&lt;/a&gt; ). If we think of agents as being that same kind of &amp;quot;execution lubricant&amp;quot;--that is, something that makes execution that was formally difficult, easy--&lt;strong&gt;&lt;em&gt;we can reasonably expect that we are about to experience a surge in creative new applications and ideas&lt;/em&gt;&lt;/strong&gt;. (Including, perhaps, games!)&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;I don&apos;t really want to get into a hot debate about what qualifies as a 4GL. I&apos;m using VB and (V)FP as the canonical exemplars of the genre, and if you feel like getting into a debate about what qualifies as a 4GL, you are free to do so on LinkedIN or somewhere. Maybe Reddit. Or Quora. Or, better yet, your own blog.&lt;/p&gt;
&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;Meanwhile, if you&apos;re still one of those programmers who used to argue with us &amp;quot;high-level&amp;quot; C++ developers because &amp;quot;nothing beats the performance and control of hand-crafted assembly language!&amp;quot;.... I&apos;m just not quite sure what to tell you at this point.&lt;/p&gt;
&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;And yeah, we ignored that one Assembly guy in the back of the room.&lt;/p&gt;
&lt;a href=&quot;#fnref-3&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

	</description>
    </item>
    <item>
      <title>Layoff Thinking</title>
      <link>http://blogs.newardassociates.com/blog/2026/layoff-thinking.html</link>
      <pubDate>Wed, 8 Apr 2026 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2026/layoff-thinking.html</guid>
      	<description>
	&lt;p&gt;LinkedIn has been awash in layoff stories for, God, it feels like forever now. But a recent post got me thinking about layoffs, and how some of our reactions are deeply visceral when others get laid off around us, and why it&apos;s such a deeply personal thing to be suddenly unemployed.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;First, &lt;a href=&quot;https://www.linkedin.com/posts/jillian-omalior_you-share-your-thoughts-about-the-oracle-activity-7447018090854326272-4FsO&quot;&gt;the post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The video does some interesting analysis around what the real cause of the layoff is (and I think she&apos;s right about that), but the text above the video reads, in part:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We are so conditioned to believe that we have no inherent worth in capitalism unless we are EARNING. So we outsource our own worth to the very privileged few who are seemingly doing capitalism &amp;quot;right.&amp;quot;&lt;/p&gt;
&lt;p&gt;You&apos;re worthy, I promise you. Struggle isn&apos;t necessary, poverty doesn&apos;t happen because you&apos;re lazy and entitled.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;... which got me thinking. &lt;em&gt;Why&lt;/em&gt; is it we take it so hard when we are separated from a company?&lt;/p&gt;
&lt;p&gt;In Western (American) society, we often place a great deal of our identity into what we do.&lt;/p&gt;
&lt;p&gt;Consider, for a moment, how we greet each other when strangers first meet: &amp;quot;Hi, what&apos;s your name? What do you do?&amp;quot; (In the Deep South, I&apos;m told the question is often, &amp;quot;What church do you go to?&amp;quot; while New Yorkers, I&apos;m told, ask &amp;quot;Where ya from?&amp;quot; meaning &amp;quot;Which of the boroughs do you live?&amp;quot; and answers of anything other than a New York borough is essentially discounted and heavily judged.) These questions, right out of the gate, are how we look to understand other people, meaning we are using them to understand that other person.&lt;/p&gt;
&lt;p&gt;In essence, these questions are what we use to establish our identity, our sense of selves, and how we represent that self both to others and to ourselves. It&apos;s ingrained into us as kids--in fact, it&apos;s a natural outgrowth of how, when we are children, we self-identify based on our school/grade/teacher which then leads naturally to college which then leads naturally to employer.&lt;/p&gt;
&lt;p&gt;Notice how &amp;quot;What do you do&amp;quot; is right up there, right after the name, even? We use that as a definition of who we are, to ourselves every bit as much as we do to others.&lt;/p&gt;
&lt;p&gt;Is it any surprise, then, that people take a layoff hard? Employers are &lt;em&gt;literally&lt;/em&gt; striking a hole at somebody&apos;s sense of self when laying them off. It&apos;s as deep of a blow as taking away their national identity or displacing them out of their culture.&lt;/p&gt;
&lt;p&gt;While I&apos;ve always enjoyed programming and making money as a programmer, I don&apos;t think I&apos;ve had that sense of &amp;quot;self&amp;quot; wrapped entirely in that concept of being a programmer. When everybody around me was a &amp;quot;Java developer&amp;quot; or a &amp;quot;.NET developer&amp;quot;, I was just &amp;quot;a developer&amp;quot;. Possibly because I&apos;ve spent a ton of time thinking about all the other things I could (and wanted) to do: fiction author, sommelier, dungeon master, game developer, and a few more to boot. Don&apos;t get me wrong, I love coding and I love learning about all this new tech stuff, but if I couldn&apos;t make money at it, I&apos;d do it on the side while making money doing whatever else. It&apos;s a weird thing to explain sometimes.&lt;/p&gt;
&lt;p&gt;My reason for bringing all this up? In the spirit of trying to console people by counseling actions to take: If you&apos;re experiencing a layoff, I think it critical to lean into all of the non-work parts of your self. Re-center your sense of identity &lt;em&gt;away&lt;/em&gt; from work. Hobbies. Family. Voracious consumer of urban fantasy romance slam poetry. Whatever. Take the chance to rebuild your sense of self around things that &lt;em&gt;aren&apos;t&lt;/em&gt; work, so that when you get back into work, you&apos;re never quite as vulnerable as you were before.&lt;/p&gt;
&lt;p&gt;In other words: You are way more than what you do. You have skills, insights, views, and probably a whole lotta love that you can offer. Your company said you have no worth to them? Fuck &apos;em. You have worth, just because. It sucks, yes, and it&apos;s important to grieve. Then get up and go wander the coffee aisle at the local grocery store, enjoying all the smells. Go watch kids in the park for a while. Swing on a swing like you did when you were five. Whatever. Be you. Reconnect with yourself, and realize that nowhere inside you is a company logo. You are &lt;em&gt;waaaaay&lt;/em&gt; more than just what you do, and that in of itself is &lt;em&gt;waaaaay&lt;/em&gt; bigger than where you do it.&lt;/p&gt;
&lt;p&gt;I don&apos;t know if that helps anyone else. But it kept me sane (and even a degree hopeful) during my three-year &amp;quot;involuntary sabbatical&amp;quot; a few years back.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Things I Think I Think... Preferring Local OSS LLMs</title>
      <link>http://blogs.newardassociates.com/blog/2026/titit-local-ai.html</link>
      <pubDate>Wed, 1 Apr 2026 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2026/titit-local-ai.html</guid>
      	<description>
	&lt;p&gt;While spending some time inside the company Slack, I mentioned that I wanted to try a particular tool but using locally-hosted LLMs rather than cloud-hosted ones. The response was basically &amp;quot;LULZ y would u want to do that&amp;quot; and not only was I a little surprised at the response, I realized I felt a strong desire to explain why, in a format more suited to a blog post than a Slack message.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;&lt;em&gt;(This is a part of my series of blog posts in which I muse out loud about the &amp;quot;things I think I think&amp;quot;. I find that writing out my thoughts helps me reecognize, categorize, and summarize them. If you find value in them, dear reader, I am happy, but keep in mind I am not really writing these to persuade or educate; in fact, it&apos;s fair to say I&apos;m not really writing them for you at all.)&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;Local-first LLMs&lt;/h4&gt;
&lt;p&gt;First, a quick clarification: When I talk about executing my AI infrastructure locally, as opposed to using the stuff in the cloud, I&apos;m generally referring to a stack that leans heavily into the open-source community, for the basic reason that locally-hosted commercial options are just nonexistent. I&apos;m not sure if this will change any time soon, but I actually don&apos;t see any reason why it would--after all, we&apos;ve essentially moved from a world where, 40 years ago, you bought a copy of Office and installed it locally onto your machine to today, where the commercial options are all cloud-hosted, and only open-source options (a la Libre Office) are available for local install. I suspect this has a lot to do with software piracy and the whole &amp;quot;how do I force people&apos;s local installs to behave differently whether or not they have given me money&amp;quot; and license keys and that whole thing--it&apos;s just a lot easier to not bother and host the commercial stuff online. I don&apos;t see that changing now, &amp;quot;soon&amp;quot;, or even &amp;quot;ever&amp;quot;.&lt;/p&gt;
&lt;p&gt;The other component to this, of course, is the hardware--you really need a hefty GPU card (or cards) in your machine to run an LLM that&apos;s on par with running one of the LLMs in the cloud. For the record, my gaming rig on my desk hosts an NVidia FeForce RTX 4090, which isn&apos;t all that bad considering it&apos;s at least a year old. It&apos;s not going to win any competitions against a Cray, of course, but it definitely will run LLMs much better than your average ChromeBook, that&apos;s for sure.&lt;/p&gt;
&lt;p&gt;And, for almost everything I&apos;m seeing in the LLM-based software stack, there&apos;s been some pretty fast congregation around the Anthropic API set, it seems. &lt;a href=&quot;https://ollama.com/&quot;&gt;Ollama&lt;/a&gt;, for example, can mimic Anthropic API to allow Claude Code to use it (instead of their native servers) by setting some local environment variables:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export ANTHROPIC_AUTH_TOKEN=ollama
export ANTHROPIC_API_KEY=&amp;quot;&amp;quot;
export ANTHROPIC_BASE_URL=http://localhost:11434
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... and then launching Claude with an Ollama model, a la &lt;code&gt;claude --model qwen3.5&lt;/code&gt;. Or, Ollama can handle a bunch of this detail for you, and you just run &lt;code&gt;ollama launch claude&lt;/code&gt; and it&apos;ll work out the rest.&lt;/p&gt;
&lt;h3&gt;Why&lt;/h3&gt;
&lt;p&gt;There&apos;s four main points that come to mind when I think on this topic:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Fallacies of Distributed Computing&lt;/li&gt;
&lt;li&gt;The Economics of 2020s AI Companies&lt;/li&gt;
&lt;li&gt;The Security of Hermitude&lt;/li&gt;
&lt;li&gt;The Ease of The Return&lt;/li&gt;
&lt;li&gt;The Clarity of Self-Hosting&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;The Fallacies of Distributed Computing&lt;/h4&gt;
&lt;p&gt;At 11:49am GMT on March 2, 2026, the unthinkable happened: Anthropic servers went down, and as a result, Claude Code was down. The &lt;a href=&quot;https://mashable.com/article/claude-down-ai-anthropic-outage&quot;&gt;world noticed&lt;/a&gt;, in large part because not only did productivity numbers go way down, but Solitaire scores went way up &lt;sup id=&quot;fnref-1&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;What many people learned--again, the hard way--is that Claude Code, like many systems, &lt;a href=&quot;https://www.adventureppc.com/blog/claude-code-down-in-2026-complete-status-guide-error-fixes-what-to-do-during-outages&quot;&gt;is a distributed system&lt;/a&gt;, and as such it will always be held hostage to the Fallacies of Distributed Computing:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The network is reliable;&lt;/li&gt;
&lt;li&gt;Latency is zero;&lt;/li&gt;
&lt;li&gt;Bandwidth is infinite;&lt;/li&gt;
&lt;li&gt;The network is secure;&lt;/li&gt;
&lt;li&gt;Topology doesn&apos;t change;&lt;/li&gt;
&lt;li&gt;There is one administrator;&lt;/li&gt;
&lt;li&gt;Transport cost is zero; and&lt;/li&gt;
&lt;li&gt;The network is homogeneous.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Again, these are eight assumptions that every distributed system developer makes at some point in their life, and any one of these assumptions usually ends up creating painful scenarios when the assumption is proven false, as they always are. Yes, networks have gotten better than they were twenty, or even ten, years ago, but they&apos;re still fallible, and that still doesn&apos;t prevent any of the other seven from creating problems.&lt;/p&gt;
&lt;p&gt;It&apos;s tempting to take the position of, &amp;quot;Well it doesn&apos;t happen that often, and besides, we even have WiFi on airplanes at 40,000 feet in the air, so...&amp;quot; but that essentially ducks responsibility for dealing with failure modes that can and often do happen at the most awkward times. When the Internet was young, we built systems that were essentially crippled if the network wasn&apos;t present, and over time &lt;a href=&quot;https://martin.kleppmann.com/papers/local-first.pdf&quot;&gt;developed&lt;/a&gt; &lt;a href=&quot;https://www.heavybit.com/library/article/local-first-development&quot;&gt;approaches&lt;/a&gt; to try and compensate for that. Then, of course, the mobile devices came along, and while we got excited about having actual CPU and storage available to us on the device (most of which we put towards games), we quickly got back to building applications that couldn&apos;t run when there was no network, only to make the same realization that we really still needed to have a good fallback plan in the event the network wasn&apos;t available.&lt;/p&gt;
&lt;p&gt;Now, as we see companies building more and more &amp;quot;AI-powered&amp;quot;/&amp;quot;agentic&amp;quot; applications, we discover pretty quickly which ones are essentially wrappers around calls to the OpenAI or Anthropic AI models running in the cloud. Keep in mind, if you&apos;re doing this, you&apos;re not just basing your uptime on the uptime that OpenAI or Anthropic can manage--you&apos;re also basing your uptime on the uptime of their Internet provider, the cloud host they&apos;re running in, the telecom backbones between you and them, your local Internet provider, and even the uptime of your local Internet. (Looking at you, &lt;a href=&quot;https://www.trustpilot.com/review/www.comcast.net&quot;&gt;Comcast&lt;/a&gt;!) The point is, distributed systems are inherently more fragile than local ones.&lt;/p&gt;
&lt;p&gt;Which then leads me towards &amp;quot;If we can host the LLM model locally, then there&apos;s one less distribution link over which failures can bring the system to its knees.&amp;quot; This is, I think, going to be even more important in the months and years to come, because frankly having a single point of failure, no matter how much we protect against that failure, is almost always a bad idea &lt;sup id=&quot;fnref-2&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Not to mention it&apos;ll cost a whole lot less, which brings me to my next point.&lt;/p&gt;
&lt;h4&gt;The Economics of &amp;quot;AI&amp;quot; Companies&lt;/h4&gt;
&lt;p&gt;In a nutshell, I&apos;m absolutely convinceed the current marketplace of AI companies is a bubble, and I&apos;m absolutely convinced that the bubble is going to pop. It doesn&apos;t mean that OpenAI or Anthropic, or even Microsoft or Google or Amazon or Oracle, will go bankrupt. But that bubble popping is definitely going to have a massive ripple effect throughout the rest of the industry, and a whole lotta money that&apos;s been propping up some ridiculously unsustainable business assumptions is going to go up in smoke.&lt;/p&gt;
&lt;p&gt;I defer the in-depth discussion of why I think this to &lt;a href=&quot;https://www.wheresyoured.at/&quot;&gt;Ed Zitron&lt;/a&gt;; if you want a deep take on his latest thinking (as of this writing), check out &lt;a href=&quot;https://www.wheresyoured.at/the-subprime-ai-crisis-is-here/&quot;&gt;The Subprime AI Crisis Is Here&lt;/a&gt;. There is just no way I could explain it better than he does, but I will warn you: If you want to argue with him, you&apos;d better have at least a Bachelors in Economics or Finance, because he is not just hand-waving over the details.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://openai.com/index/testing-ads-in-chatgpt/&quot;&gt;first&lt;/a&gt; &lt;a href=&quot;https://help.ads.microsoft.com/#apex/ads/en/60343/0&quot;&gt;cracks&lt;/a&gt; are showing, by the way, and the only reason Anthropic hasn&apos;t openly floated the idea of ads in Claude is because they just recently and very aggressively &lt;a href=&quot;https://www.theverge.com/ai-artificial-intelligence/873686/anthropic-claude-ai-ad-free-super-bowl-advert-chatgpt&quot;&gt;mocked ChatGPT for it&lt;/a&gt;, which means they&apos;ve locked themselves out of that option for at least seven days (which is how long it &lt;a href=&quot;https://www.vuelio.com/uk/blog/how-long-does-a-news-story-last/&quot;&gt;takes us as a society to forget about stuff&lt;/a&gt;; check out &lt;a href=&quot;https://www.newslifespan.com/&quot;&gt;https://www.newslifespan.com/&lt;/a&gt; if you want to see more).&lt;/p&gt;
&lt;p&gt;But the crux of the situation is this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Any company involved in &amp;quot;AI&amp;quot; right now is spending way more than it&apos;s making.&lt;/li&gt;
&lt;li&gt;The gap is being made up by venture capital funding (or more creative accounting schemes).&lt;/li&gt;
&lt;li&gt;Venture capital funding and creative accounting are not indefinitely sustainable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;... which then leads us to the inescapable conclusion that either (a) the companies involved in &amp;quot;AI&amp;quot; are going to have to find ways to make their income exceed their expenditures, which means any dependents will also see their costs raise, which eventually finds its way to the consumers who are accustomed to getting everything for free, or (b) the whole system flies apart when the venture capital lubrication runs out. Or (c) some combination of (a) and (b), which will still cause a pretty major ripple of Bad Stuff (TM) to wash across the industry.&lt;/p&gt;
&lt;p&gt;All of which will be safe-harbored by those who are thinking about local-first LLM-hosted stacks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;EDIT, 6 April 2026:&lt;/strong&gt; The recent &lt;a href=&quot;https://www.theverge.com/ai-artificial-intelligence/907074/anthropic-openclaw-claude-subscription-ban&quot;&gt;Anthropic ban on OpenClaw&lt;/a&gt; is essentially shutting down the use of Claude subscriptions to run third-party harnesses like Open Claw; &amp;quot;Instead, if users want to use OpenClaw with Claude, they’ll have to use a “pay-as-you-go option” that will be billed separate from their Claude subscription.&amp;quot; There&apos;s a fair number of reasons they might do this, but one is definitely cost. This is an interesting development, to say the least.&lt;/p&gt;
&lt;h4&gt;The Security of Hermitude&lt;/h4&gt;
&lt;p&gt;Actually there&apos;s a third (er, fourth?) possibility that can generate cash for the AI companies, one which most SaaS companies have proven is entirely too tempting to ignore: (d) We sell your data to the highest bidder.&lt;/p&gt;
&lt;p&gt;Are you OK with each and every one of your conversations with ChatGPT suddenly being analyzed and sold off to advertisers who will now pepper you with ads for all those things you thought you were sharing with ChatGPT in confidence? Considering how many people use ChatGPT as &lt;a href=&quot;https://medium.com/the-point-of-view/we-fired-our-therapist-and-asked-chatgpt-to-fix-our-marriage-5da684ffec09&quot;&gt;marriage counselors&lt;/a&gt; and &lt;a href=&quot;https://www.cnn.com/2025/11/06/us/openai-chatgpt-suicide-lawsuit-invs-vis&quot;&gt;mental health experts&lt;/a&gt;.... I&apos;m not sure I&apos;d be comfortable with that.&lt;/p&gt;
&lt;p&gt;On a more corporate scale, though, if your company is currently baking Claude or other agents into the center of your decision-making or dashboarding process, you&apos;re essentially now trusting that at no point will all of that data flowing in and out of the LLM (&amp;quot;tokens&amp;quot;, remember) will at no point be considered the &lt;a href=&quot;https://www.economist.com/leaders/2017/05/06/the-worlds-most-valuable-resource-is-no-longer-oil-but-data&quot;&gt;&amp;quot;new oil&amp;quot;&lt;/a&gt; and sold to the highest bidder. And don&apos;t get me wrong! Anthropic would never consider doing that, just like Google will always be the company that adheres to its &lt;a href=&quot;https://en.wikipedia.org/wiki/Don%27t_be_evil&quot;&gt;&amp;quot;Do No Evil&amp;quot;&lt;/a&gt; motto that it told us over and over again was at the core of their corporate culture &lt;sup id=&quot;fnref-3&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; .&lt;/p&gt;
&lt;h4&gt;The Ease of the Return&lt;/h4&gt;
&lt;p&gt;And if it turns out that absolutely none of the scenarios I&apos;m imagining--not only do AI companies figure out how to make one USD of income cover ten USD of expenses, forever, but the Internet suddenly becomes a bastion of reliability and physics-defying performance--then it&apos;s actually a pretty simple switch over to using the cloud-based stuff.&lt;/p&gt;
&lt;h4&gt;The Clarity of Self-Hosting&lt;/h4&gt;
&lt;p&gt;Most of all, though, when you have to build your own stack, you learn things. Figuring out how to get Ollama going, figuring out which models I want hosted locally, figuring out how to get &lt;a href=&quot;https://openwebui.com/&quot;&gt;OpenWebUI&lt;/a&gt; or Claude or &lt;a href=&quot;https://opencode.ai/&quot;&gt;OpenCode&lt;/a&gt; or VSCode or &lt;a href=&quot;https://docs.ollama.com/integrations/n8n&quot;&gt;n8n&lt;/a&gt; or &lt;a href=&quot;https://docs.ollama.com/integrations/marimo&quot;&gt;marimo&lt;/a&gt; to work with it, figuring out the key differences between Ollama and &lt;a href=&quot;https://vllm.ai/&quot;&gt;vLLM&lt;/a&gt; or &lt;a href=&quot;https://github.com/ggml-org/llama.cpp&quot;&gt;LlamaCpp&lt;/a&gt;, all of these things are inherently educational and powerful ways to understand how all this shit works.&lt;/p&gt;
&lt;p&gt;Because truthfully, that&apos;s really where the real power rests: Knowing how to put these pieces together, so that now you can see all the wires and the data flows and what it looks like at rest and so on. Assuming that software developers are still going to be relevant and necessary even if we write less code (which suggests we&apos;re going to be moving into more architect-type roles than &amp;quot;code monkey&amp;quot; roles of the past), somebody still has to know how to wire it all up in such a way that it matches the company&apos;s goals and interests and concerns.&lt;/p&gt;
&lt;p&gt;And I want to be one of those &amp;quot;sombody&amp;quot;s.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;Actually, does anybody besides me still play Solitaire? What is it you kids use these days? Minesweeper? Grand Theft Auto? Something on your Steam deck? &lt;em&gt;shakes fist at clouds&lt;/em&gt;&lt;/p&gt;
&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;Which also explains why I&apos;m 150% a fan of government-sponsored space exploration and research. The sooner we can reduce our dependency on Earth-centric life, the more robust our species becomes in the face of potential dangers. But that&apos;s another topic for another day (and probably a few single-malt Scotches, to boot). If you want those thoughts early, catch me at a conference, plunk your quarter in the jukebox (i.e., buy me a Macallan, double, neat), and be prepared to listen through the whole playlist.&lt;/p&gt;
&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.the-independent.com/tech/google-dont-be-evil-code-conduct-removed-alphabet-a8361276.html&quot;&gt;Until it wasn&apos;t&lt;/a&gt;.&lt;/p&gt;
&lt;a href=&quot;#fnref-3&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

	</description>
    </item>
    <item>
      <title>Things I Think I Think... Disruption</title>
      <link>http://blogs.newardassociates.com/blog/2026/titit-disruption.html</link>
      <pubDate>Tue, 31 Mar 2026 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2026/titit-disruption.html</guid>
      	<description>
	&lt;p&gt;You know how the startup community loves to talk about &amp;quot;disrupting&amp;quot; industries? Well, thanks to the general magic of large language models, combined with the capitalist drive of huge VC-backed companies like OpenAI and Anthropic, we find ourselves not imposing one, but having one imposed on us. And I&apos;m pretty sure, we don&apos;t like it.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;&lt;em&gt;(This is the first in an anticipated series of blog posts, in which I muse out loud about the &amp;quot;things I think I think&amp;quot;. I find that writing out my thoughts helps me reecognize, categorize, and summarize them. If you find value in them, dear reader, I am happy, but keep in mind I am not really writing these to persuade or educate; in fact, it&apos;s fair to say I&apos;m not really writing them for you at all.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Over the past several months, I&apos;ve been responsible for spinning up a more formalized &lt;a href=&quot;/devrel/&quot;&gt;Developer Relations&lt;/a&gt; function within &lt;a href=&quot;https://nutrient.io&quot;&gt;Nutrient&lt;/a&gt;. On the surface of it, it&apos;s not a hard problem: They are a developer-facing product company, originally a developer who wrote a thing that people wanted to pay for, and grew. Their current product suite consists of selling document+workflow solutions, both libraries and server-hosted functionality, and they&apos;ve historically sold through inbound marketing leads (aka, &amp;quot;Our customers found us&amp;quot;). There&apos;s any number of things that we could start with; we could do some &lt;a href=&quot;/blog/2023/devrel-activity-ontology&quot;&gt;Reach&lt;/a&gt;-oriented activities, like &lt;a href=&quot;/devrel/activities/article&quot;&gt;Articles&lt;/a&gt;, &lt;a href=&quot;/devrel/activities/blog-post&quot;&gt;Blogs&lt;/a&gt;, or even spin up an &lt;a href=&quot;/devrel/activities/hackathon&quot;&gt;Hackathon&lt;/a&gt; or two, which could/would/should improve our inbound leads. Or we could do some &lt;a href=&quot;/blog/2023/devrel-activity-ontology&quot;&gt;Interactivity&lt;/a&gt;-boosting activities, a la an &lt;a href=&quot;/devrel/activities/ambassadors&quot;&gt;Ambassadors&lt;/a&gt;, or a few &lt;a href=&quot;/devrel/activities/conference-session&quot;&gt;Conference Sessions&lt;/a&gt;. Maybe even pair hard with the Sales team and so a bunch of &lt;a href=&quot;/devrel/activities/customer-pre-sale&quot;&gt;Customer Pre-Sales&lt;/a&gt; work.&lt;/p&gt;
&lt;p&gt;But the ugly part of this story is the simple fact that most of us are living in some degree of quivering. Whether with existential dread, anticipatory excitement, or outright ambiguity, we&apos;re all of us &amp;quot;on edge&amp;quot; because of the recent Rise of the LLM Coding Agents. There&apos;s some folks who are oozing a brazen confidence that &amp;quot;This is the new thing&amp;quot;, usually coupled with a sales pitch, either for their product or for their newsletter (as the most recent newly-self-christened Thought Leader, of course). Other folks exude the vibe of &amp;quot;I&apos;ve been there, it&apos;s slop, don&apos;t stress about it&amp;quot;. For a much larger percentage of us, it&apos;s creating some serious anxiety:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;Am I about to be layed off?&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Are my skills no longer useful?&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Why does my boss keep looking at me funny?&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Can coding agents really replace me?&amp;quot; (Note that this hits differently between the juniors and the seniors.)&lt;/li&gt;
&lt;li&gt;&amp;quot;Is this no longer a &apos;safe&apos; industry in which to be employed?&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That last one, by the way, hits really hard, because for the past twenty-five years, ever since the Internet made its mainstream debut, we&apos;ve all of us in this industry felt like we had a safe harbor in which to park our boats. Sure, yeah, we&apos;ve had our swells--the streets ran red in 2001 when 9/11 combined to create the &amp;quot;Dot-Bomb&amp;quot; Era, and again in 2008 when the sub-prime mortgage crisis triggered some financial fluctuation that claimed a lot of jobs. But for the most part, this industry has been seen as one of the &amp;quot;safest&amp;quot; in which to labor, particularly when compared to just about any other blue collar job, a la manufacturing.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Interestingly enough, in my &lt;a href=&quot;https://www.newardassociates.com/presentations/Keynotes/RethinkingEnterprise.html&quot;&gt;Rethinking Enterprise&lt;/a&gt; keynote, I use the line &amp;quot;Tell me the secret sauce, the magic pill, ... the &amp;quot;best practice&amp;quot;... that will help me stay employed for the forseeable future&amp;quot;. That one was about the shift from &amp;quot;enterprise&amp;quot; technologies to what we later called &amp;quot;microservice&amp;quot; technologies, and it was way less disruptive than what we&apos;re seeing now. But, still, it&apos;s the same merry-go-round, just... bigger and faster and with a lot more sharp places to land if you get thrown off.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There&apos;s a deep karmic element here, because for close to thirty years, we software folks have often been at the center of practicing &amp;quot;disruption&amp;quot; on all these other industries. Most recently, we were going to replace taxi drivers with autonomous vehicles (remember Waymo? Waze? Uber before they became a taxi service and food-delivery company?). We&apos;ve spent four decades replacing assembly-line workers with robots of one form or another, but even receptionists (both the front-desk and phone variety) are now commonly replaced by phone trees and kiosks. For three of those four decades, we&apos;ve inflicted &amp;quot;disruption&amp;quot; on other industries by putting them in front of a computer and some bespoke software we wrote in the name of &amp;quot;efficiency&amp;quot; and &amp;quot;cost savings&amp;quot; and expected them to go along with it willingly if not happily. When they protested that they would lose their jobs if they helped us as &amp;quot;subject matter experts&amp;quot; to get the software right, we told them &amp;quot;No way! You&apos;ll just get promoted now that you can do more&amp;quot; and beat for the door before the pink slip arrived. We confidently referred their questions about their future longevity to their boss so that we could avoid uncomfortable conversations. Besides, if they &lt;em&gt;really&lt;/em&gt; wanted to be in a career with longevity, they&apos;d teach themselves programming.&lt;/p&gt;
&lt;p&gt;Say it with me: EYE-roh-nEEEEEEE....&lt;/p&gt;
&lt;p&gt;This, folks, is what it feels like to be &amp;quot;disrupted&amp;quot;. It&apos;s a maelstrom of chaos and anxiety. Nobody&apos;s quite sure what&apos;s happening next. Whose jobs are safe. Whose are in danger. Where the high ground is in order to avoid the flood that we all feel coming, that deep rumbling within the earth beneath us. What new language or tool do we need to learn? Should we learn to build our own models? Which coding agent is the &amp;quot;best&amp;quot; (meaning, which one will outlive the others and survive) to learn (because if I can help it, I only want to learn one)?&lt;/p&gt;
&lt;p&gt;A number of years ago, back in 2007, Alan Greespan (the Chairman of the Fed during the Boom Times) wrote his memoir, &lt;em&gt;The Age of Turbulence&lt;/em&gt;, in which he described how the US has historically been able to bend and adjust to the &amp;quot;whirlwinds of creative destruction&amp;quot; that periodically strike:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Creative destruction is the principal driving force of economic progress, the “perennial gale” that uproots businesses—and lives—but that, in the process, creates a more productive economy. With rare exceptions the only way to increase output per hour is to allocate society’s resources to areas where they will produce the highest returns—or, in more formal language, to direct society’s gross domestic savings (plus savings borrowed from abroad) to fund cutting-edge technologies and organizations. Creation and destruction are Siamese twins. The process involves displacing previously productive assets and their associated jobs with newer technologies and their jobs.&amp;quot; (p. 13)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is one of those times, and if you&apos;re one of those &amp;quot;previously productive assets&amp;quot; about to be &amp;quot;displaced&amp;quot;, man, it becomes hard to keep faith in capitalism. A more productive economy is all well and good, but when the &amp;quot;good&amp;quot; seems to go to all the people at the top, and it seems the &amp;quot;well&amp;quot; just keeps getting deeper and deeper around you.... Yeah suddenly maybe &amp;quot;the economy&amp;quot; isn&apos;t quite as important as it once was.&lt;/p&gt;
&lt;p&gt;But if there&apos;s a silver lining to the whole idea, it&apos;s that this &amp;quot;creative destruction&amp;quot; leaves more opportunity behind it than it guts on its path through the world:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;A striking number of the machines that have revolutionized productivity look like improvised contraptions. Cyrus McCormick’s threshing machine, described by the London Times as a cross between a flying machine and a wheelbarrow,7 helped to produce a 500 percent increase in output per hour for wheat and a 250 percent increase in output for corn from its invention in 1831 to the end of the nineteenth century. In the process, it helped to displace as much as a quarter of the world’s agricultural labor force. In 1800, a farmer working hard with a scythe could harvest only a single acre in a day. By 1890 two men using two horses could cut, rake, and bind twenty acres of wheat in the same time.&amp;quot; (p.15)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That reduced the total agricultural labor force, but also increased the available labor pool within cities, wherein a much greater set of opportunities lay, and helped create the pool of people that we would now call &amp;quot;the labor force&amp;quot;. More subtly, though, their offspring (once we established child labor laws) would congregate within public schools, gain an education that far exceeded what they would have received living in their small towns and farms, and would go on to become what we now refer to as &amp;quot;the middle class&amp;quot;.&lt;/p&gt;
&lt;p&gt;Lots of people like to use the example of how the car replaced the horse. In fact, though, the horse&apos;s eventual replacement by machinery was much trickier and more complex than that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;It can take a long time for a new technology to change an economy: the spread of Samuel Morse’s telegraph was complicated by the size of the country and the difficulty of the terrain. Though telegraph wires quickly blanketed the East Coast and the more densely inhabited parts of the West Coast, giving people access to almost instant communications, the center of the country remained an information void. In the late 1850s, it still took more than three weeks to convey a message from one coast to the other by a combination of telegraph and stagecoach. Sometimes old technologies can work in tandem with new ones: starting in 1860, the Pony Express, with its riders leaping from one horse to another fresh one, reduced the time it took to get a message across the country to under ten days. The ponies were much more flexible than more advanced methods of transport such as wagons or trains: riders could ride up steep ravines and negotiate narrow trails.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;quot;But Ted,&amp;quot; some will argue, &amp;quot;By 1910 we had cars, and poof, no more horses.&amp;quot;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;The Nation magazine addressed the paradox of the popularity of the horse in the age of steam in October 1872:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Our talk has been for so many years of the railroad and steamboat and telegraphy, as the great “agents of progress,” that we have come almost totally to overlook the fact that our dependence on the horse has grown almost pari passu with our dependence on steam. We have opened up great lines of steam and communication all over the country, but they have to be fed with goods and passengers by horses. We have covered the ocean with great steamers, but they can neither load nor discharge their cargoes without horses.11&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;quot;For several decades America’s equine population grew more than twice as fast as its human population, from 4.3 million horses and mules in 1840 to 27.5 million in 1910. That meant that the ratio of horses and mules to people increased over seventy years of pell-mell progress from one to every five humans to one to every three. People used horses to drive mills, pull plows, walk alongside canal boats, herd cattle, fight battles, and above all, carry burdens for short distances. It took the combination of three kinds of power to displace horses from the heart of the American economy. Steam power replaced horses for long-distance hauling. Electric power replaced them for urban transport. And “horseless carriages” replaced them for short hauls.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;quot;But Ted, this is different. It&apos;s more like electricity, when it was introduced.&amp;quot;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Four decades after Thomas Edison’s spectacular illumination of Lower Manhattan in 1882, electricity had done little to make the country’s factories more productive. Introducing electricity was not just a matter of plugging factories into the electricity grid. It involved redesigning entire production processes and replacing vertical factories with horizontal ones to get the best out of the new power source.&amp;quot; (p. 17)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And, point of fact, many companies around the turn of the last century had &lt;a href=&quot;https://www.google.com/search?q=chief+electricity+officers&quot;&gt;&amp;quot;Chief Electricity Officers&amp;quot;&lt;/a&gt;, whose job was to manage the infrastructure and use of electricity within the company.&lt;/p&gt;
&lt;p&gt;And today, companies are hiring &amp;quot;Chief AI Officers&amp;quot;, often from the same pool from which we hired &amp;quot;Chief Data Officers&amp;quot; just a half-decade ago. (Nobody&apos;s saying what happened to our &amp;quot;Chief Blockchain Officers&amp;quot;, though, which is weird... you think they&apos;re OK?)&lt;/p&gt;
&lt;p&gt;My point here is really one of faith: That yes, this is another one of those whirlwinds of creative destruction, and it&apos;s scary as hell. This is what living in the middle of the maelstrom looks like. And if we lean into the analogy of the storm, recognize that there&apos;s some point at which everything will suddenly become quiet and still, like you suddenly see how everything works together and how it&apos;s all going to work out--which means you&apos;re in the eye, and it&apos;s about to get a whole lot worse because you&apos;re only halfway through it.&lt;/p&gt;
&lt;p&gt;But storms do pass, eventually, and in clearing away whatever was there before, we have a chance to rebuild and do something entirely new and different, or the same thing but better now that we have the opportunity/requirement to rebuild. It&apos;s not always fun--in fact, it&apos;s very often the very opposite of fun. It&apos;s scary, it&apos;s panic-inducing, it&apos;s the very definition of stress in that it&apos;s worrying about something over which we really have zero control.&lt;/p&gt;
&lt;p&gt;Unfortunately, as with many things in life, it &lt;strong&gt;&lt;em&gt;is&lt;/em&gt;&lt;/strong&gt;, and wishing it weren&apos;t isn&apos;t going to help anything or anyone.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Things I Think I Think... About Touching Code</title>
      <link>http://blogs.newardassociates.com/blog/2026/titit-touching-code.html</link>
      <pubDate>Tue, 31 Mar 2026 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2026/titit-touching-code.html</guid>
      	<description>
	&lt;p&gt;It&apos;s been suggested that, as a natural consequence of the coding agent evolution, as coding agent adoption rises, the amount of time developers will spend working directly with code will either quickly or slowly approach zero. Despite some reasonable analogies that would suggest it, I don&apos;t agree, because of the nature of how LLMs work and what we expect out of code.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;&lt;em&gt;(This is a part of my series of blog posts in which I muse out loud about the &amp;quot;things I think I think&amp;quot;. I find that writing out my thoughts helps me reecognize, categorize, and summarize them. If you find value in them, dear reader, I am happy, but keep in mind I am not really writing these to persuade or educate; in fact, it&apos;s fair to say I&apos;m not really writing them for you at all.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;While I was in &lt;a href=&quot;https://www.newardassociates.com/events/2026/vslive-vegas.html&quot;&gt;Las Vegas for VSLive!&lt;/a&gt; two weeks ago, I got into some conversations with some of the other speakers, many of whom I&apos;ve known for several decades. As most would expect, talk turned to the subject of &amp;quot;AI&amp;quot; and coding agent tools, and how they&apos;re changing the way we work. Or not. Or replacing us. Or not. Or trying to replace us and failing miserably. Or not.&lt;/p&gt;
&lt;p&gt;Yeah, it was a pretty lively Speaker Room, no question about that. We&apos;ve all known each other too long to be drawn into &amp;quot;fights&amp;quot;, per se, but we definitely have our opinions, and while I agreed with some, I definitely disagreed with others. One of those places where I strongly disagree is with the opinion that &amp;quot;In time, developers will never see the C#/Java/Python/whatever, because the coding agent will take care of it all.&amp;quot;&lt;/p&gt;
&lt;p&gt;The analogy frequently cited here is that of the compiler. Back in the day when &amp;quot;developer&amp;quot; meant &amp;quot;writing assembly code by hand&amp;quot;, the introduction of &amp;quot;high-level languages&amp;quot; like Pascal and C &lt;sup id=&quot;fnref-1&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; generated a lot of pushback from developers who swore that they could generate far better code by hand than the compiler could. And, in all fairness, they often could! In fact, I would argue that anyone who has the 10,000 hours required to be an &amp;quot;expert&amp;quot; in the subject could, probably, come up with more efficient/optimized assembly output than the compiler would.&lt;/p&gt;
&lt;p&gt;It&apos;s just... going to take them a while to do so. And meanwhile, the modern C/C++ compiler is processing dozens, if not hundreds, of C files simultaneously and making sure all of them are correct and &amp;quot;bound well&amp;quot; (meaning, names and signatures match). The compiler can do a million things in the time it takes me as a human to do one of them.&lt;/p&gt;
&lt;p&gt;Coding agent can generate code... well, maybe not a million times faster than a human, but at least on par with the human. Even if the agent never gets faster than the human, we can spin up more agents much more easily than we can spin up more humans. Development team scaling problem, solved!&lt;/p&gt;
&lt;p&gt;Except...&lt;/p&gt;
&lt;p&gt;Look, as I write this, I&apos;ve got Claude running in a terminal, trying (for the third time) to code up a Tic-Tac-Toe game in .NET 10 and Avalonia. Specifically, it&apos;s an experiment to see how well &lt;a href=&quot;https://github.com/Fission-AI/OpenSpec&quot;&gt;OpenSpec&lt;/a&gt; works as a means to drive a coding agent (I&apos;ve been using OpenCode and just now turned to see how Claude would do) in specification-driven development, both to test the system as well as to get some reps in on how to use this approach to building software. &lt;sup id=&quot;fnref-2&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;The first two times did not go well.&lt;/p&gt;
&lt;p&gt;In all fairness, I believe I understand why--I think the LLM ran out of context window in one case, and in the other I wasn&apos;t using the tool properly--but in both cases, the agent very confidently told me &amp;quot;I have implemented all of your features! It all works and runs great!&amp;quot; even though in another terminal window, doing the &lt;code&gt;dotnet run&lt;/code&gt; thing sometimes wouldn&apos;t even build, much less run, and when it did run, it either lacked the very functionality I told it to build (for some reason, it just could not figure out how to display a dialog when a game was won or tied), it did something different than I told it to do (it added a &amp;quot;New Game&amp;quot; button to the main window, not something I asked for), or in one frustrating span of a couple of hours, it simply displayed no main window at all.&lt;/p&gt;
&lt;p&gt;Being the developer that I am, and being the &amp;quot;I want to understand what&apos;s happening here&amp;quot; kind of developer I am, I cracked a peek into the generated code--in one case, it had laid out the scaffolding for creating the 3x3 grid of buttons to use as the game board... but hadn&apos;t actually created the buttons. Instead, it had a helpful comment, &lt;code&gt;// We will want to create the buttons later but for now focus on the core implementation&lt;/code&gt;, which is a helpful comment, if a bit misguided. I mean, I was asking it to build the GUI in this spec, what &amp;quot;core implementation&amp;quot; was it thinking it was working on if not the implementation of the GUI?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(As I write this, I keep having to go back to the Claude terminal window to answer &amp;quot;Do you want to make this edit to tasks.md&amp;quot;? even though every time I answer &amp;quot;Yes, allow all edits during this session&amp;quot;. Even though the Claude terminal window very clearly reads &amp;quot;accept edits on&amp;quot;.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Thing is, the nature of an LLM is by definition one of probability, not deterministic output. An LLM is a neural network of tokens--at its simplest, a billions-large collection of &lt;a href=&quot;https://en.wikipedia.org/wiki/Markov_chain&quot;&gt;Markov chains&lt;/a&gt;--and the coding agent is using that to &amp;quot;guess&amp;quot; what the next (several (hundred)) token(s) will be. We can use weights to adjust the degree to which the LLM randomizes the next element in the chain, but because the chain has probability at the heart of it...&lt;/p&gt;
&lt;p&gt;... LLMs are, by nature, nondeterministic.&lt;/p&gt;
&lt;p&gt;This means that every time we run the coding agent and ask it to generate code, it will, by default, choose something that&apos;s either a little (or a lot) different from the next time we run it, or the time after that, or the time after that. In fact, one of the books I&apos;m tech-editing even goes so far as to suggest that developers using a coding agent should &amp;quot;just try again&amp;quot; if the first result generated isn&apos;t up to snuff &lt;sup id=&quot;fnref-3&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Nondeterminism is not something we&apos;re really &amp;quot;OK&amp;quot; with in code &lt;sup id=&quot;fnref-4&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;. If I can&apos;t trust the compiler to take my source and produce something consistently out of it, then a whole lot of our other infrastructure falls apart. For example, if one build passes all the tests, but the next one doesn&apos;t, even though nothing in the source (specification) has changed, is the thought process here that &amp;quot;We&apos;ll just keep deploying until we have one that works?&amp;quot; That seems awfully risky, particularly as the size of the things we&apos;re specifying grows.&lt;/p&gt;
&lt;p&gt;Here&apos;s what I mean by that: If a given agent has only a 0.01% chance of producing an erroroneous line of code per line of code, then in a 100-line program, it&apos;s a pretty good bet (99%!) that whatever the agent produces will work. But most software systems are much larger than 100 lines. Some reach to 10,000 lines, at which point probability states that you&apos;re going to get an error somewhere. Once we go to 100,000 lines, or even a million lines, though, now you have multiple errors cropping up, and the chances that you will get a &amp;quot;clean&amp;quot; build that you can deploy to production is essentially nil.&lt;/p&gt;
&lt;p&gt;BUT, that doesn&apos;t mean that the agent isn&apos;t useful in generating the code, IF you have people who can go in and smooth out the five or ten or a hundred places where the errors are occurring. Doing this, though, means having humans in on the action and knowing what&apos;s being written well enough such that they can wade into a particular place in the code, understand enough of what&apos;s going on to diagnose the problem, fix it, and extract themselves. Developer, meet code.&lt;/p&gt;
&lt;p&gt;In a lot of ways, this is actually reminiscient of what we&apos;ve always known about code: You&apos;ll write it once, but read it a hundred or more times. Which was always the argument for why code should be formatted a certain way, designed a certain way, variables named a certain way, and so on. &lt;strong&gt;&lt;em&gt;Minimizing the cognitive load to understand a section of code was always a high priority for human-authored code.&lt;/em&gt;&lt;/strong&gt; One would think we would want to carry that forward into the coding-agent era, particularly since in this new world I will be wading into code that, by definition, I&apos;ve never seen before.&lt;/p&gt;
&lt;p&gt;Another speaker in the room pointed out the very true fact that just as coding agents are nondeterministic, so are humans. &amp;quot;We seem OK with humans writing code, and they&apos;re not producing the same thing each time, why should we care about what the coding agent cranks out?&amp;quot; Which, again, I&apos;m not opposed to the coding agent to (a) go away or (b) be useless. The more common/mainstream the thing you&apos;re asking the agent to code up, the more likely the agent will do so with some level of success.&lt;/p&gt;
&lt;p&gt;But it won&apos;t generate the code the same way given the same inputs, and that&apos;s deeply worrisome. Forget the regulatory requirements that many business (health, financial, e-commerce, etc) labor under, let&apos;s just consider the engineering infrastructural parts of the discussion. If I can&apos;t be certain that &amp;quot;spec&amp;quot; will yield &amp;quot;implementation&amp;quot; that will ensure it&apos;s using database connection pools, parameterized database queries, sanitized inputs, and so on, then either I can&apos;t trust agent-generated code at all and need to throw the idea/tool away (which would not endear me to the accountants or the board), or I need to always &amp;quot;have a human in the loop&amp;quot; to make sure that the resulting output is correct.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;SIDE NOTE: Interestingly enough, the lack of determinism in humans was what spawned the now-ubiquitous use of unit tests to ensure that the code does what it claims it does. As techniques for achieving its stated goal go, automated testing is a really powerful one on the list. Perhaps part of the trick is to have a spec that is well-defined enough (using, dare I say, maybe, a DSL or even programming language?) that the coding agent can code up unit tests out of the spec. Or, perhaps, the trick is to have the developers write the unit tests that the coding agent must respect and pass without modification before it can declare victory. That can help--but at the cost of developers writing code again, and what&apos;s worse, writing the part of the code that historically they&apos;ve never enjoyed writing. I&apos;m not sure this is a &amp;quot;win&amp;quot; for anybody.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Axiom:&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;Developers will always need to be able to read and write high-level language code.&lt;/strong&gt; The language may be C#, Java, Python, or even C/C++, but they&apos;ll need to know how to work well within them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Corollary:&lt;/strong&gt; &lt;em&gt;The amount of code we write vs read will remain consistent, or tip a little bit more towards &apos;read&apos;.&lt;/em&gt; Yes, the agents can generate code way faster than humans can, no argument. But theoretically, the agent will get commonly-written code right more often, and warrant less human scrutiny on those parts, so the relative balance between &amp;quot;read&amp;quot; and &amp;quot;write&amp;quot; will remain roughly constant.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Remaining open question(s):&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Will we need the same number of developers (proportionally speaking) as we used three years ago? Probably not, but it&apos;s hard to say for sure. Going into and coming out of COVID was such a market-muddling event, it skewed lots of things in very extreme ways, making it a little unreasonable to draw as a &amp;quot;norm&amp;quot; to which we will return. That said, though, the Internet disruption of thirty years ago vastly accelerated the demand for developers, so that&apos;s a reasonable inference as well.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;I find it just incredibly tickling to think that the language that was designed to be a &amp;quot;portable assembly language&amp;quot; was, in its day, considered &amp;quot;high level&amp;quot;. Don&apos;t get me wrong, it totally is, compared to every assembly language I&apos;ve ever laid eyes on, but considering how people today grumble and compain about C++, much less C.... &lt;em&gt;hee, hee&lt;/em&gt;&lt;/p&gt;
&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;I should mention, because it might be relevant, I chose Tic-Tac-Toe primarily because it should be something that agents can understand pretty quickly and easily, and so therefore I&apos;m minimizing the variables involved in the experiment. Also, just for the record, as I have &lt;a href=&quot;/blog/2026/titit-local-ai&quot;&gt;documented elsewhere&lt;/a&gt;, I prefer running local LLMs rather than cloud-hosted ones.&lt;/p&gt;
&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;Something about how now the context window incorporates the failed effort and the LLM can learn from that and produce a better result.&lt;/p&gt;
&lt;a href=&quot;#fnref-3&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-4&quot;&gt;
&lt;p&gt;Interestingly enough, one of the other speakers in the room piped up with, &amp;quot;The C# compiler is non-deterministic, you know.&amp;quot; Which floored me--the very nature of a compiler is to be deterministic, what the hell? Marcel even pointed out that the C# compiler provides a &lt;code&gt;Deterministic&lt;/code&gt; option in the project file, a la &lt;code&gt;&amp;lt;Deterministic&amp;gt;true&amp;lt;/Deterministic&amp;gt;&lt;/code&gt;. Now, Marcel is usually nowhere close to being full of shit, so I assumed he was right that the option existed, but WTH is it turning off? Google is your friend here: &lt;a href=&quot;https://www.google.com/search?q=C%23+compiler+nondeterministic&quot;&gt;&amp;quot;By default, the C# compiler produces non-deterministic output. The resulting assembly includes elements like a timestamp and a randomly generated Module Version ID (MVID), which cause the binary content to differ across compilations even if the source code is identical.&amp;quot;&lt;/a&gt; Which... yeah, that&apos;s not really non-determinism, but sure, you get points for pointing out something I didn&apos;t know. Next round&apos;s on me, buddy.&lt;/p&gt;
&lt;a href=&quot;#fnref-4&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

	</description>
    </item>
    <item>
      <title>2026 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2026/2025-tech-predictions.html</link>
      <pubDate>Thu, 1 Jan 2026 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2026/2025-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;It&apos;s that time of the year again, when I make predictions for the upcoming year. As has become my tradition now for almost two decades, I will first go back over last years&apos; predictions, to see how well I called it (and keep me honest), then wax prophetic on what I think the new year has to offer us.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;In the large, 2025 was... well, damn. Last year at this time I wrote, &amp;quot;We thought 2023 was tumultuous, but then 2024 said, &apos;Hold my beer.&apos;&amp;quot; and I find myself wanting to repeat the phrase all over again. I can&apos;t quite put my finger on what is happening, but finding myself wanting to repeat these phrases over and over again suggests that either there&apos;s a larger social element at work here (I solemnly swear I am NOT going to bring up politics), or else I&apos;ve entered my &amp;quot;Grumpy Old Man&amp;quot; era. Or, possibly, both. Either way, 2025 was an &amp;quot;interesting&amp;quot; year, where &amp;quot;interesting&amp;quot; is that word you use when you really don&apos;t know what other word to use.&lt;/p&gt;
&lt;p&gt;Just when the tech market felt like it was just maybe, sorta, starting to make sense, the whole &amp;quot;AI will replace developers!&amp;quot; thing kicked into high gear and threw us all for a wild loop. LinkedIN was bad in 2024? LinkedIN 2025 said, &amp;quot;Hold my beer. And, you know, here&apos;s my car keys and cellphone too--this is going &lt;em&gt;hyper&lt;/em&gt; cray-cray.&amp;quot; Companies were hiring. Companies were laying off. Jobs were lost to AI. No, turns out they weren&apos;t lost to AI, but lost because companies were losing money on AI projects. No, they were making money on AI projects, just not where people could see it. No, that was a lie.&lt;/p&gt;
&lt;p&gt;You know how that Ancient Chinese Curse says, &amp;quot;May you live in interesting times&amp;quot;? Welcome to the most interesting times of my lifetime, anyway. Now you know why the Ancient Chinese considered that a curse and not a blessing.&lt;/p&gt;
&lt;p&gt;Let&apos;s take that look back in the mirror and see what I said a year ago and how close--or off--I was.&lt;/p&gt;
&lt;p&gt;As per previous years, I&apos;m giving myself either a &lt;strong&gt;+1&lt;/strong&gt; or a &lt;strong&gt;-1&lt;/strong&gt; based on a purely subjective and highly-biased evaluational criteria as to whether it actually happened (or in some cases at least started to happen before 31 Dec 2025 ended). If you want to skip to the new predictions, &lt;a href=&quot;#2026&quot;&gt;scroll down&lt;/a&gt; to the next major heading.&lt;/p&gt;
&lt;h2&gt;In 2025, I wrote ...&lt;/h2&gt;
&lt;p&gt;... even more stuff than in 2024, it seems, but that&apos;s often because there&apos;s so many parallel threads that it&apos;s hard to stay focused. I&apos;ll try harder this time around. But let&apos;s start with some of the personal (and therefore easy to score) stuff.&lt;/p&gt;
&lt;h4&gt;Our book will ship! (&lt;em&gt;p&lt;/em&gt; 0.9)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Seriously! It will! I promise!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt;: As I write this (on December 31st, 2025), I can only say that we got &lt;em&gt;so&lt;/em&gt; close. But we didn&apos;t get it slid in under the wire--we&apos;re still iterating on proofs with the publisher. That said, we do have a &lt;a href=&quot;https://link.springer.com/book/9798868818943&quot;&gt;publisher page&lt;/a&gt;, and we can take pre-orders, and....&lt;/p&gt;
&lt;p&gt;Yeah, OK, no, we didn&apos;t ship. &lt;strong&gt;-1&lt;/strong&gt;. But, on the other hand....&lt;/p&gt;
&lt;h4&gt;Maybe I&apos;ll have a full-time gig again? (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Three years and counting. I wouldn&apos;t mind the &amp;quot;enforced retirement&amp;quot; so much, were it not for all these people coming around my place, telling me I owe them money.... Fortunately I keep finding the odd thing to do every so often, but it&apos;d be nice to not have to answer questions that start with &amp;quot;Tell me of a time when....&amp;quot;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt;: &lt;strong&gt;+1&lt;/strong&gt;. I picked up some consulting work at Capital One during the summer of 2025, and that in turn transformed into a full-time engagement at Capital One, so yay! Employment! Oh, and yay for a win in the predictions, but more, yay for employment!&lt;/p&gt;
&lt;h4&gt;I&apos;ll start either a YouTube channel or some video training (&lt;em&gt;p&lt;/em&gt; 0.4)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;The probability goes up if I don&apos;t have something full-time landed by the end of January.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt;: &lt;strong&gt;-1&lt;/strong&gt;. I got distracted by a few things, and then the consulting thing popped up. Sorry not sorry and all that.&lt;/p&gt;
&lt;h4&gt;I&apos;ll speak at a brand-new (to me) conference (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;I have no idea which one, but I&apos;d love for some suggestions and/or requests. I love the shows I hit regularly, but I wouldn&apos;t mind going someplace entirely new and talking to people who&apos;ve never heard me speak before.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt;: &lt;strong&gt;-1&lt;/strong&gt;. Nope. Didn&apos;t happen. Still want it to, though, so this&apos;ll carry over into 2026.&lt;/p&gt;
&lt;h4&gt;&amp;quot;Developers are obsolete&amp;quot; prose will peak, then dwindle (&lt;em&gt;p&lt;/em&gt; 0.8)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Look, let&apos;s be honest: Lots of people have a vested interest in seeing software development&apos;s &amp;quot;hold&amp;quot; over the creation of software broken. Startup founders desperately want to believe they don&apos;t need a CTO or any of those really expensive &amp;quot;full-stack&amp;quot; people to build out their idea. Non-FAANG tech-adjacent companies look at their labor costs and think, &amp;quot;Do we &lt;em&gt;really&lt;/em&gt; need to have all these expensive people on our payroll?&amp;quot; AI venture capitalists (who want to see their investment make fortune quickly, so they can bail and reap the high stock price) want people to buy into the idea that AI can replace... pretty much anybody... without waiting for actual evidence of the success of replacing humans with AI. It&apos;s all going to hit a fever pitch this year, as the &amp;quot;pro-AI&amp;quot; crowd tries to drown out the growing surge of &amp;quot;anti-AI&amp;quot; evidence, then the bubble will burst, the AI startups will start to collapse, and the VCs will start hunting up their next hype to invest-pump-dump.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; My, goodness, I guess I got half of that right. The &amp;quot;developers are obsolete&amp;quot; prose definitely hit a high note in 2025. I mean, some people took real swings at it with articles like &lt;a href=&quot;https://generativeai.pub/the-junior-developer-extinction-were-all-building-the-next-programming-dark-age-f66711c09f25&quot;&gt;&amp;quot;The Junior Developer Extinction: We’re All Building the Next Programming Dark Age&amp;quot;&lt;/a&gt;. And, in some ways, yeah, the correction/caveats came right with it, such as what we see in that very same article: &amp;quot;Recent studies tell contradictory stories. PwC’s 2025 Global AI Jobs Barometer found that productivity growth nearly quadrupled in AI-exposed industries since 2022, rising from 7% to 27%, while a major Danish study of 25,000 workers across 7,000 workspaces found that AI chatbots “had no significant impact on earnings or recorded hours in any occupation” — with users saving just 3% of their time on average. ... Meanwhile, Microsoft research involving over 4,000 developers found that those using GitHub Copilot achieved a 26% increase in productivity, and Nielsen Norman Group studies suggest productivity gains as high as 126% for coding tasks. But here’s the kicker: according to the 2024 DORA report, speed and stability have actually decreased due to AI, and Uplevel’s quantitative study found that using Copilot didn’t result in productivity improvements but did increase the rate of bugs produced.&amp;quot;&lt;/p&gt;
&lt;p&gt;Can someone please make it all make sense? Developers using AI are going slower, yet companies are reporting higher productivity metrics, yet companies are reporting failed AI projects in numbers we&apos;ve (literally) never heard of for a technology that still remains so popular and strategy-centric. It&apos;s baffling! It&apos;s bonkers! It&apos;s &lt;em&gt;cray-cray&lt;/em&gt;! And it&apos;s not like the people writing about it aren&apos;t trying to make sense of it all; again, from that same article: &amp;quot;Meanwhile, The New Stack’s 2025 developer survey found that &apos;developers have become even more cynical and frankly concerned about the return on investment of AI in software development.&apos; The honeymoon period is ending, and reality is setting in.&amp;quot;&lt;/p&gt;
&lt;p&gt;Except... that the reality is having a hard time setting in. LinkedIN, that finger-on-the-pulse of professional movements, still feeds me quotes and citations and examples of companies who are &amp;quot;all in&amp;quot; on AI and AI coding tools and other &amp;quot;agentic&amp;quot; things. Tons of &amp;quot;AI influencers&amp;quot; (most of whom don&apos;t appear to have ever written code in their lives unless it was of the &amp;quot;vibe&amp;quot; variety) are breathlessly telling us of how the whole profession is changing. If you&apos;re getting the same kind of feed I am, it&apos;s obvious that there&apos;s still a TON of companies sinking an exorbitant amount of money into AI-related projects... even as a growing number of tech professionals (paraphrasing Fowler, Beck, and a few others) are telling us all to &amp;quot;calm down&amp;quot; and that &amp;quot;AI isn&apos;t replacing developers, but it can make developers more successful&amp;quot;.&lt;/p&gt;
&lt;p&gt;We&apos;ll come back to this in the 2026 predictions below, but I think that the dichotomous nature of what&apos;s happening here is explainable, and justifies me giving myself a &lt;strong&gt;+1&lt;/strong&gt; on this one.&lt;/p&gt;
&lt;h4&gt;AI startups are going to start failing (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;It may be this year, or it may be next year, but the AI venture-capital-gravy-train is about to run out. Fully 25% of all VC money went into &amp;quot;something something AI&amp;quot;, and it&apos;s eerily reminiscient of the &amp;quot;dot-com&amp;quot; years, when a huge percentage of all investment and VC money went into &amp;quot;something something Internet&amp;quot; and gave us such wonderful profit-avoidant monstrosities like &amp;quot;pets.com&amp;quot;. (Seriously. The sock puppet. It&apos;s all that&apos;s left of what was one of the most trumpeted startups in the early 2000s.) But eventually, your business has to actually make money (even you, Sam Altman), and when the profits aren&apos;t there, the shutdowns follow.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt;: I guess it all depends on how you classify &amp;quot;failing&amp;quot;. First off, yes, &lt;a href=&quot;https://www.wearefounders.uk/top-10-startup-failures-of-2025-so-far/&quot;&gt;there were failures&lt;/a&gt;; in fact, &lt;a href=&quot;https://techstartups.com/2025/12/09/top-ai-startups-that-shut-down-in-2025-what-founders-can-learn/&quot;&gt;more than a few failed&lt;/a&gt;. Builder.ai was the classic con-man game, calling it AI but secretly operating humans in the background, but it wasn&apos;t always that simple. Rain AI (&amp;quot;revolutionary AI chips&amp;quot;) took that classic line of &amp;quot;let&apos;s put the software thing into a chip&amp;quot;, and like it&apos;s Lisp- and Java-flavored predecessors, collapsed. And, yes, lots of startups fail, but these were some pretty big ones with some pretty sizable players backing them in some pretty large ways.&lt;/p&gt;
&lt;p&gt;It&apos;s important to call out that some of this was due to the environment, not the tech: When the VCs handed out money to (literally) everybody in 2020/2021, those companies had a 2-3 year runway, which, if you do the math (and add in an extra year of &amp;quot;emergency/bridge funding&amp;quot;), ends somewhere in 2023-2025 timeframe. They had to make good on their business, or die trying.&lt;/p&gt;
&lt;p&gt;But the complete collapse of a startup isn&apos;t the only way it fails; Google, for example, did a &lt;a href=&quot;https://www.joinpavilion.com/blog/what-windsurfs-exit-says-about-startup-culture-in-2025&quot;&gt;talent-acquisition play&lt;/a&gt; with Windsurf, which raises the question, &amp;quot;If Windsurf fails in 2026, is that because the market isn&apos;t there, or because the company didn&apos;t execute, or because the company&apos;s &lt;a href=&quot;https://jomasego.medium.com/what-happened-to-windsurf-20297b7d9b14&quot;&gt;key executors were scooped out&lt;/a&gt;?&amp;quot;&lt;/p&gt;
&lt;p&gt;The bloodbath isn&apos;t over yet, I don&apos;t think, but that&apos;s for the 2026 section. For now, I&apos;m going to call this a &lt;strong&gt;+1&lt;/strong&gt; because we definitely see some AI-centric startups that looked impregnable suddenly collapse.&lt;/p&gt;
&lt;h4&gt;ARM is going to start eating into Intel in a huge way (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;In the beginning, there was the x86. And Intel rode that line into massive, generational-spanning profits. But slowly, over time, the ARM chip architecture has been slowly but steadily eroding the bulwark that x86/x64 erected (&amp;quot;You&apos;d have to recompile everything! Nothing would run out of the box! Dogs and cats will merge to form a master race that will enslave humanity!&amp;quot;), such that by the end of 2024, not only was any shipping device without a built-in keyboard running ARM internally, Microsoft had a version of Windows running on the ARM chip. This upcoming year, there&apos;s literally no barriers left to ARM&apos;s complete dominance of the CPU market. The &amp;quot;Apple Silicon&amp;quot; MacBooks were just the vanguard in the horde of new ARM-based laptops that are going to come out and essentially take over. (As a caveat, if you&apos;re a native-language developer, as in you use C, C++, Swift, Rust, Go, Nim, Zig, and so on--if you&apos;ve not started learning what ARM assembly looks like and behaves, now&apos;s a good time to start learning it.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt;: &lt;a href=&quot;https://learn.microsoft.com/en-us/windows/arm/overview&quot;&gt;Windows. On. ARM.&lt;/a&gt; &lt;strong&gt;+1&lt;/strong&gt; That&apos;s the final strut keeping the avalanche away from the ski lodge that is Intel&apos;s x86/x64 business. The numbers aren&apos;t there yet (if you can find any!), with some folks calling 2025 sales of Windows/ARM PCs to be around 10-15% of new laptop sales, but the &lt;a href=&quot;https://www.webpronews.com/arm-based-windows-laptops-thrive-in-2025-amid-fierce-competition/&quot;&gt;signs are there&lt;/a&gt; that this is going to heat up soon. Intel&apos;s going to do everything it can to try and staunch the bleeding, but they&apos;ve now reached the official &amp;quot;This is the moment it all went to shit&amp;quot; demarcation point.&lt;/p&gt;
&lt;h4&gt;Java and C# aren&apos;t going to introduce anything significant (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Look, I&apos;ve been saying this for a few years now, and I&apos;m going to make this the last year I do so, but these languages are so mainstream right now that nobody (except for conference speakers, who constantly mine the feature lists for &amp;quot;What&apos;s New&amp;quot; talks for the coming year) really (a) pays much attention to their &amp;quot;v.Next&amp;quot; featureset, or (b) cares. The price of mainstream status is a desire for &amp;quot;sustainability&amp;quot;, which means most Java shops are not moving versions unless it&apos;s an &amp;quot;LTS&amp;quot; release, and most .NET shops are in the same mindset. (BTW, most iOS shops have lost track of all the new &amp;quot;bright shiny&amp;quot;s that Swift keeps getting, and what&apos;s worse, each release seems entirely incompatible with the previous.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt;: I&apos;m giving myself a &lt;strong&gt;+1&lt;/strong&gt; solely because when I asked nine colleagues (some from Java, some from C#) what the new features of Java or C# were, they couldn&apos;t remember. Considering these are folks that, like me, used to track the new upcoming release info religiously, I&apos;m taking that as a sign that both these platforms are, in a lot of ways, &amp;quot;done&amp;quot;. Not &amp;quot;done&amp;quot; meaning &amp;quot;dead&amp;quot;, but &amp;quot;done&amp;quot; meaning, &amp;quot;There&apos;s just not a lot that I desperately want the implementors to introduce&amp;quot;.&lt;/p&gt;
&lt;h4&gt;TypeScript jumps the shark (&lt;em&gt;p&lt;/em&gt; 0.6)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;The TypeScript language started life as an attempt to add a strongly-typed type system to the JavaScript ecosystem, in order to provide greater and greater up-front verification of code in order to get better errors earlier. (That&apos;s the general goal of any strongly-typed language, and while we can debate whether that&apos;s a good idea or not, what&apos;s not debatable is that a significant number of programmers buy into it, one of them being Anders.) But TypeScript also discovered that it could do a &lt;em&gt;lot&lt;/em&gt; of type-level things, and TypeScript has gotten more and more complex and complicated and confusing with each release. (I&apos;ve commented, elsewhere, that I lost faith in the language when the team chose not to create a language spec for it anymore, choosing instead to just say, &amp;quot;The code is the spec&amp;quot; and publish a new blog post with each release desribing new features in a casual and imprecise way.) This is the year (though it could be next year, although some have said it was already last year) that TypeScript starts compiling (or not compiling) expressions that absolutely confuse the hell out of anybody without a PhD in type theory. (For whatever it&apos;s worth, two years ago &lt;a href=&quot;https://dev.to/tylim88/series/20966&quot;&gt;somebody put together&lt;/a&gt; a list of &apos;WTF moments&apos;, and they&apos;re... interesting.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt;: Ehhh.....? When the language implementors announce that &lt;a href=&quot;https://devblogs.microsoft.com/typescript/typescript-native-port/&quot;&gt;they&apos;re rewriting the entire language in a different (entirely unrelated) language&lt;/a&gt;, it definitely begs some questions. Was the compiler performance really bad enough to justify this work? Will the new compiler be bug-for-bug compatible with the old one, particularly when there&apos;s no publicly-available specification to be able to verify against? And are the developers at Microsoft so enamored of Go that they deliberately avoided some of the other languages they could easily have used (C++, if you want the native compilation target or C#/F#, particularly in conjunction with some of the CLR AOT-to-native options, all these come to mind...).&lt;/p&gt;
&lt;p&gt;But again, truthfully? Name the last new language feature TypeScript introduced and tell me why it matters to you. Whether you agree with me on the &lt;strong&gt;+1&lt;/strong&gt; really rests on whether you can answer that with any degree of accuracy.&lt;/p&gt;
&lt;h4&gt;Python type hinting goes mainstream (&lt;em&gt;p&lt;/em&gt; 0.6)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Quietly, while nobody was looking for it, &lt;a href=&quot;https://peps.python.org/pep-0484/&quot;&gt;Python introduced &amp;quot;type hinting&amp;quot;&lt;/a&gt;, where Python code can be given Pascal-style type hints to parameters and return types, allowing tools like IDEs and editors to be able to provide better edit-time support. Most of the Python tutorials, it seems, ignored this for a while, but starting last year it seems the notion of writing type-hinted Python is becoming more and more acceptable to the Python community, though it seems that the majority of the community kept to &amp;quot;untyped&amp;quot; Python. My guess is, this is the year that the balance shifts, and &amp;quot;typed&amp;quot; Python begins to outweight the &amp;quot;untyped&amp;quot; Python. Legacy &amp;quot;untyped&amp;quot; codebases will of course exist for centuries to come, but I suspect that this coming year might be when companies start scouring their Python codebase and thinking, &amp;quot;Maybe we should put type hints in...?&amp;quot;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt;: It&apos;s hard to say, honestly. Lots of sample and demo code has sprung up using type hinting, and the coding-assistant tools love to slither it in to the code they generate, but are Pythonistas actually embracing it? Well, &lt;a href=&quot;https://engineering.fb.com/2025/12/22/developer-tools/python-typing-survey-2025-code-quality-flexibility-typing-adoption/&quot;&gt;Meta thinks so&lt;/a&gt;. &lt;a href=&quot;https://pyrefly.org/blog/why-typed-python/&quot;&gt;Pyrefly agrees&lt;/a&gt;. And hey, if &lt;a href=&quot;https://www.reddit.com/r/Python/comments/1nti5ar/why_todays_python_developers_are_embracing_type/&quot;&gt;Reddit agrees&lt;/a&gt;, it must be true, right?&lt;/p&gt;
&lt;p&gt;But I&apos;m not 100% sure I agree yet. Periodically I find interesting Python repos on GitHub that are relatively large and entirely absent any type hints whatsoever, and the rank-and-file Python developer (not to mention all the data science folks, who aren&apos;t programmers and don&apos;t necessarily see the reason for type hints) isn&apos;t always reflected in the blog posts, so.... &lt;strong&gt;-1&lt;/strong&gt;. I just don&apos;t feel comfortable claiming this as a correct prediction in 2025.&lt;/p&gt;
&lt;h4&gt;JetBrains tries very hard to push Kotlin Multiplatform (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;JetBrains put a ton of time and energy into KMP, and thus far it looks like there&apos;s been absolutely zero uptake from anyone outside of the building. If JetBrains is going to be able to call this any kind of success, they&apos;re going to need 2025 to be the year that KMP emerged as a credible competitor to React Native or Flutter.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt;: &lt;strong&gt;+1&lt;/strong&gt;. For starters, they took it to production status; for seconders, their blog was filled with comparisons to React Native and the iOS or Android native ecosystems. And, in some ways, it appears to have made something of an impact, as their own &lt;a href=&quot;https://www.snappmobile.io/kmp&quot;&gt;developer survey&lt;/a&gt; suggests that there&apos;s a non-trivial number of folks using it. (They survey was for 2024, but the analysis came out in 2025, so we have to take the data with at least a little salt.)&lt;/p&gt;
&lt;h4&gt;Flutter begins its quiet slide into obscurity (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Speaking of which, Flutter&apos;s going to start being quiesced by Google. First there was the layoffs (200-some people in October of last year), which signaled pretty strongly that Google&apos;s &amp;quot;done&amp;quot; with Flutter, all the PR statements notwithstanding. Then the &lt;a href=&quot;https://github.com/join-the-flock/flock&quot;&gt;community fork&lt;/a&gt; that came out of that news led a number of folks to think, &amp;quot;Wow, Google&apos;s &lt;em&gt;really&lt;/em&gt; done with Flutter&amp;quot;, since nobody would think to create a community fork of something that&apos;s being actively developed and maintained by the multi-trillion-dollar entity that created it. That makes the companies who make money on the things developers build (as opposed to those companies who make money on building things for developers) get &lt;em&gt;very&lt;/em&gt; nervous about adopting or continuing to invest in Flutter, and we can expect Flutter&apos;s usage numbers and interest level to plummet as a result. Yes, the open-source tools are there, and yes, people will continue to work on them, but hey by the way, how&apos;s the &lt;a href=&quot;https://parseplatform.org/&quot;&gt;Parse&lt;/a&gt; community looking these days? Or &lt;a href=&quot;https://loopback.io/doc/index.html&quot;&gt;LoopBack&lt;/a&gt;?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt;: &lt;a href=&quot;https://dev.to/3lvv0w/is-flutter-dying-in-2025-a-deep-dive-idm&quot;&gt;I wasn&apos;t the only one curious about this&lt;/a&gt;, and when that article asked, &amp;quot;Is Flutter dying?&amp;quot; it answered itself with &amp;quot;No. It&apos;s evolving.&amp;quot; That&apos;s a touch telling. On top of that, there&apos;s &lt;a href=&quot;https://getflocked.dev/&quot;&gt;Flock&lt;/a&gt;, which is a community-led fork of Flutter, which itself suggests some amount of uncertainty about Flutter&apos;s longevity (at least as a Google-sponsored/-backed effort). (Come on, you don&apos;t create a community fork of something if the company behind it is sending out strong signals and actions towards growth and sustainability.) I&apos;ve liked the technology for years, but given all this, it&apos;s hard not to see it beginning that quiet slide. &lt;strong&gt;+1&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;Swift will release a new version, and it will have incompatibilities (&lt;em&gt;p&lt;/em&gt; 0.8)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Like the rain in Seattle, Apple always releases a new version of Swift every year, and every year, there&apos;s something in there that&apos;s not backwards-compatible with the previous version. There is zero reason to expect that 2025 will be any different on that score.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt;: Swift 6.2 was released in September of 2025, and 6.1 in March, and 6.2 (bugs nothwithstanding) is compatible with 6.1, and 6.1 is &lt;em&gt;supposed to be&lt;/em&gt; compatible with 6.0, though the language implementors claim that some stricter enforcement of concurrent code may yield compilation errors in 6.1 that went through OK in 6.0. Still, these aren&apos;t deliberate breaking changes, in the grand scheme of things, so... &lt;strong&gt;-1&lt;/strong&gt;.&lt;/p&gt;
&lt;h4&gt;Rust will not replace C++ (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Oh, I know the downsides to C++. I really do. I programmed in the language for a half-decade (back in the &amp;quot;bad ol&apos; days of pre-C++08, waaay back in the late 90s), so I&apos;m well aware of all the dangers of pointers and what-not. But Rust isn&apos;t a high-level language, and there&apos;s way too much C and C++ code out there for companies to credibly consider rewriting all that code. We can ache and moan about computer security and stability all we like, but doing that rewrite is not a simple line-for-line replacement, precisely &lt;em&gt;because&lt;/em&gt; of the pointer guarantees that Rust enforces--all of those pointers have to be debated, decided, and declared, and it has to be consistent across multi-million-line codebases. Rust may make some inroads in getting new system-level development, but it&apos;s not going to make C++ &amp;quot;go away&amp;quot; any time soon, not this year or the next (or the one after that, or even the one after that).&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt;: Ohboy. &lt;em&gt;THIS&lt;/em&gt; one. I was pretty confident about this one, until... &lt;a href=&quot;https://thenewstack.io/microsoft-goes-all-in-on-rust-for-core-infrastructure-and-much-more/&quot;&gt;boom&lt;/a&gt; and &lt;a href=&quot;https://thenewstack.io/microsofts-rust-bet-from-blue-screens-to-safer-code/&quot;&gt;boom&lt;/a&gt;. Windows is a massive C/C++ codebase (though there&apos;s some other stuff in there too, to be sure), so if they&apos;re starting to replace the C/C++ code with Rust code, that&apos;s a pretty solid vote of confidence.&lt;/p&gt;
&lt;p&gt;Does this mean that C++&apos;s days are (finally) numbered and all those C++ devs should pack it in and learn... (um... what is the latest thing to learn again)? Probably not. Between the fact that the amount of C/C++ code in the world is ridiculously large enough to resist easy ports to anything, and the fact that Microsoft has done these sorts of &amp;quot;We&apos;re going to rewrite Windows in...&amp;quot; kinds of announcements before, let&apos;s give it some time before we count Rust as having successfully replaced C/C++ at Microsoft, much less anywhere else. But, it&apos;s definitely a turning point, and in fairness, I think it merits a &lt;strong&gt;-1&lt;/strong&gt;.&lt;/p&gt;
&lt;h4&gt;Odin, Nim and Zig will gain some attention (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;All of these are system-level languages in the tradition of C++ or Rust, and all of them are interesting in their own rights. I suspect some of the enthusiasm for Rust will get siphoned off into these, and before long the &amp;quot;Rust will replace C++&amp;quot; crowd will turn into the &amp;quot;Rust/Odin/Nim/Zig will replace C++&amp;quot; crowd, before they start fighting among themselves which of those four will do the replacing (because, of course, there can only be one, right?).&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt;: Well, Zig is definitely getting some airtime, for sure, particularly since it&apos;s what powers Bun, the high-performance JS runtime. Nim and Odin, though, seem to be trailing in popular usage, though each definitely has its ecosystem that is growing. Still, I look around and don&apos;t see any crowds chanting, so this gets me a &lt;strong&gt;-1&lt;/strong&gt;.&lt;/p&gt;
&lt;h4&gt;DIY databases will start gathering attention (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;There&apos;s been a quiet surge of interest in SQLite recently, since it ships pretty much everywhere (it&apos;s already on every mobile device on the planet, and its C codebase and bindings make it super-easy to FFI out to if there aren&apos;t already language-level bindings for your chosen language) and it&apos;s a pretty feature-complete subset of SQL-92. That&apos;s gotten a number of folks intrigued with the idea of &amp;quot;local database&amp;quot;-based functionality, which in turn has sparked some interest in &amp;quot;Wait, what exactly makes up a database, again...?&amp;quot; because if I can get the storage engine and bypass the SQL-ish query and talk directly to the query engine and.... Well, suddenly people are starting to wonder if the database has to be the black box we&apos;ve always assumed it to be. I think in 2025 we&apos;re going to start cracking it apart and doing a little plug-and-play of the components as part of, or behind, their service interfaces.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt;: I&apos;m not sure how I was expecting this to manifest, so I can&apos;t quite tell if I was right or wrong. SQLite is one of those things that&apos;s been around since forever (it&apos;s shipped on the device on both iOS and Android since each of their first release), and the fact that one can make use of it from within a browser in a variety of different ways (compile the SQLite source via emscripten to get a WebAssembly implementation directly, or use browser-native storage which is often implemented in SQLite, or use the port of SQLite to Javascript, and that&apos;s just three ways to approach the idea) makes it &lt;em&gt;really&lt;/em&gt; hard to track.&lt;/p&gt;
&lt;p&gt;But if we look at the intent of the prediction, what I was really going after was custom database implementations that would start gathering some interest, and I can&apos;t honestly say I saw much of that across 2025. &lt;strong&gt;-1&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;Final tally&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;ten wins (&amp;quot;+1&amp;quot;s)&lt;/li&gt;
&lt;li&gt;nine losses (&amp;quot;-1&amp;quot;s)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;... which puts me squarely in the middle of the bell curve. Good thing this isn&apos;t my day job!&lt;/p&gt;
&lt;h2&gt;2026 Predictions&lt;/h2&gt;
&lt;div id=&quot;2026&quot; /&gt;
&lt;p&gt;So now let&apos;s turn our head to 2026.&lt;/p&gt;
&lt;p&gt;As I do every year, each prediction comes with a probability factor (&lt;em&gt;p&lt;/em&gt;) that ranges anywhere from 0.0 to 1.0, with most predictions appearing in the 0.3 to 0.8 range. This is a trick I picked up from my International Relations days, where political prediction briefings often came with a similar kind of probability as a way of offering a &amp;quot;confidence&amp;quot; factor. Anything higher than a 0.8 means &amp;quot;We&apos;re pretty damn sure&amp;quot;, and anything less than 0.3 means &amp;quot;We&apos;re including it mostly out of completeness but we don&apos;t expect it.&amp;quot;&lt;/p&gt;
&lt;p&gt;But before we get started.... You know how I keep writing more stuff each successive year, and apologize for it the following year? Not even going to pretend this time around, this one could be the longest yet. (And, to no one&apos;s real surprise, it&apos;s all about AI! Because... &lt;em&gt;sigh&lt;/em&gt;) Brace yourself.&lt;/p&gt;
&lt;h4&gt;2026 AI predictions are going to be even wilder than 2025&apos;s (&lt;em&gt;p&lt;/em&gt; 0.8)&lt;/h4&gt;
&lt;p&gt;... because VC-backed startups need people to believe, so the VCs can exit the startups they&apos;ve backed.&lt;/p&gt;
&lt;p&gt;The landscape of the startup scene has been in the throes of a sea change for some time now, going back a few tech-generations (AI, blockchain, etc), and it goes like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Somebody, typically one of the folks with close ties to venture capital or Y Combinator, comes up with an idea. It doesn&apos;t have to be an actually accomplishable idea, it just has to be able to look remotely feasible and have some kind of sexy demo.&lt;/li&gt;
&lt;li&gt;The founder, through the VC&apos;s network, gets some tech press folks to do some interviews.&lt;/li&gt;
&lt;li&gt;Because the tech press is even more sensitive to &amp;quot;clicks&amp;quot; and &amp;quot;page views&amp;quot; than the regular press, offers up a soft-ball interview in which the idea is never deeply examined or questioned, but reinforced as &amp;quot;groundbreaking&amp;quot;. The founder is held up as an icon, deified, and memes about their daily workout routine become the staple of LinkedIN feeds.&lt;/li&gt;
&lt;li&gt;Other VCs, now desperate to jump on to a &amp;quot;winning thing&amp;quot;, immediately pony up some money.&lt;/li&gt;
&lt;li&gt;This reinforces the press coverage, as other tech press outlets immediately clamor for interviews. Trusting that the scrutiny has already been done (&amp;quot;I mean, if you&apos;re a VC, you wouldn&apos;t just put umpteen-million into it without doing a serious due diligence on it, right?&amp;quot;), they offer up even softer-ball interviews, and the deification takes root. This is &amp;quot;The Next Big Thing&amp;quot;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Unfortunately, as Theranos showed us, this basically has a predictable cycle:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The CEO/founder does a lot of press, and makes wild-eyed promises that the tech press eats up.&lt;/li&gt;
&lt;li&gt;As deadlines approach, the CEO soft-pedals back some of the promises, but makes other, lateral, promises as a way of showing how &amp;quot;on top of things&amp;quot; the company really is. &amp;quot;We&apos;re so close&amp;quot; becomes a common refrain, along with &amp;quot;We just need... to get there.&amp;quot;&lt;/li&gt;
&lt;li&gt;The company maybe IPOs, if it can&apos;t swing sweetheart deals with massive backers (lookin&apos; at you, Microsoft, Google, Amazon...).&lt;/li&gt;
&lt;li&gt;With each missed deadline, the CEO grows wilder in their predictions, and the needs grow more outlandish.&lt;/li&gt;
&lt;li&gt;At some point in all this, somebody gets an uneasy &amp;quot;Waaiiiitaminute&amp;quot; feeling, and starts digging through the data. Maybe they work there, maybe they don&apos;t, but they start piecing things together and prodding at the facade.&lt;/li&gt;
&lt;li&gt;Whispers start to echo across the blogosphere, and before too long somebody in the mainstream press with more of an investigative journalistic bent gets wind of it. They start doing research.&lt;/li&gt;
&lt;li&gt;LinkedIN memes and blog predictions, meanwhile, skyrocket.&lt;/li&gt;
&lt;li&gt;A news article or documentary effectively pointing out the lack of clothing on the supposed emporer&apos;s person comes out.&lt;/li&gt;
&lt;li&gt;Within days, the cards begin to collapse, and everybody in the tech industry nods along, as if they always suspected something from the beginning (even as they quietly mourn the deep losses they just took on their stock portfolio as the &lt;em&gt;wunderkind&lt;/em&gt;&apos;s company crumples).&lt;/li&gt;
&lt;li&gt;Fanbois continue to fanboi, of course.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&apos;s almost as if the tech industry made a deliberate decision to look at the Gartner Hype Curve not as a &amp;quot;lesson learned&amp;quot;, but as one of those Maps of the Hollywood Stars that must be slavishly followed over and over again.&lt;/p&gt;
&lt;p&gt;Meanwhile... We&apos;re in peak Inflated Expectations territory here with AI, folks. That means in order to keep the eyes off the bottom line, the predictions are going to only get wilder.&lt;/p&gt;
&lt;h4&gt;AI-based startups that use AI to mimic humans are going to crater--hard (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;... because humans keep anthropomorphizing AI, and keep believing that AI can do human-sensitive things better than humans can.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.allthingsdistributed.com/2025/11/tech-predictions-for-2026-and-beyond.html&quot;&gt;Werner Vogels thinks robots can help foster companionship&lt;/a&gt;; I deeply reject that premise, because humans have systematically rejected machines replacing humans in all but the most desperate of cases, and because cases where people have done so, &lt;a href=&quot;https://www.columbiapsychiatry.org/news/chatgpt-therapy-is-good-but-it-misses-what-makes-us-human&quot;&gt;missed the mark&lt;/a&gt; or &lt;a href=&quot;https://www.cnn.com/2025/11/06/us/openai-chatgpt-suicide-lawsuit-invs-vis&quot;&gt;ended badly&lt;/a&gt;. Humans can still tell the difference between machines and humans, even if they can&apos;t say why they know. Worse, if humans &lt;em&gt;suspect&lt;/em&gt; that the voice on the other end is a machine, they&apos;ll treat it wildly different.&lt;/p&gt;
&lt;p&gt;But that said, lots of startups are going to go down this path, and while they might get some traction to start, they&apos;ll crater hard when they try to scale out. Because we are all of us lonely, and having an always-available companion seems like the easier solution than actually building empathy and connection with other humans. Certainly the more profitable one, anyway. But the results... &lt;a href=&quot;https://www.youtube.com/watch?v=zkGk_A4noxI&quot;&gt;will not help people&lt;/a&gt;, only balance sheets.&lt;/p&gt;
&lt;h4&gt;OpenAI starts tying itself in knots to avoid having to make good on its promises (&lt;em&gt;p&lt;/em&gt; 0.6)&lt;/h4&gt;
&lt;p&gt;... because Sam Altman has made a lot of promises, and doesn&apos;t have a great track record of delivering on them (January 2025: &amp;quot;We know how to build Artificial General Intelligence&amp;quot;; November 2025: &amp;quot;Hey we got GPT-5.1 to use em dashes correctly when instructed (but not always)&amp;quot;), and 2025 saw OpenAI making even bolder promises. This is going to catch up to him in a big, big way.&lt;/p&gt;
&lt;p&gt;Look, Sam knows how to project confidence--every CEO does at that level, it&apos;s a prerequisite of the job at this point--but that doesn&apos;t mean he knows how to actually bring it forth to fruition. We&apos;ve all seen the &lt;a href=&quot;https://www.youtube.com/shorts/pB7faDHkHJI&quot;&gt;meme of the financial shell game&lt;/a&gt; that Microsoft, NVidia, OpenAI, and a few others are playing with &amp;quot;promises of investment&amp;quot;, or perhaps you&apos;ve watched the &lt;a href=&quot;https://www.youtube.com/watch?v=l0K4XPu3Qhg&quot;&gt;More Perfect Union video&lt;/a&gt;. But Sam&apos;s playing at &lt;a href=&quot;https://wlockett.medium.com/you-have-no-idea-how-screwed-openai-actually-is-8358dccfca1c&quot;&gt;an entirely new level&lt;/a&gt; with &lt;a href=&quot;https://www.wheresyoured.at/openai-onetrillion/&quot;&gt;trillions on the line&lt;/a&gt;, and you kinda have to wonder if he is resting much of his confidence on the idea that OpenAI is just &amp;quot;too big to fail&amp;quot; and can rely on government bailout in the event the piper does come calling.&lt;/p&gt;
&lt;p&gt;I&apos;m certainly no financial expert, and I don&apos;t claim to have the inside scoop on all the hallways of power back-room deals that OpenAI and SoftBank and all the other players are whipping up, but Altman&apos;s already backed away from so many deadlines and dates, before too long a lot more folks are going to notice, and you can&apos;t just keep selling whipped air forever. (See: Musk, Elon.) I suspect that in 2026, the shell games will come faster, the retrenching will come quicker, and I think Sam Altman is going to find himself at the center of a firestorm large enough to make Sam Bankman-Fried look like small potatoes.&lt;/p&gt;
&lt;p&gt;And with that, there&apos;s going to be a whole lotta finger-pointing and crashing.&lt;/p&gt;
&lt;h4&gt;Meanwhile, your electric bill is going to go up by at least 50% (&lt;em&gt;p&lt;/em&gt; 0.8), possibly more (&lt;em&gt;p&lt;/em&gt; 0.6)&lt;/h4&gt;
&lt;p&gt;... because all those data centers that AI needs are being built on taxpayer and utility customer dime.&lt;/p&gt;
&lt;p&gt;Next time your major urban city mayor is looking to &amp;quot;bring some jobs home&amp;quot;, ask them what the domestic cost will be--for example, if they bring in a data center (which largely runs itself, compared to an automobile plant or steel mill), ask them if &lt;a href=&quot;https://www.youtube.com/watch?v=YN6BEUA4jNU&amp;amp;list=PL1UE_u2gB0jlWarYdSufb-v-ld039CI2h&quot;&gt;your electric bills will go up&lt;/a&gt; as a result, and if they&apos;ll agree to put legislation in place to force the company building the data center to foot the additional rise if it does. It&apos;ll spark an interesting debate at the city council meeting at least.&lt;/p&gt;
&lt;p&gt;(Oh, and for bonus points, ask about not your utility bill, but the bill of the most impoverished part of your city. After all, data centers don&apos;t go into posh suburban neighborhoods, they go into wherever the land is the cheapest.)&lt;/p&gt;
&lt;h4&gt;&amp;quot;Vibe coding&amp;quot; is going to crater--hard (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;... because we have started to figure out software development is not about writing code, but understanding the problem well enough to be able to articulate what code to write.&lt;/p&gt;
&lt;p&gt;To understand the &amp;quot;why&amp;quot; of vibe coding, let&apos;s accept a couple of statements as axiomatic:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;Software is eating the world.&amp;quot;&lt;/strong&gt; --Marc Andreesen. &lt;em&gt;(Shouldn&apos;t come as a surprise to anyone, though at some point I hope that we realize that you can&apos;t eat software, and jobs like primary school education, plumbing, farming, and so on, are all pretty important to the continuation of Western society as we know it...)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;The demand for software is infinite, yet its supply is finite.&amp;quot;&lt;/strong&gt; --Neal Ford. To be precise, the demand for &lt;em&gt;new&lt;/em&gt; software is infinite--it&apos;s not that everybody wants copies of Microsoft Word, it&apos;s that everybody has ideas of something that will make Word completely obsolete and hey, you&apos;re a software developer, right, you could code it for me and we could split the profits 70-30 my way because of course it&apos;s my idea....&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Supplying new software requires some form of software development.&lt;/strong&gt; Canonically, this means hiring somebody who&apos;s accomplished with one or more programming languages. (We&apos;ll get to the alternatives in a moment, just hang on.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Learning software development is a non-trivial investment of time and money.&lt;/strong&gt; Historically, this has meant going off to get a Computer Science degree from some college or university, which is often a four-year investment. Some folks can do it in less time, others do it in a self-taught manner, but it&apos;s not like you can read one &amp;quot;For Dummies&amp;quot; book and suddenly know all of what you need to know about how to build a mobile app, API backend, database storage, security, cloud management, and user interface design. This non-trivial investment is a core reason why the &amp;quot;supply of software (development) is finite&amp;quot;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Given the above axioms, there&apos;s a simple conclusion that any macroeconomist can tell you about: As demand rises, if supply remains fixed, the equilibrium price goes up. This is why programmer salaries went through the roof during the original dotcom era--and have stayed there ever since, despite the setbacks we&apos;ve seen over the last three decades.&lt;/p&gt;
&lt;p&gt;However, one other axiom needs to be cited here to make all of it make sense:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Businesses will always seek to optimize to their most crucial metric: Profit.&lt;/strong&gt; This means maximizing their revenue while minimizing their expenses.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If your business is built on software, there&apos;s a strong probability that your biggest expense is... software developers. It used to be owning and operating all those big server farms that every company had tucked away someplace (usually at the center of the building behind glass walls because damn it looks impressive to potential investors to see row upon row of machines with blinky lights...), but the cloud took care of all that &lt;sup id=&quot;fnref-1&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. And, to be clear, software development labor has been a sizable part of most companies&apos; expense sheet for &lt;em&gt;(checks notes)&lt;/em&gt; three decades now, so the cloud thing helped some, but the original problem remains.&lt;/p&gt;
&lt;p&gt;So if you&apos;re a software development shop, how do you cut the expenses of your software developers?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;You look for ways to make software development faster.&lt;/strong&gt; After all, faster means fewer hours means less cost (because cost = hourly rate x hours). We see it, everywhere along the way, in the way that new programming languages are marketed, new tools are sold, or new practices are introduced. They might vary in their message, but everywhere, somewhere, there&apos;s a prominent tagline about &amp;quot;greater productivity&amp;quot;. Remember the 4GLs of the 90s?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;You look for ways to make software development cheaper.&lt;/strong&gt; &amp;quot;Hey, maybe if we go find software developers in countries with way lower standards of living, we can pay them less to do the same work.&amp;quot; Alternatively, we also saw the rise of &amp;quot;coding bootcamps&amp;quot; that promised to take people with no coding background whatsoever and turn them into software developers in just twelve months--no, nine--no, &lt;em&gt;six&lt;/em&gt;--no, no, you fools, &lt;strong&gt;&lt;em&gt;overnight&lt;/em&gt;&lt;/strong&gt;. Naturally, it gave rise to &lt;a href=&quot;https://www.jezebel.com/students-claim-a-west-virginia-nonprofit-promising-to-t-1834703462&quot;&gt;scams&lt;/a&gt; and &lt;a href=&quot;https://www.nytimes.com/2019/05/12/us/mined-minds-west-virginia-coding.html&quot;&gt;lawsuits&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;You look for ways to avoid software development entirely.&lt;/strong&gt; In macroeconomic terms, what substitute goods/services&lt;sup id=&quot;fnref-2&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; can we use to get what we need? In common parlance, this translates to &amp;quot;What if we use something that doesn&apos;t require software developers yet still builds software?&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If some of you are old enough to remember CASE tools in the late 80s or the UML tools in the late 90s, those were both plays to avoid software development, though in retrospect it&apos;s easy to see how neither one really dodged the basic need, which is &amp;quot;You have to understand the problem deeply enough to be able to figure out how the software should work to solve it.&amp;quot;&lt;/p&gt;
&lt;p&gt;Vibe coding is, in many respects, the Visual Basic of the 2020s: A tool that&apos;s designed to let &amp;quot;anybody&amp;quot; create software (thus neatly avoiding the high cost of software development) and finally slay the Dragon of Infinite Software Demand by allowing supply to run free, no longer burdened by the obstacle of knowing how software works.&lt;/p&gt;
&lt;p&gt;But, if you were paying attention two paragraphs back, you already know why vibe coding is failing: &amp;quot;You have to understand the problem deeply enough to be able to figure out how the software should work to solve it.&amp;quot; It&apos;s not that we don&apos;t have tools that can churn out millions of lines of code; the problem is that you need to know how to break the problem down into smaller pieces such that the AI coding tools can actually have a decent chance of generating code that will solve it. (Ironically enough, this is where most software development processes--whether AI-driven or not--run into issues.)&lt;/p&gt;
&lt;p&gt;The reason for the prediction? We&apos;ve had these &amp;quot;vibe coding&amp;quot; tools in our hands for a half-year or more now, and we&apos;re already seeing their limits. In 2026, they&apos;ll remain, but their use will be limited to building quickie prototypes, and there really isn&apos;t a market for tools that can only build quickie prototypes.&lt;/p&gt;
&lt;h4&gt;AI coding assistant tooling is going to gain momentum (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;... because AI&apos;s not gaining much steam anywhere else.&lt;/p&gt;
&lt;p&gt;The aforementioned AI startups are constantly trying to sell us on AI in HR, medicine, and finance, but honestly, after a year or so, it doesn&apos;t seem to be having much effect, and companies are starting to backtrack and re-trench. For starters, companies tried to use AI agents to do hiring, and that landed... &lt;a href=&quot;https://www.buzzfeed.com/meganeliscomb/ai-job-interview-glitches-tiktok&quot;&gt;poorly&lt;/a&gt;. Things really turned south when companies realized that candidates could do that too, and did. Maybe we can outsource other HR tasks... wait, &lt;a href=&quot;https://en.wikipedia.org/wiki/Up_in_the_Air_(2009_film)&quot;&gt;I think I&apos;ve heard that one before&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Likewise, AI&apos;s use in the legal space has... &lt;a href=&quot;https://www.npr.org/2025/07/10/nx-s1-5463512/ai-courts-lawyers-mypillow-fines&quot;&gt;problems&lt;/a&gt;. Sorry, Mike Lindell, you can&apos;t just hallucinate your way into proof of the 2020 stolen election! And he&apos;s &lt;a href=&quot;https://www.reuters.com/legal/government/judge-rebukes-minnesota-over-ai-errors-deepfakes-lawsuit-2025-01-13/&quot;&gt;not&lt;/a&gt; &lt;a href=&quot;https://www.lawnext.com/2025/05/ai-hallucinations-strike-again-two-more-cases-where-lawyers-face-judicial-wrath-for-fake-citations.html&quot;&gt;alone&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Turns out, lots of people get grumpy when AI just makes stuff up out of nothing (even &lt;a href=&quot;https://cdt.org/insights/the-sag-aftra-strike-is-over-but-the-ai-fight-in-hollywood-is-just-beginning/&quot;&gt;people who are paid to do exactly that&lt;/a&gt;), and that trend is only likely to continue. Which then, if you&apos;re in the AI business, where can you let the non-deterministic nature of generative AI fly in a space that&apos;s open to it, yet structured enough to not be hamstrung by it?&lt;/p&gt;
&lt;p&gt;Coding, of course. Programming languages require structure and conformance to form (minimizing the hallucination possibilities), particularly if backed by unit or integration tests, but also require some creativity in translating &amp;quot;problem&amp;quot; to &amp;quot;solution&amp;quot;. The coding agents have already had some measure of success--see the aforementioned &amp;quot;vibe coding&amp;quot;--but we&apos;re starting to understand their limitations--see the aforementioned &amp;quot;vibe coding&amp;quot;. In 2026, that curve is going to pick up steam, and we&apos;ll see it get stronger as the year goes by.&lt;/p&gt;
&lt;h4&gt;Specification-oriented development will gain traction (&lt;em&gt;p&lt;/em&gt; 0.6)&lt;/h4&gt;
&lt;p&gt;... because it captures a large part of the essence of programming.&lt;/p&gt;
&lt;p&gt;When Don Syme (he of the F# language) and John Lam (whom I&apos;m lucky to have worked with at DevelopMentor back in the day) both together started talking about &amp;quot;specification-oriented development&amp;quot;, it rattled my brain a bit. These are smart dudes, and if they think there&apos;s something there, enough to both blog and implement something around it, then I&apos;m curious by default.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.blog/ai-and-ml/generative-ai/spec-driven-development-with-ai-get-started-with-a-new-open-source-toolkit/&quot;&gt;&amp;quot;Spec Kit makes your specification the center of your engineering process.&lt;/a&gt; Instead of writing a spec and setting it aside, the spec drives the implementation, checklists, and task breakdowns.  Your primary role is to steer; the coding agent does the bulk of the writing.&amp;quot; On the surface of this, I like where this is going, because elevating the abstractions in programming is something that I&apos;ve been advocating for a very long time now. (We&apos;ve been surfing at the &amp;quot;object&amp;quot; level for three decades--what say we start re-thinking the problem again?)&lt;/p&gt;
&lt;p&gt;I&apos;m not 100% convinced that this is going to be the &amp;quot;path forward&amp;quot; for our programming, but it&apos;s pretty clear that some kind of LLM-driven engagement, whether through coding agents as part of an IDE, or through these &amp;quot;specification&amp;quot; files, is going to markedly color much of what we programmers do for the next few years. I think there&apos;s a fair amount of rigor in what&apos;s being suggested here, but at the same time, this is &lt;a href=&quot;https://dsyme.net/2025/08/27/on-natural-language-programming/&quot;&gt;flying in the face of some pretty well-established doctrine&lt;/a&gt;, and it&apos;s there&apos;s a pretty high mountain of evidence &lt;a href=&quot;https://www.cs.utexas.edu/~EWD/transcriptions/EWD06xx/EWD667.html&quot;&gt;against the idea of natural language&lt;/a&gt; as a deterministic way to write code.&lt;/p&gt;
&lt;p&gt;So this looks interesting, but I don&apos;t think it&apos;s going to take over the world yet. It&apos;ll capture some attention, it&apos;ll get some revision, it&apos;ll maybe spark something else that takes over the world, but somehow, it&apos;s going to get some traction over the next year. (What it really needs, though, is a good tutorial/walkthrough on how to use it, both for the simplest &amp;quot;Hello world&amp;quot; case and for a non-trivial example case. Right now the docs on the GitHub repo are a little vague in a lot of places.)&lt;/p&gt;
&lt;h4&gt;Languages will matter less than fundamentals and concepts (&lt;em&gt;p&lt;/em&gt; 0.6)&lt;/h4&gt;
&lt;p&gt;... because coding assistants can carry the weight of syntax better than humans can.&lt;/p&gt;
&lt;p&gt;This also means I&apos;m not making any generalized predictions about Java, C#, Python, Swift, or any of the other current crop of languages--there&apos;s simply little to no point, at least in 2026. They&apos;re still important, don&apos;t get me wrong, but their importance is now at more of a strategic level than a tactical one. (Meaning: CTOs and VPs won&apos;t care about which version of Java you&apos;re using, but will care about whether you&apos;re using Java as opposed to C# or Python.)&lt;/p&gt;
&lt;h4&gt;Micro-LLMs/Small Language Models (SLMs) gain traction for more widespread use (&lt;em&gt;p&lt;/em&gt; 0.6)&lt;/h4&gt;
&lt;p&gt;... because the Fallacies of Distributed Computing still hold, and servers making all these remote calls (over MCP) will slow down model responses, so we&apos;ll look for ways to bring them all together under one roof--which means having models small enough to execute locally.&lt;/p&gt;
&lt;p&gt;... because also, we&apos;re going to start realizing that we don&apos;t want &amp;quot;god&amp;quot; agents, because that increases the security risk. We&apos;re going to want agents that know how to do one thing and don&apos;t try to do anything else.&lt;/p&gt;
&lt;h4&gt;We will see a new crop of languages trying to incorporate natural language (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;... because we still desire determinstic behavior out of our programming languages.&lt;/p&gt;
&lt;p&gt;This is going to be the natural outcome of (a) more AI coding agent use, (b) SLMs gaining traction, and (c) a strong desire to &amp;quot;smash together&amp;quot; the agent into the IDE and then the language, which we see already in the aforementioned specification-oriented development. Programming languages have the ability to abstract away details we don&apos;t want to deal with (a la memory management or pointers), so it stands to reason that some enterprising language designer will figure out how to fold all of that into a text-based input scheme that has just enough rules to allow the agents to shine, while keeping the non-determinism out.&lt;/p&gt;
&lt;h4&gt;Quantum will gain traction (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;... because the computing power is there, we just need to figure it out&lt;/p&gt;
&lt;p&gt;I won&apos;t go too deep into the details here, but quantum definitely represents a massive leap forward in computing capability, and while your average video game has no need for it, lots of other applications do (including maybe future LLM models?), and it&apos;s too enticing to ignore. Somewhere before the end of the decade, we&apos;re going to start seeing developers working against quantum SDKs and using quantum languages, but don&apos;t ask me what they&apos;ll look like--I&apos;m having a hard enough time understanding the basic science of a qubit to start with!&lt;/p&gt;
&lt;h4&gt;Android starts to move in on laptops (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;... because Google wants it to, and mobile devices have long since become powerful enough to be laptop replacements.&lt;/p&gt;
&lt;p&gt;You know what the line is between a tablet and a laptop? Me neither.&lt;/p&gt;
&lt;p&gt;For years, laptops have tried to stave off the tablets by offering touch-based input (well, all of them except macOS, anyway), to varying degrees of success. Laptops had a few things going for them--larger screen sizes, more ports, an operating system that wasn&apos;t hamstrung by only being able to install things through the app stores, and so on. But over the last few years, we&apos;ve seen those things slowly evaporate (except for the &amp;quot;more ports&amp;quot;, which Bluetooh connectivity, wireless protocols, and dongle/hubs are making irrelevant for the most part), to the point now where many people get a larger iPad and a Bluetooth keyboard, and call that a laptop.&lt;/p&gt;
&lt;p&gt;The manufacturers feel it; it&apos;s why &lt;a href=&quot;https://www.howtogeek.com/seen-a-samsung-tablet-lately-its-like-buying-a-pc/&quot;&gt;Lenovo and Samsung have tablets that act like laptops&lt;/a&gt;. Google, meanwhile, &lt;a href=&quot;https://www.androidauthority.com/chrome-os-becoming-android-3500661/&quot;&gt;already announced&lt;/a&gt; that they want to do away with ChromeOS in favor of Android, and the work over the last year pretty much demonstrates that they&apos;re ready to start backing that with laptop or desktop hardware.&lt;/p&gt;
&lt;p&gt;Are you going to get Android on a desktop machine? Probably not--a good chunk of the rationale for a desktop purchase these days is gaming, and Android still isn&apos;t anywhere close to that world yet, with the other chunk of the rationale being development, which Android again isn&apos;t close to. (Although, if I&apos;m being frank, a good keyboard, a good monitor, a command-line prompt, and a half-decent editor, and Android&apos;s no worse than many Linux distros at that point.) Either way, it feels like the natural path is for Android to slide into the space that used to be occupied by ChromeOS, and that&apos;s through ChromeBooks, e.g., laptops.&lt;/p&gt;
&lt;h4&gt;iOS remains stale (&lt;em&gt;p&lt;/em&gt; 0.6)&lt;/h4&gt;
&lt;p&gt;... because Glass mode is just... uninspiring.&lt;/p&gt;
&lt;p&gt;Seriously. Apple tried really hard to make Apple Intelligence a thing, but in the end, all we&apos;re seeing is better and more cameras on the iOS devices, and frankly, &lt;strong&gt;&lt;em&gt;yawn&lt;/em&gt;&lt;/strong&gt;. One of their most recent commercials was showing how to use iPhones in cinematography. So we literally have Apple urging us to buy their product by making commercials on... making commercials.&lt;/p&gt;
&lt;h4&gt;Deepfakes will be the social nightmare that plagues us (&lt;em&gt;p&lt;/em&gt; 0.8)&lt;/h4&gt;
&lt;p&gt;... because they&apos;re good enough, and because some humans would rather work against other humans than for humanity.&lt;/p&gt;
&lt;p&gt;If &amp;quot;AI actors&amp;quot; are good enough to be considered for use by Hollywood (lookin&apos; at you, &lt;a href=&quot;https://en.wikipedia.org/wiki/Tilly_Norwood&quot;&gt;Tilly Norwood&lt;/a&gt;!), then it takes almost no thought at all to realize that she could very easily show up in a faked Zoom call, FaceTime, or news report. She and her cousins are going to be the source of scams, lies, and even deeper distrust of what we see on the screen.&lt;/p&gt;
&lt;p&gt;Ironically, it could be what gets us &lt;em&gt;off&lt;/em&gt; those screens, but let&apos;s see how it all plays out. Personally I think the growing &amp;quot;digital divide&amp;quot; is going to center on how much one bases their life on their digital footprint, and we could very well see Generation Alpha (or the one that follows it) utterly rejecting some of the lifestyle approach that Millennials and GenZ embrace because of all this. It will be very interesting to watch over the next decade or two.&lt;/p&gt;
&lt;h4&gt;I&apos;ll speak at a brand-new (to me) conference (&lt;em&gt;p&lt;/em&gt; 0.4)&lt;/h4&gt;
&lt;p&gt;I have no idea which one, but I&apos;d love for some suggestions and/or requests. I love the shows I hit regularly, but I wouldn&apos;t mind going someplace entirely new and talking to people who&apos;ve never heard me speak before. I&apos;m giving it a slightly lower probability because full-time work always makes this trickier, but it&apos;s still a goal.&lt;/p&gt;
&lt;h4&gt;Our book will ship! (&lt;em&gt;p&lt;/em&gt; 0.99)&lt;/h4&gt;
&lt;p&gt;I know, I know, but we&apos;re serious this time. We&apos;re in the final proofs-editing stage now, so the question is really whether it&apos;ll appear on shelves (figuratively) in February or March.&lt;/p&gt;
&lt;p&gt;As always, feel free to comment and tell me why I&apos;m crazy, in whatever forums feel comfortable. In the meantime, talk to you all next year... if not sooner.&lt;/p&gt;
&lt;hr /&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;Theoretically, anyway. We&apos;re starting to see that the cost of owning a virtual machine in the cloud isn&apos;t all that much better than it is to own it on-premises, which is leading a number of companies beyond a certain size to reconsider owning and operating their own data centers. It&apos;s still way better for smaller companies, where we can benefit from the margins that are gained from a big company running lots of servers, but at a certain size, it just doesn&apos;t make sense anymore.&lt;/p&gt;
&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.economicshelp.org/blog/glossary/substitute-goods/&quot;&gt;https://www.economicshelp.org/blog/glossary/substitute-goods/&lt;/a&gt;&lt;/p&gt;
&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

	</description>
    </item>
    <item>
      <title>DevRel Activity Patterns... published</title>
      <link>http://blogs.newardassociates.com/blog/2025/devrel-patterns-published.html</link>
      <pubDate>Sat, 11 Oct 2025 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2025/devrel-patterns-published.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Two years ago, I started creating a pattern language for developer relations activities, and I published an early draft of what they looked like to this website. In the time since, they&apos;ve been refined, expanded, and collected into a single paper volume, available from APress in December of 2025.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;The book, titled, &lt;strong&gt;&lt;em&gt;Developer Relations Activity Patterns: A Unified Approach to DevRel, DX and Community Management&lt;/em&gt;&lt;/strong&gt;, is visible &lt;a href=&quot;https://link.springer.com/book/9798868818943&quot;&gt;here&lt;/a&gt; and I believe available for pre-order. Amazon has it &lt;a href=&quot;https://www.amazon.com/Developer-Relations-Activity-Patterns-Management/dp/B0FJWPD3CQ/ref=sr_1_1&quot;&gt;here&lt;/a&gt;, for those who prefer the Amazon infrastructure, and the back cover blurb reads like so:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Developer relations (DevRel) go beyond just blog posts, conference talks, and clever tweets. It is a discipline grounded in intention, empathy, and consistent actions. This book outlines foundational strategies employed by successful DevRel teams in just 39 focused patterns.&lt;/p&gt;
&lt;p&gt;Using a tactical approach to effectively engage in developer relations, each pattern is based on real-world experience and designed for scalability. By using a pattern form to describe the various activities of developer relations in detail, the book clearly lays out the intention, shows how to create empathy with your audience, and provides a clear guide on how to execute it. Within this book, you&apos;ll discover how to extend your reach, enhance meaningful interactions, and align your initiatives with both developer communities and company strategy without compromising your values or experiencing burnout.&lt;/p&gt;
&lt;p&gt;Whether you&apos;re a solo advocate, managing a small startup team, or leading DevRel on a larger scale, &lt;em&gt;Developer Relations Activity Patterns&lt;/em&gt; is your practical playbook for refining strategy and amplifying your impact.&lt;/p&gt;
&lt;p&gt;You will:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gain a greater understanding of what developer relations means and the range of activities under its remit&lt;/li&gt;
&lt;li&gt;Learn the tools, approaches, and new tactics for developer community engagement&lt;/li&gt;
&lt;li&gt;Understand how and when to apply each tactic, based on your aims and objectives&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;For those who are curious, this is the culmination of the work started &lt;a href=&quot;https://blogs.newardassociates.com/blog/2023/devrel-activity-pattern-language.html&quot;&gt;back in 2023&lt;/a&gt;, and the originals are &lt;a href=&quot;https://blogs.newardassociates.com/devrel/activities/index.html&quot;&gt;still available&lt;/a&gt; on this website, for those who are curious to get an early (or free) peek at what&apos;s in the book. But the process of getting them book-ready involved the four of us authors (myself, Woody, Scott, and David) each turning each pattern over in our heads, collectively looking to expand each entry and, perhaps most importantly, looking to identify metrics that a DevRel team can use to determine if a given activity is accomplishing its goals. It was an early realization for us that metrics are the &amp;quot;silent killer&amp;quot; of any DevRel effort, so leaned hard into that, looking to identify or suggest metrics that would emerge from each activity.&lt;/p&gt;
&lt;p&gt;I&apos;m pretty sure that these aren&apos;t exhaustive, either. People who&apos;ve been running DevRel teams for years will probably identify a few that we missed, or have issues with how we break these down. And, if you ask me, that&apos;s good! Patterns are never meant to be ready-to-eat solutions, but help foster communication and discussion and provide a vocabulary for people &amp;quot;in the space&amp;quot; to be able to discuss these ideas and concepts at a higher (and more productive) level. With any luck, this book will help DevRel teams better execute on their efforts.&lt;/p&gt;
&lt;p&gt;Thanks for reading!&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Introducing Linguis</title>
      <link>http://blogs.newardassociates.com/blog/2025/introducing-linguis.html</link>
      <pubDate>Sat, 11 Oct 2025 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2025/introducing-linguis.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Linguis, available for examination and/or forking, is a language designed to explore the axis of, &amp;quot;How much can we tweak the front-end of the language, in this case the parser, so that people of different nationalities can write code in the syntax of their choice?&amp;quot; Available at &lt;a href=&quot;https://github.com/tedneward/Linguis&quot;&gt;https://github.com/tedneward/Linguis&lt;/a&gt; for perusal, though it&apos;s only at a 0.1 now.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;It&apos;s been an interesting 2025 so far, and with two-plus months left, I realized that aside from the new book coming out, I haven&apos;t really worked on any of the things &lt;a href=&quot;https://blogs.newardassociates.com/blog/2023/what-i-want-to-build.html&quot;&gt;I want to build&lt;/a&gt;. Thus, time to get one of the &amp;quot;little ones&amp;quot; off the list: A language with differing input syntax over the exact same AST.&lt;/p&gt;
&lt;p&gt;As I mention in the project&apos;s &lt;a href=&quot;https://github.com/tedneward/Linguis/blob/main/README.md&quot;&gt;README&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Programming languages have, almost since their inception, assumed a fixed syntax that is rooted in English for its keywords, with relatively few exceptions. Pascal has PROGRAM, FUNCTION, VAR, and so on. C has if/else, for, while. Even homoiconic languages like Lisp use English nouns for its forms.&lt;/p&gt;
&lt;p&gt;When I was in college, though, I took a trip to visit some friends in Belgium, and they had a French computer there--complete with its own version of French BASIC, where all the keywords were in--you guessed it--French. It took me a hot second to map the keywords I knew to their French equivalents, and definitely made reading the code an extra level harder.&lt;/p&gt;
&lt;p&gt;Now, in 2025, we still see most of our popular programming languages based on English keywords, which makes me wonder: Why? Don&apos;t get me wrong, as a native English speaker, I am happy that my native tongue is the default lingua franca for the programming industry, but in an era where we have literally gigs of RAM to throw at a problem, why are we continually enforcing English as a necessary prerequisite for programming?&lt;/p&gt;
&lt;p&gt;Thus, Linguis: A programming language (procedural, since this is a POC) whose keywords are &amp;quot;pluggable&amp;quot; and in several sets, so that those of non-native English speaking descent can program in their mother tongue.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For example, somebody writing English syntax might write:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name = input(&amp;quot;Hello, what is your name?&amp;quot;)
println(&amp;quot;Hello &amp;quot; + name + &amp;quot; it is nice to meet you&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But somebody writing this from a French perspective might prefer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name = saisir(&amp;quot;Hello, what is your name?&amp;quot;)
imprimernl(&amp;quot;Hello &amp;quot; + name + &amp;quot; it is nice to meet you&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... where &lt;em&gt;saisir&lt;/em&gt; is the French translation of &amp;quot;input&amp;quot; and &lt;em&gt;imprimer&lt;/em&gt; is likewise for &amp;quot;print&amp;quot;. (I tacked on the &amp;quot;nl&amp;quot;--&lt;em&gt;nouvelle ligne&lt;/em&gt;--to make it the parallel to println.) Notice that the literal strings don&apos;t change, nor do the identifiers, since those aren&apos;t directly interacting with the compiler, but it would be pretty easy to imagine how the French student would write the earlier English program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nom = saisir(&amp;quot;Bonjour, quel est ton nom?&amp;quot;)
imprimernl(&amp;quot;Bonjour &amp;quot; + nom + &amp;quot; c&apos;est agréable de vous rencontrer&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Part of the experiment here, as already being seen in the fragment above, is that the source code will need to be in full Unicode-capable streams, so that the different languages can each have their native characters represented faithfully. (Imagine what, for example, the above would need to look like for Arabic, Hebrew, or even Klingon.)&lt;/p&gt;
&lt;p&gt;Currently, as I write this, only the AST itself, built in Python, is in the repository. The tests execute AST constructs (although to be more accurate they&apos;re &amp;quot;intermediate executable&amp;quot; tree nodes, not really &amp;quot;abstract syntax&amp;quot; nodes) directly at the moment, and it supports basic procedural constructs--variable declarations, simple scoped name-value bindings, if/while/for flow control constructs, and function definitions and calls, that sort of thing. It&apos;s definitely &lt;em&gt;not&lt;/em&gt; a sophisticated language, but it&apos;s not intended to be--the sophistication, such as it is, will come at the parser level, not the semantic or execution level.&lt;/p&gt;
&lt;p&gt;Next steps at this point are to introduce the first parser (and the core interface/abstraction for doing so without being tied to what that parser is) and a main &amp;quot;driver&amp;quot; that will take a &lt;code&gt;.ling&lt;/code&gt; file from the command-line, parse, and execute it. Then a second syntax, and maybe a third. (I&apos;m planning English, French, and German, in that order, since I know those languages well, reasonably well, and passably okay, in that order). Once I&apos;ve got three, I&apos;ll probably quit while I&apos;m ahead and move on to something else, but this should keep me entertained through the end of 2025, anyway.&lt;/p&gt;
&lt;p&gt;Naturally, if you feel like tossing in a hand, particularly if you want to take a crack at introducing a new syntax, it&apos;s a public repo for a reason. :-)&lt;/p&gt;
&lt;p&gt;But, otherwise, thanks for reading!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE 31 Oct 2025:&lt;/strong&gt; Linguis is getting closer to &amp;quot;done&amp;quot; for the US-English keyword set! Basic scalar types (booleans, ints, floating-point, strings) are in place, along with the core maths (+, -, *, /. %. ^) and comparison (==, !=, &amp;lt;, &amp;gt;, &amp;lt;=, =&amp;gt;) operators. I&apos;ve also discarded my custom AST in favor of going straight to the Python AST objects--for the US-English parser, for example, the parse returns a Python &lt;code&gt;ast.Module&lt;/code&gt; object suitable for compilation and execution. (Yes, compilation--Python is an interpreted language, but the method call to turn the source into an executable code object is called &lt;code&gt;compile&lt;/code&gt;.) I&apos;m working to add lists and function defintions/calls, fix some of the missing pieces (unary negation, the boolean operators, etc), and then pivot to implementing the second parser... Pig Latin!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE 7 Nov 2025:&lt;/strong&gt; For all intents and purposes, Linguis is a complete experiment! I have working parsers and tests for English, French, and Pig Latin, though candor compels me to state that the language is hardly bullet-tested/-proofed in any way. The larger point, though, that we can swap the lexer symbols without changing the parser or AST, has been proven out pretty well, for my money. Now, a few folks suggested that it should be possible to &amp;quot;round trip&amp;quot; from English to French to Pig Latin, which is interesting, but a little beyond what I was planning to do. I may still get back to that at some point, but for now, there&apos;s a few other experiments I want to try out.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Why Writing Matters (to the Technical Professional)</title>
      <link>http://blogs.newardassociates.com/blog/2025/why-writing-matters.html</link>
      <pubDate>Mon, 11 Aug 2025 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2025/why-writing-matters.html</guid>
      	<description>
	&lt;p&gt;As a software developer in 2025, it is difficult to choose how to spend one&apos;s time. New programming languages (Rust, Zig, AssemblyScript, ...), new data storage implementations (NoSQL, NewSQL, multimodel databases, ...), and of course the alluring temptation of &amp;quot;artificial intelligence&amp;quot;, all beckon for the developer&apos;s time and attention. More importantly, in a world where ChatGPT can toss off an essay on any topic imaginable without requiring any work on your part, why would any intelligent software developer spend a moment&apos;s effort on writing prose?&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;It&apos;s a reasonable question, and one that misses three-quarters of the point of writing. Yes, writing is used to communicate, which is in of itself a valuable outcome. Without communication, humans lose their primary advantage over all the other creatures on the planet. Communication is what allows us to erect buildings, advance science, and/or rally to a cause, among other pursuits. Much of written communication comes through informal media, like Slack messages, SMS, or email, and is often used to inform others of temporal items of interest--status messages, PR notifications, and the classic standup what-I-did-yesterday-what-I-will-do-today-any-blockers three-parter. And these are both important and impossible for ChatGPT to provide &lt;sup id=&quot;fnref-1&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;As alluded in the previous paragraph, however, writing serves multiple purposes beyond the simpler act of pulling words out of one head into a form that others can consume. Writing serves multiple purposes to the technical professional. The more senior the professional, the more important the ability to write becomes, both on the job and in pursuit of the career. Across literally every company and organization, in every job role and seniority category, no single skill better returns on investment that that of the ability to craft clear and precise prose.&lt;/p&gt;
&lt;h2&gt;Why Bezos Thought Writing Matters&lt;/h2&gt;
&lt;p&gt;In June of 2004, Jeff Bezos sent a memo throughout Amazon with the subject title, &amp;quot;No PowerPoint presentations from now on at S-Team.&amp;quot;&lt;sup id=&quot;fnref-2&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; In the early days of Amazon, the S-Team would do weekly four-hour meetings that focused on execution on various projects. Each deep dive would begin with the typical oral-presentation-backed-by-PowerPoint-slides by the relevant team, which simply wasn&apos;t working. &amp;quot;The format often made it difficult to evaluate the actual progress and prevented the presentations from proceeding as planned. The deep dives were, in short, frustrating, inefficient, and error prone for both the presenter and the audience.&amp;quot;&lt;sup id=&quot;fnref-3&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Seeking a better answer, they latched on to Edward Tufte&apos;s &amp;quot;The Cognitive Style of PowerPoint: Pitching Out Corrupts Within&amp;quot;, in which he wrote, &amp;quot;As analysis becomes more causal, multivariate, comparative, evidence based, and resolution-intense, the more damaging the bullet list becomes.&amp;quot; This fit the problem they were seeing: their topics were complex, interconnected, requiring plenty of information to explore, yet the PowerPoint linear sequence of slides was not flexible enough, nor was the presenter-led approach. &amp;quot;Besides, the Amazon audience of tightly scheduled, experienced executives was eager to get to the heart of the matter as quickly as possible. They would pepper the presenter with questions and push to get to the punch line, regardless of the flow of slides. Sometimes the questions did not serve to clarify a point or move the presentation along but would instead lead the entire group away from the main argument. Or some questions might be premature and would be answered in a later slide, thus forcing the presenter to go over the same ground twice.&amp;quot;&lt;sup id=&quot;fnref-4&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Despite the heartache and churn the memo caused, they felt they had found a root cause problem: &amp;quot;The real risk with using PowerPoint in the manner we did, however, was the effect it could have on decision-making. &lt;strong&gt;&lt;em&gt;A dynamic presenter could lead a group to approve a dismal idea.&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;&lt;em&gt;A poorly organized presentation could confuse people&lt;/em&gt;&lt;/strong&gt;, produce discussion that was rambling and unfocused, and rob good ideas of the serious consideration they deserved. &lt;strong&gt;&lt;em&gt;A boring presentation could numb the brain so completely&lt;/em&gt;&lt;/strong&gt; that people tuned out or started checking their email, thereby missing the good idea lurking beneath the droning voice and uninspiring visuals.&amp;quot; &lt;em&gt;(Emphasis mine.)&lt;/em&gt; &lt;sup id=&quot;fnref-5&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2&gt;Writing as Explanation&lt;/h2&gt;
&lt;p&gt;Amazon found, as many others have, that moving from PowerPoint to Word as the presentation format forced a deep change in the presentation itself. Ideas would need to be fleshed out more fully, with only the words on the page to carry the weight of the proposal or insight, rather than the force of personality (or relative position in the org chart) of the presenter. This approach is not simpler or easier--in fact, it is much more difficult, on both sides: &amp;quot;... this model imposes duties and expectations upon the audience as well. They must objectively and thoroughly evaluate the idea, not the team or the pitch, and suggest ways to improve it. The work product of the meeting is ultimately a joint effort of the presenter and their audience—thinking that they can all stand behind.&amp;quot; &lt;sup id=&quot;fnref-6&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Part of this comes from what takes place during a typical presentation. A slide comes up at the front of the room, with the 6 bullet points each with 6 words. By necessity, each bullet point must be short and an incomplete sentence, with much of the content (and all of the nuance) inferred by the reader. Worse, the presenter is often speaking as the audience reads, forcing the audience to choose one or the other media--either they listen to what the presenter has to say, or they read and ignore the presenter&apos;s commentary. Compounding the negative impact, the presenter is typically verbally describing the nuanced elements of some or all of the bullet-pointed statements, meaning the audience has now missed exactly the nuanced take on the bullet points. If an audience member spots the nuance, they ask a question about it, requiring the presenter to awkwardly point out that question was already addressed; if they miss the nuance or say nothing, the nuance is never mentioned again. In any event, the nuance itself, not being captured anywhere in the slide, is only available to those who were in the presentation at the time of its presenting. The slide deck, on its own, is missing a crucial dimension that will be lost to time.&lt;/p&gt;
&lt;p&gt;In a written narrative, the linear nature of reading requires the author to spend extra time considering the order and flow of the words on the page. The author may (and most often will not) be present when the reader reads, meaning the author must step back and consider how the reader will consume the document: When will they ask the obvious question? Can I move the answer to that question earlier in the narrative to head that question off? Am I presenting the simplest case first, or the most complex? Much of the writing process is, in fact, editing, in order to make sure that the readers are &amp;quot;getting it&amp;quot; the way the author intends. &lt;sup id=&quot;fnref-7&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-7&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Readers do not want to wade through a 5,000 page novel to understand the quarterly performance numbers, however; brevity matters. Amazon found that six pages, 11-point font, single-spaced, is the right length for a presentation designed to take an hour. Attendees to the presentation enter the room, receive a printed copy of the narrative, and spend the first twenty minutes reading. (Roughly speaking, an average reader fluent in the language can read one page every two or three minutes.) The narrative is free to include additional material, such as charts or graphs or other material, in an appendix, but the mandatory reading material may go no longer than six pages. Any attempts to go beyond that length are summarily rejected. This brevity forces the presentation not only to be consumable within a single hour-long meeting slot, but also the narrative itself to be tightly focused. Many writers throughout history have learned this lesson. &lt;sup id=&quot;fnref-8&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-8&quot;&gt;8&lt;/a&gt;&lt;/sup&gt; &lt;em&gt;(For these same reasons, I set a hard limit on this narrative of 2500 words, excluding the Appendix, despite the Web&apos;s obvious lack of &amp;quot;pages&amp;quot; in the publishing sense.)&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Writing as Branding&lt;/h2&gt;
&lt;p&gt;For those who do not (or do not aspire to) work at Amazon, writing still offers clear benefits. In the highly-interconnected World Wide Web, opportunities abound for well-written prose to catch an audience&apos;s eye and create positive reaction. Granted, the Web currently contains trillions if not quadrillions of characters, all clamoring for time under our eyeball, and most of it is worthless. This is, however, nothing new--Arthur Schopenhauer, 19th-century German philosopher, recognized the same problem: &amp;quot;In his essays, On Authorship and On Reading, he identified two types of authors: those who write for the sake of the subject, and those who write for the sake of writing (and really, for the sake of making money). Their motivations couldn&apos;t be more different. The former write because they are curious and they want to figure something out. They&apos;re like a detective, exploring a subject from all sides, trying to come to a deeper understanding. For them the process of writing is how they figure out what they don&apos;t know and how they come up with new ideas. The latter because they get paid by the word, not the insight. You can recognize the latter by how they stretch out half-baked thoughts &apos;to the greatest possible length.&apos; Their writing is evasive, &apos;lacking in definiteness and clearness.&apos;&amp;quot; &lt;sup id=&quot;fnref-9&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-9&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;This, as an aside, is the primary reason why ChatGPT will, over time, prove to be highly inefficient as a tool for creating effective prose. &lt;sup id=&quot;fnref-10&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-10&quot;&gt;10&lt;/a&gt;&lt;/sup&gt; While it might know facts and figures, because it lacks the ability to reason and understand the underlying ontology or mental model of the subject under discussion, it will never be able to speak in &amp;quot;definiteness and clearness&amp;quot; effectively. In fact, at least to the date of this writing, where it does attempt to speak with such specificity it usually falls victim to hallucination and/or error.&lt;/p&gt;
&lt;p&gt;Those who can put forth prose in a manner that is clear, precise, and direct on a given topic will find that their reputation--their &amp;quot;brand&amp;quot;, as the marketing-savvy put it--will grow in a positive direction. Moreover, because the prose stands apart from its author, the message and meaning of the narrative will not be diminished regardless of the author&apos;s timidity or introvertedness.&lt;/p&gt;
&lt;h2&gt;Writing as Reasoning&lt;/h2&gt;
&lt;p&gt;What often comes as a surprise to the new writer is that writing is not just an exercise in dumping thoughts from head to keyboard; Paul Graham put it this way: &amp;quot;A good writer doesn’t just think, and then write down what he thought, as a sort of transcript. A good writer will almost always discover new things in the process of writing.&amp;quot; &lt;sup id=&quot;fnref-11&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-11&quot;&gt;11&lt;/a&gt;&lt;/sup&gt; The act of reaching into the brain, exploring what we know about a topic, and transferring it to some communicative medium (such as written, or even spoken, words) causes us to re-examine the material.&lt;/p&gt;
&lt;p&gt;Mortimer Adler once said, &amp;quot;The person who says he knows what he thinks but cannot express it usually does not know what he thinks.&amp;quot; &lt;sup id=&quot;fnref-12&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-12&quot;&gt;12&lt;/a&gt;&lt;/sup&gt; Consider a hypothetical for a moment: You are asked, without using any reference material, to explain how radio works. If you are like many people, you know that radio is distributed through the air in some sort of invisible &amp;quot;wave&amp;quot; (hence the term, &amp;quot;radiowaves&amp;quot;) that can degrade over distance, although AM waves seem to have greater longevity than FM waves, can be interrupted by physical objects such as walls, or by electrical fields such as lightning storms. But the actual act of transforming sound into wave, or wave back into sound, most of us are unclear on how that works. We have a mental model--an abstraction--of how the radio works, and that mental model suffices for most scenarios in post-2000 civilization. But when asked to dive into detail, we quickly discover that our mental model, like most models, is incorrect (yet still useful).&lt;/p&gt;
&lt;p&gt;Consider the scenario in which a company seeks to make a significant shift in its operations. Each individual associated with this effort has a mental model of how the effort should proceed. (Or, to be fair, perhaps only some do, and the rest are eager to build such a model based on what those who do tell them.) One individual may be thinking that this is a &amp;quot;software problem&amp;quot; that can be fixed with the proper application of code and databases. Others may think the software is fine, it&apos;s a process issue. Others in turn may want to outsource the entire solution. &amp;quot;Whether we realize it or not, mental models help us think at the subconscious level. They shape what we see, what we choose to ignore, and what we miss entirely.&amp;quot; &lt;sup id=&quot;fnref-13&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-13&quot;&gt;13&lt;/a&gt;&lt;/sup&gt; Until the models are brought out of the brain and into the world for examination, with some degree of detail, the implicit assumptions resting within a model remain buried, like corporate land mines, waiting until discovery (usually the hard way).&lt;/p&gt;
&lt;p&gt;Anecdotally, many programmers have felt this revelatory effect without realizing it: A programmer stares at the bug which has stumped them for the past two hours. They call another developer over to look at the screen, and start to explain the problem. One of two things frequently happens at this point; either the stumped programmer suddenly, mid-explanation, snaps his fingers and says, &amp;quot;Wait! Never mind, I think I got it&amp;quot; and dives back to the keyboard, or the other programmer leans over and says, &amp;quot;Wait, did you mean to have a comma here?&amp;quot; In both cases, the act of explaining the mental model of the bug yielded up an incorrect assumption that was buried in the stumped programmer&apos;s mind. Once brought out of the brain, the assumption is spotted and discarded.&lt;/p&gt;
&lt;p&gt;Writing something down forces the author to think more clearly, instead of resting on the feeling of having thought clearly.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The degradation of focus in writing is not exclusive to the software industry; liberal arts programs in academia find themselves facing existential questions as well. &amp;quot;The liberal arts, particularly the humanities, are far from thriving on most college and university campuses. Shifting market demands, financially wary stakeholders, and rampant politicization pose an immediate threat to the humanities.&amp;quot; &lt;sup id=&quot;fnref-14&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-14&quot;&gt;14&lt;/a&gt;&lt;/sup&gt; Part of what drives this is the incorrect assumption that &amp;quot;learning to code&amp;quot; is the sole necessary focus for success in a technical career. But if coding requires thinking, and thinking is based on incorrect models, then it behooves any &amp;quot;coder&amp;quot; to have a tool in their toolbox that permits--forces, even--them to bring their mental model out, for both collaborative and analytical purposes.&lt;/p&gt;
&lt;p&gt;Writing does that.&lt;/p&gt;
&lt;h1&gt;Appendix&lt;/h1&gt;
&lt;h2&gt;Bibliography&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Working Backwards&lt;/em&gt;, by Bryar, Carr; ISBN 978-1250267603&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The PR-FAQ Framework&lt;/em&gt;, by Calbucci; ISBN 979-8991318921&lt;/p&gt;
&lt;p&gt;Farnam Street blog; &lt;a href=&quot;https://fs.blog&quot;&gt;https://fs.blog&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Endnotes&lt;/h2&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;Or, perhaps, it is better to say that ChatGPT couldn&apos;t really provide without prompting, which would then be unnecessary--the act of getting the prompt out of the standup participant&apos;s head and into words is literally the point of the standup, and ChatGPT&apos;s participation would at that point be rendered entirely unnecessary.&lt;/p&gt;
&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;The S-Team is the senior-most leadership team at Amazon; basically, Jeff Bezos and his direct reports.&lt;/p&gt;
&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;&lt;em&gt;Working Backwards&lt;/em&gt;, p. 80&lt;/p&gt;
&lt;a href=&quot;#fnref-3&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-4&quot;&gt;
&lt;p&gt;&lt;em&gt;Working Backwards&lt;/em&gt;, p. 80&lt;/p&gt;
&lt;a href=&quot;#fnref-4&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-5&quot;&gt;
&lt;p&gt;&lt;em&gt;Working Backwards&lt;/em&gt;, p. 81&lt;/p&gt;
&lt;a href=&quot;#fnref-5&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-6&quot;&gt;
&lt;p&gt;&lt;em&gt;Working Backwards&lt;/em&gt;, p. 95&lt;/p&gt;
&lt;a href=&quot;#fnref-6&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-7&quot;&gt;
&lt;p&gt;In many fiction-writing workshops, when an author puts a particular piece up for review, the author is required to sit in the room with the reviewers, but is required to remain silent while the reviewers discuss. This allows the author to hear the discussion of her work first-hand, but does not allow the author the &amp;quot;crutch&amp;quot; of being able to explain what the readers &amp;quot;should have gotten&amp;quot;. It is often simultaneously the most excrutiating and enlightening experiences an author can experience.&lt;/p&gt;
&lt;a href=&quot;#fnref-7&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-8&quot;&gt;
&lt;p&gt;A few examples: &amp;quot;I have only made this letter longer because I have not had the time to make it shorter.&amp;quot; -- Blaise Pascal (The Provincial Letters, Letter 16, 1657); &amp;quot;Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.&amp;quot; (Antoine de Saint-Exupéry, Airman&apos;s Odyssey)&lt;/p&gt;
&lt;a href=&quot;#fnref-8&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-9&quot;&gt;
&lt;p&gt;Farnam Street blog, &lt;a href=&quot;https://fs.blog/schopenhauer-dangers-clickbate/&quot;&gt;https://fs.blog/schopenhauer-dangers-clickbate/&lt;/a&gt;&lt;/p&gt;
&lt;a href=&quot;#fnref-9&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-10&quot;&gt;
&lt;p&gt;For the record, no part of this essay was produced by ChatGPT.&lt;/p&gt;
&lt;a href=&quot;#fnref-10&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-11&quot;&gt;
&lt;p&gt;Quoted on Farnam Street blog, &lt;a href=&quot;https://fs.blog/why-write/&quot;&gt;https://fs.blog/why-write/&lt;/a&gt;&lt;/p&gt;
&lt;a href=&quot;#fnref-11&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-12&quot;&gt;
&lt;p&gt;Quoted on Farnam Street blog, &lt;a href=&quot;https://fs.blog/writing-to-think/&quot;&gt;https://fs.blog/writing-to-think/&lt;/a&gt;&lt;/p&gt;
&lt;a href=&quot;#fnref-12&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-13&quot;&gt;
&lt;p&gt;&lt;em&gt;The Great Mental Models&lt;/em&gt; Vol 1, p. 4&lt;/p&gt;
&lt;a href=&quot;#fnref-13&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-14&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://manhattan.institute/article/protecting-the-liberal-arts-and-humanities-in-american-higher-education&quot;&gt;https://manhattan.institute/article/protecting-the-liberal-arts-and-humanities-in-american-higher-education&lt;/a&gt;&lt;/p&gt;
&lt;a href=&quot;#fnref-14&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

	</description>
    </item>
    <item>
      <title>Book Review: Building A Debugger</title>
      <link>http://blogs.newardassociates.com/blog/2025/book-review-building-a-debugger.html</link>
      <pubDate>Fri, 23 May 2025 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2025/book-review-building-a-debugger.html</guid>
      	<description>
	&lt;p&gt;No Starch Press sent me a copy of Sy Brand&apos;s &amp;quot;Building A Debugger&amp;quot;, which walks, step by step, through the process of building your own assembly-level, native-executable debugger. It geeks me out in ways I haven&apos;t geeked out since... well, since the last low-level geekery book (the ARM assembly book) they sent me.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;For close to two decades now, I&apos;ve been telling developers (experts to neophytes) that you need to know &amp;quot;one level below the level at which you work&amp;quot;. Knowing how your Java class turns into JVM bytecode, or how that .NET assembly looks like on disk, is often the difference between knowledge and ignorance. How does the &lt;em&gt;yield return&lt;/em&gt; keyword work in C#? How did Java do inner classes before adopting nested-access classes in JDK 11 (or 12 or 15 or whenever the hell nested-access was introduced)? Being able to crack open the compiled binary, look at the disassembled output, and have at least a rough idea of what&apos;s going on, is a huge skill that every developer must have.&lt;/p&gt;
&lt;p&gt;In my personal quest to pursue that, I&apos;ve deep-dived into bytecode virtual machines (both the CLR and the JVM, among others), language compilers and interpreters (too numerous to count), and even an operating systems class in college. (I had quite the time explaining why an International Relations major wanted to take this class, let me tell yoU!) But as much as I&apos;ve been &lt;em&gt;aware&lt;/em&gt; of how a debugger works, I&apos;ve never tried to build one, particularly not one that&apos;s based on the Linux OS. I did dabble once with how to do it in Win32, but that went as far as &amp;quot;attach the process, walk the PE file, and... yeah, that&apos;s about all I want to do&amp;quot;. I never actually got to a point where I could set a breakpoint, examine memory, any of that. It was a pretty shallow dipping-of-the-toe and that was about it.&lt;/p&gt;
&lt;p&gt;Sy Brand has managed to not only tell me the water&apos;s fine, but snuck up behind me and pushed me in.&lt;/p&gt;
&lt;h2&gt;Physical&lt;/h2&gt;
&lt;p&gt;It&apos;s a typical No Starch Press book--the covers are pretty solid, the binding has that crease that allows for the book to be opened pretty widely without cracking, and the pages are heavy enough to feel good. It weighs in around 700 or so pages and 20+ chapters, and each chapter is pretty singly-focused, making each chapter a nice &amp;quot;chunk&amp;quot; to peruse during a short reading stint.&lt;/p&gt;
&lt;h2&gt;Contents&lt;/h2&gt;
&lt;p&gt;Contrary to a lot of books (including ones I&apos;ve written!), Brand doesn&apos;t spend the first chapter explaining the concepts of what&apos;s going to be covered--this is a book about building debuggers, and the assumption is that you know what a debugger is, what its basic functionality is and should be, and at least the basics of how one interacts with a debugger to, you know, debug programs. Instead, the Introduction does a lot of that &amp;quot;here&apos;s what we&apos;re going to do&amp;quot;, and Chapter 1 dives right into laying out the project structure using CMake to build &lt;code&gt;sdb&lt;/code&gt;, the &amp;quot;Sy Brand Debugger&amp;quot;.&lt;/p&gt;
&lt;p&gt;Oh, did I forget to mention? Brand uses C++17 to build the debugger, which actually makes a great deal of sense for the topic at hand. The book isn&apos;t about C++17, though, and explanatory text about C++ itself is left to an &amp;quot;explain it when we get there&amp;quot; approach. As someone who&apos;s not used C++ &amp;quot;in anger&amp;quot; in about twenty years--meaning my last foray with C++ was somewhere around C++03 or so--I think I&apos;m just about at the level assumed for the book.&lt;/p&gt;
&lt;p&gt;Likewise, CMake is not explained or explored, other than to offer up a cursory description of it and how it works. I can appreciate that--again, this is a book about building a debugger, not a book about CMake. And for the most part, the Chapter One steps are pretty easy to follow, although in my own &lt;code&gt;tdb&lt;/code&gt;/&amp;quot;Ted DeBugger&amp;quot; setup, I found that (a) the latest CMake is 4 where the book assumes 3 (which I don&apos;t think will be a problem down the road), and (b) some of the supporting cast, &lt;code&gt;vpkg&lt;/code&gt; and &lt;code&gt;libedit&lt;/code&gt;, have some OS dependencies that I had to puzzle through myself.&lt;/p&gt;
&lt;p&gt;Oh, and by the way, this is a book about building an &lt;em&gt;x64&lt;/em&gt; debugger, not an x86 or ARM debugger, so if you&apos;re on a recent MacBookPro, you&apos;re a little stuck. The choice to make this an x64 book is pretty reasonable--after all, x86 is ancient history, but not everybody has transitioned to ARM yet--but at the same time, it will limit the audience of the book. I have a vague idea to try and build an ARM debugger using the principles laid out in the book, but that&apos;s a long ways off for me, personally. (But if I were an editor at No Starch Press, I&apos;d be thinking &lt;em&gt;very&lt;/em&gt; seriously about putting Randall Hyde and Sy Brand into a room together and not let them out until a &amp;quot;Building an ARM Debugger&amp;quot; manuscript was on its way.)&lt;/p&gt;
&lt;p&gt;Once the project is set up--complete with tests, by the way, yay--Chapter 2 walks the reader through the very basics of &amp;quot;Compilation and Computer Architecture&amp;quot;. This is probably the fastest pass I think I&apos;ve ever seen on topics ranging from CPU endianness and major pieces (registers, program counter, etc) to executable file formats and memory layout. From pages 11 to 25--fourteen pages in total--is not a lot of room to explain all that. Heck, &lt;em&gt;Linkers and Loaders&lt;/em&gt; took an entire book just to explain executable file formats, and that was several hundred pages in size. My point here is, if you&apos;re not familiar with some of the material in Chapter 2, you&apos;ll probably want (or need) to supplement what&apos;s here with external resources. Again, this is a book about building a debugger, and it stays pretty tightly focused to that. The author won&apos;t leave you entirely out in the cold if you don&apos;t know what a DWARF or ELF file is, but you have to do your homework, too.&lt;/p&gt;
&lt;p&gt;Once we get past that, though, from Chapter 3 onwards, it&apos;s &amp;quot;pick a subtopic in debuggers, and let&apos;s put it into our debugger&amp;quot; territory. Chapter 3 is about attaching to a target process, Chapter 4 is about automated testing, 5 is registers, 6 is testing those registers, 7 gets us to breakpoints, and so on, all the way up through Chapter 22&apos;s &amp;quot;Advanced Topics&amp;quot;, which touches on remote debugging, among other things. As Brand covers elements of each topic, code is written in steps, sometimes refactoring along the way to make the debugger more maintainable and extensible. All of the &amp;quot;sdb&amp;quot; code is available via the author&apos;s GitHub, by the way, so while you don&apos;t &lt;em&gt;need&lt;/em&gt; to type it all in by hand, I&apos;ve often found that if I juts wanted to use somebody else&apos;s debugger, I&apos;d &lt;code&gt;brew install gdb&lt;/code&gt;, not &amp;quot;Alexa, order the book &apos;Building a Debugger&apos;&amp;quot;. Typing it in and working through the error messages is a part of learning the subject.&lt;/p&gt;
&lt;h2&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;This book is going to come with me on a few upcoming trips, but then probably go to a shelf and stay there a while--it&apos;s a tutorial, not a reference, and like many tutorials, once you &amp;quot;get it&amp;quot;, the need to go back and do the tutorial again is drastically reduced. Quite honestly, this is true of some of my favorite books, one of which is the ancient &lt;em&gt;Windows++&lt;/em&gt; book by Paul DiLascia, wherein he builds a C++ GUI framework for the Windows OS. Man, I worshipped that book for the longest time. Still have it on a shelf somewhere. Will probably never read it again, except for nostalgia&apos;s sake, but it did its thing and did it well--I learned so much about how to build an important part of what we were using at the time to write software.&lt;/p&gt;
&lt;p&gt;Frankly, I wish books like this were more popular, but I&apos;m simultaneously glad they aren&apos;t, because knowing this material is often what helps set the &amp;quot;senior developer&amp;quot; apart from the &amp;quot;junior&amp;quot;. If you know how something works under the hood, you find the concepts carry over into all sorts of different places. Knowing how an x64 debugger works makes using a debugger on any CPU platform a much easier exercise, and too few programmers actually know how to make use of a debugger at all, much less use it well. On top of that, there&apos;s often opportunities to build &amp;quot;little tools&amp;quot; to help gain visibility into one-off situations and scenarios. (For example, knowing how debuggers work make it much easier to understand how code coverage tools work, not to mention certain observability tools and platforms. Oh, and did you ever want to &amp;quot;intercept&amp;quot; a native call to be able to provide some pre-/post-processing? Yeah, knowing how debuggers work open all of those options up inside your brain.)&lt;/p&gt;
&lt;p&gt;Is this book worth learning C++ if that&apos;s never been a language you mastered? Eh, maybe. Honestly I think any developer who wants to crack the upper echelon of the industry needs to know at least a little C/C++, and this is a good exercise by which to go from &amp;quot;I know how to read it&amp;quot; to &amp;quot;I have built an interesting tool with it&amp;quot;. But you could, conceivably, use any system-level language, like Rust, Nim, Zig, or maybe even Odin, to build this, assuming you know enough of how those languages work to be able to mentally translate the C/C++ into the language of choice.&lt;/p&gt;
&lt;p&gt;Overall, I think you should buy it, read it, then tweak what you&apos;ve learned into something that&apos;s useful for your own purposes. And who knows? Maybe next time there&apos;s a weird Heisenbug that&apos;s driving the rest of your team natty, you might think, &amp;quot;Wait, maybe if I write a little tool that hooks certain API calls and takes a snapshot of certain variables, we can get a better sense of what&apos;s going on....&amp;quot; and build that tool and get that better sense and be the brilliant idea that finds the bug and get the kudos and the raise and the promotion and the cheering parade and.... Uh, right, sorry, got lost in my own daydream for a second there.&lt;/p&gt;
&lt;p&gt;Did I say buy this book yet? Yeah, go buy this book.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Disclaimer: No Starch Press sent me a review copy of the book; no other compensation was provided.&lt;/em&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Synchronous Work, Asynchronous Work</title>
      <link>http://blogs.newardassociates.com/blog/2025/sync-and-async.html</link>
      <pubDate>Sat, 15 Mar 2025 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2025/sync-and-async.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Over the last two years, we&apos;ve seen a dramatic policy debate playing out on the feeds of LinkedIn: &amp;quot;WFH (Work From Home) vs RTO (Return to Office)&amp;quot;. Nearly everyone has an opinion, and many (if not most) of them are held strongly. Some are held based on data, some on personal preference, and many are based on personal experience. Nearly all of them, however, focus on the wrong part of the debate: it&apos;s not really about &amp;quot;WFH vs RTO&amp;quot;, but about &amp;quot;async vs sync&amp;quot;.&lt;/p&gt;
&lt;!--more--&gt;
&lt;script type=&quot;module&quot;&gt;
    import mermaid from &apos;https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs&apos;;
    mermaid.initialize({ startOnLoad: true });
&lt;/script&gt;
&lt;p&gt;Over the last five years, we&apos;ve seen a remarkable transition/cycle in &amp;quot;work&amp;quot;, thanks to the COVID-19 pandemic.&lt;/p&gt;
&lt;h3&gt;Everybody go home! Don&apos;t come back! (But keep working!)&lt;/h3&gt;
&lt;p&gt;When the pandemic lockdown was imposed, nearly every company on the face of the planet &amp;quot;went remote&amp;quot;, doing everything they could to enable their employees to work from home, partly out of a desire to keep their employees, but primarily out of a desire to keep the company going. And for the two-plus years of lockdown, it actually worked out remarkably well--certainly, some jobs were heavily affected since they couldn&apos;t be done remotely (looking at you, every assembly-line job ever), but overall, for our industry, the shift was relatively smooth and painless. We discovered that Zoom/Teams/Slack/Discord and other tools could be used with great effect, though not without pain, and software was written, tested, deployed, and debugged.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Personal story: I was working for Rocket Mortgage at the time, and in the span of a week, the company went from the traditional &amp;quot;We expect all our employees to be physically present in our corporate office&amp;quot; (in Detroit, Michigan) the previous week to &amp;quot;We are monitoring the situation closely&amp;quot; on Monday to &amp;quot;Take your laptops home&amp;quot; (some of which hadn&apos;t left their laptop dock literally since the employee started working for the company one, three, or even ten-plus years earlier) by Friday. The Rocket IT team scrambled--successfully--to make sure that every single laptop could VPN in to the company network over a span of five days, and for the most part, the shift from &amp;quot;office&amp;quot; to &amp;quot;remote&amp;quot; was complete, at least at the technology level.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;During the lockdown, loads of new social rules were quickly hammered out and then renegotiated as necessary. &amp;quot;Camera on&amp;quot; vs &amp;quot;camera off&amp;quot; became a nation-wide talking point for teams. Instituting a five-minute break between meetings for people to get up and take a bio break--even when there&apos;d never been a perception of a need to do that with back-to-back meetings in different physical buildings--became a corporate policy. Suddenly, pets were welcomed &amp;quot;into&amp;quot; the (virtual) meetings.&lt;/p&gt;
&lt;p&gt;And the world just laughed when we remembered the video of &lt;a href=&quot;https://www.youtube.com/watch?v=Mh4f9AYRCZY&quot;&gt;a small girl joining her dad&apos;s BBC news report from home&lt;/a&gt;, because suddenly that was all of us, particularly those with kids. Suddenly, &lt;em&gt;every&lt;/em&gt; day was &amp;quot;take your kid to work day&amp;quot;!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Another personal note: Running the &amp;quot;Technology Culture&amp;quot; team at Rocket at the time, I was front-and-center on figuring out what the new &amp;quot;remote office&amp;quot; culture could/should be for the folks in technology. Not all the policies we created &amp;quot;stuck&amp;quot;, and some definitely got adjusted as we stumbled along, but for the most part, it was a pretty successful culture shift. By the time I left, most of them had become habitual rather than enforced.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But more germane to this essay, several &lt;a href=&quot;https://www.apollotechnical.com/working-from-home-productivity-statistics/&quot;&gt;studies&lt;/a&gt; documented that WFH led to greater productivity. By 2022, the world seemed poised to enter the &amp;quot;next phase&amp;quot; of work, where all thanks to ubiquitous Internet access and telecommunication applications, all of us (or at least a significant number of us) would be working from home.&lt;/p&gt;
&lt;h3&gt;Everybody come back! No, seriously!&lt;/h3&gt;
&lt;p&gt;Then, as the lockdown eased up, companies started to push back on the WFH approach, as we began to see the &amp;quot;missing parts&amp;quot; of working together physically in the same place. The toll of being &amp;quot;trapped&amp;quot; in one&apos;s domicile began to weigh more and more heavily on people, and even the most introverted of employees found their mental health took a hit from the lack of casual social contact. Businesses local to the office(s) found their revenue was highly tied to people being in the office, and many cities began a campaign to entice people back to the downtown areas to help get those downtown businesses back on their feet or on a more solid footing.&lt;/p&gt;
&lt;p&gt;Recognizing that &lt;em&gt;some&lt;/em&gt; time together in the same place/time is better than none, many companies began to explore &amp;quot;hybrid&amp;quot; options wherein an employee spends some percentage of their time in the office, the rest working from home. Some policies sought to give their employees flexibility in the matter, others lay down core numbers (3 days here, 2 days there) by fiat. Meanwhile, some academic &lt;a href=&quot;https://www.forbes.com/sites/benjaminlaker/2023/08/02/working-from-home-leads-to-decreased-productivity-research-suggests/&quot;&gt;studies&lt;/a&gt; suggested that there might be objective reasons working from an office was more productive, though most critics of those studies quickly pointed out flaws in the study or in the lack of peer review (which, to be fair, was also true of the pro-WFH studies, too).&lt;/p&gt;
&lt;p&gt;By 2023 and 2024, &amp;quot;return to office&amp;quot; mandates became more common, none more severe than Amazon&apos;s &amp;quot;everybody is back in the office five days a week&amp;quot; policy (re)introduced in late 2024. While some employees welcomed the return, many also balked, particularly since there seemed no credible reason for it. That in turn led corporate conspiracy theorists claimed it was because corporate building leases had to be justified, or that this was a filter designed to get people to &amp;quot;quiet quit&amp;quot; or as a test of loyalty.&lt;/p&gt;
&lt;h3&gt;My own thoughts&lt;/h3&gt;
&lt;p&gt;Though weighing in with my own thoughts on the debate isn&apos;t the point of this essay, there&apos;s still an inherent elephant in the room that needs to be addressed. If you don&apos;t care to hear my opinions, feel free to skip this section, but for those who are curious, let me lay down a few things that are facts, assumptions, or statements that I take to be axioms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fact: You will never get everybody under one roof.&lt;/strong&gt; Let&apos;s face it, companies of any size larger than a startup are global affairs. You might have a good chunk of your people in one place, but there will always be salespeople out on the road, DevRel advocates at conferences, and the CEO (and CTO and others) out schmoozing at cocktail parties in posh places like Paris or San Jose. The bare-metal idea that &amp;quot;We all need to get into the same room&amp;quot; is kinda ludicrous even on the very surface of it. You &lt;em&gt;might&lt;/em&gt; be able to get everybody into one of your office campuses, but everybody in the same building? For some companies, there is no building big enough.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fact: We have no standardized metric for &amp;quot;productivity&amp;quot;.&lt;/strong&gt; Seriously. The various academic studies are all over the map on this, measuring anything from &amp;quot;time spent on the laptop&amp;quot; to &amp;quot;keystrokes recorded&amp;quot; to &amp;quot;amount of work submitted&amp;quot;. In some cases, the studies abandoned any objective notion of &amp;quot;productivity&amp;quot; in favor of &amp;quot;preference&amp;quot;, which is remarkably un-scientific: I may &lt;em&gt;prefer&lt;/em&gt; something that is less productive, and I may &lt;em&gt;prefer&lt;/em&gt; things that are more productive, but my preferences are really a terrible measurement when considering options (with one exception, and that&apos;s--literally--employee contentment). Until we can get some kind of objective measurement of &amp;quot;productivity&amp;quot;, we often end up arguing past each other as we each cite studies that seem to defend our intuition going into the debate.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Axiom: It is absolutely possible to lead a team or a department well while doing so remotely.&lt;/strong&gt; I&apos;ve done it--I built a team-of-teams literally from nothing at the start of the pandemic to a department of 30 people all entirely remotely, and it was one of the closest groups I think I&apos;ve ever been a part of. Many of the people in that group are still in touch with me and each other, five years (and several job-hops) later. (Odd note: Some of the people I hired, I &lt;em&gt;still&lt;/em&gt; haven&apos;t actually met in person yet.) More to the point, many companies have operated entirely remotely and been wildly successful at it, and many others report hybrid success. Even if we allow for a certain amount of &amp;quot;That company was going to succeed regardless of--or even in spite of--their management&amp;quot;, there&apos;s still too large a number of successes to write off their success as entirely irrelevant to their management style.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Axiom: Running a team remotely is a skill.&lt;/strong&gt; It takes a very different mindset and a different set of tools. Some managers are prepared to work with those tools, some aren&apos;t. Most (all) can learn them, so it seems to me that some just choose not to.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Axiom: Talent exists everywhere.&lt;/strong&gt; With the growth of online learning (and the two-century-old societal trend of a &amp;quot;mobile workforce&amp;quot;), no longer is the best talent exclusive to the big cities.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Axiom: Temand for software exists everywhere.&lt;/strong&gt; Sometimes, the company lives in &lt;a href=&quot;https://en.wikipedia.org/wiki/Warsaw,_Indiana&quot;&gt;Warsaw, Indiana&lt;/a&gt; (home to a software company, I&apos;m serious, they &lt;a href=&quot;https://silveuscropins.com/technology/&quot;&gt;do crop insurance&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Axiom: Much communication is single-directional.&lt;/strong&gt; Not every meeting is about soliciting feedback or exchanging ideas; sometimes executives just want to tell you stuff, and sometimes (much more rarely) they want you to tell them stuff.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Axiom: Relationships deepen with physical, in-person time.&lt;/strong&gt; There is still no substitute for the experience of breaking bread together. I doubt there ever will be. If you want to get to know somebody better, on a personal, connected level, you have to have an overlapping proximate spot on the space-time continuum.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Assumption: Some work happens more smoothly together, while some work happens more smoothly alone.&lt;/strong&gt; Doing a brainstorm on a software design is still best done clustered around a whiteboard--I haven&apos;t found any online tool that&apos;s anywhere near as smooth as taking over a conference room with whiteboards, sticky notes, and pens. Sitting at your computer writing code, however, is definitely something that is best done without others around, unless you&apos;re pairing (which is actually quite doable--if not arguably better--over Zoom/Teams/etc).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Opinion: Ad-hoc conversations are, still, difficult to enable remotely.&lt;/strong&gt; Others can&apos;t overhear what two people on the team are discussing, and those sorts of overheard conversations are sometimes what leads to incredibly deep insights. Even the simple chair-swivel-&amp;quot;Hey can I bother you&amp;quot; kinds of conversations are difficult to replicate remotely. Some companies experimented with Discord or Teams, giving each individual their own &amp;quot;room&amp;quot;/private channel that was open to everyone except when the individual was in a &amp;quot;don&apos;t bother me&amp;quot; mode, making it trivial to &amp;quot;knock&amp;quot;/&amp;quot;ping&amp;quot; another individual to have the ad-hoc conversation, but it doesn&apos;t seem to have taken off as a standard practice.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Opinion: Coming all the way in to the office to put on headphones and be in Zoom meetings is ridiculous.&lt;/strong&gt; (That one kinda just doesn&apos;t need explanation, I don&apos;t think.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Analysis&lt;/h3&gt;
&lt;p&gt;If it&apos;s not clear by now, I ride the fence a little here, but only a little--I think WFH is a powerful tool/option, and frankly, I think a great deal of software development work can/should be done from home in order to obtain the lack-of-overhead (that is to say, commute time and costs) that WFH enables. I also think that several acts of software development benefit from being in person, and that it&apos;s useful for team members to spend time in one another&apos;s presence as a bonding activity. All together, I suppose it plants me firmly in the &amp;quot;hybrid&amp;quot; part of the spectrum, which is pretty consistent for me dating back to before the pandemic--long before COVID, when working (sometimes locally, sometimes remotely) as an independent consultant, I often looked to go (flying out if necessary) to the company/client to have periodic meetings in person, for all the reasons I just cited. But I also found that trying to work every day in the office was distracting and often counterproductive.&lt;/p&gt;
&lt;p&gt;Meanwhile, the debate rages on, probably continuing to do so for the remainder of this decade, if not longer. What I find most tragic about the whole discussion, though, is my belief that most of the debate is over the wrong thing: &lt;em&gt;it isn&apos;t about &lt;strong&gt;where you do the work&lt;/strong&gt;, it&apos;s about &lt;strong&gt;how the work gets done&lt;/strong&gt;.&lt;/em&gt; In particular, differentiating between synchronous and asynchronous work, and attaching the right kind of each to a particular problem, helps eliminate much of the ambiguity as to which (WFH or RTO) is more &amp;quot;productive&amp;quot; and allows teams to maximize their use of each.&lt;/p&gt;
&lt;h3&gt;Sync vs async work&lt;/h3&gt;
&lt;p&gt;Realistically, the sync-vs-async work is much like the sync-vs-async execution model; certain things lend themselves well to synchronous collaborative execution, and other things are highly independent and therefore can be executed asynchronously. I use the term &amp;quot;synchronous&amp;quot; here to mean &amp;quot;you and I have to chat with one another to get the work done&amp;quot;, and &amp;quot;asynchronous&amp;quot; to mean &amp;quot;I can charge forward without needing any additional input&amp;quot;. These are probably not entirely rock-solid definitions--I&apos;m still fleshing some of this out in my head as I write it--but it works well enough for the moment.&lt;/p&gt;
&lt;p&gt;It may be best to explain this with a series of examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Writing code: Asynchronous.&lt;/strong&gt; Generally we think of writing code as a solitary activity, at least among the generation of developers I grew up among. Just you, your keyboard, your mouse (as rarely as possible), your IDE, and whatever specs or stories you have in front of you that need doing. Crank up the music, time to get into the ZONE.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Pairing on code: Synchronous.&lt;/strong&gt; And yet, when you pair on some code, you need to both be &amp;quot;present&amp;quot; (literally or figuratively) at the same time, utilizing a high-bandwidth form of communication between you (e.g., the tiny amount of physical space between you so you can talk to one another, or a real-time video connection, or even a phone call while staring at a screen-share).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Code review: Depends.&lt;/strong&gt; There&apos;s certain forms of code review where I sit in front of my machine, taking notes as I go over the code, and then there&apos;s code reviews where we collectively sit around and discuss it amongst each other. This is probably one of those two-step activities, where the first step is asynchronous (I study the code) and the second is synchronous (we discuss our respective &amp;quot;takes&amp;quot; on the review and next steps).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Architecture or design brainstorm: Depends.&lt;/strong&gt; There&apos;s clearly value in several of us gathered around a whiteboard, each with a pen and eraser and scribbling things in a real-time caffeine-fueled frenzy, but there&apos;s also significant value in sitting in a quiet room by oneself, musing and sketching and doing individual thinking-and-processing-and-ideating. This is probably going to be something that will land differently with different people, but it&apos;s safe to assume, I think, that there&apos;s likely an iterative async/sync/async/sync cycle here: Ruminate on something for a while on your own, then bring it to the table with others to review/dissect/dissent, then take the pieces back into the quiet room for a while more, then bring it back to the table, &lt;em&gt;ad nauseam&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Debugging: Asynchronous.&lt;/strong&gt; Except, can&apos;t be overstated, so often the best debugger in the world is another person! I&apos;ve frequently told students that if you&apos;re stuck for 20 minutes, walk away from the screen then try again, but if you&apos;re stuck for two hours, try explaining the problem to another person, because just the act of explaining it will catalyze parts of your thinking and give you new ideas to try or insights to explore.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Discovering requirements/stories: Synchronous.&lt;/strong&gt; Meeting with customers and/or product folks and/or business owners and/or anybody else who has a stake in what the final product looks like is usually a back-and-forth sort of exercise, requiring high-fidelity communication and often physical props. This is probably the poster child of &amp;quot;in person&amp;quot; kinds of work; even doing this over a meeting technology (Teams, Zoom, Meet, etc) can be awkward in places.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Going through this leaves us with a growing conclusion that I think holds pretty well: &lt;strong&gt;Sync and async are not binary, but a continuum.&lt;/strong&gt; The various technologies that we have make sync vs async somewhat relative. Back in the day before electronic communication (even email), sync meant &amp;quot;We are physically gathered together&amp;quot; and async meant &amp;quot;We are physically apart&amp;quot;. The invention of postal mail (&amp;quot;snail mail&amp;quot;) meant that communication between async nodes was possible albeit slow. The telegraph made the async connection loops faster, but we don&apos;t really get to a &amp;quot;physically remote sync&amp;quot; status until the advent of the telephone. And so on--as the mechanics of communication get faster, we get higher fidelity exchange of information. Note that in some scenarios, however, such as a book, a large amount of communication can happen, but only in a single direction, which creates a low-synchronous/high-fidelity combination (and one that is pretty rare, and often highly time-consuming).&lt;/p&gt;
&lt;p&gt;This begins to turn the &amp;quot;sync/async&amp;quot; picture into a two-axis graph of &amp;quot;sychronicity&amp;quot; (how strongly do we have to be in sync with one another) and fidelity (how strongly can we convey ideas to each other). Taking a rough first pass at this, we get something like this:&lt;/p&gt;
&lt;pre class=&quot;mermaid&quot;&gt;
quadrantChart
    title What We Do and How We Do It
    x-axis Low Synchronicity --&gt; High synchronicity
    y-axis Low Fidelity --&gt; High Fidelity
    Code review:::work: [0.45, 0.5]
    Code:::work: [0.1, 0.2]
    Pairing:::work: [0.85, 0.85]
    Brainstorming:::work: [0.95, 0.95]
    Documentation:::work: [0.3, 0.8]
    Snail mail:::mechanic: [0.1, 0.1]
    Email:::mechanic: [0.2, 0.2]
    Prose:::mechanic: [0.1, 0.8]
    Meeting, software:::mechanic: [0.8, 0.8]
    Meeting, physical:::mechanic: [0.9, 0.9]
    &quot;Chat (Zoom, etc)&quot;:::mechanic: [0.65, 0.5]
    SMS:::mechanic: [0.4, 0.4]
    classDef work radius: 5, stroke-color: #310085
    classDef mechanic radius: 30, color: #00ff33, stroke-color: #10f0f0
&lt;/pre&gt;
&lt;p&gt;The upshot? For those activities which are high-sync/high-fidelity, we probably want to be in the office together; for those which are low-sync/low-fidelity, we probably can (and want) to be WFH (or rather, &amp;quot;working from anywhere&amp;quot;). The other two (low-sync/high-fidelity and high-sync/low-fidelity)? Either they&apos;re one-offs, or they&apos;re just not a thing for us.&lt;/p&gt;
&lt;p&gt;(&lt;em&gt;Caveat:&lt;/em&gt; This is a first pass, thinking-out-loud sort of graph, so maybe it doesn&apos;t fit, but I&apos;ve found it useful to think this way when thinking about this topic. Use as starting point for your own thinking, or discard it entirely, if you wish.)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Embrace Change (Not Perfection)</title>
      <link>http://blogs.newardassociates.com/blog/2025/embrace-change.html</link>
      <pubDate>Thu, 13 Mar 2025 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2025/embrace-change.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Ever had one of those situations where you find that some data about your engagement with a company or institution is incorrect, go through the motions to correct it, only to discover it has mysteriously changed back to the original, incorrect, value? The other day I was driving with my wife back from some doctor&apos;s appointments and we were talking about some social media friends she has that were complaining about the same. It&apos;s the modern take on &amp;quot;tilting at windmills&amp;quot;, yet it&apos;s so common we just accept it as an everyday part of modern life. It got me thinking about the problem from a software perspective, rather than a human or corporate perspective. And I think we, software developers, are partly to blame for the situation. Incorrect data, it seems, is impossible to correct in any system larger than a single database.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Consider, as an example, the classic TV trope (such a &amp;quot;King of the Hill&amp;quot; episode) where a beloved character is suddenly thrust into an obviously incorrect situation (Hank&apos;s driver&apos;s license, on renewal, lists him as being female instead of male), at which point &amp;quot;hijinks ensure&amp;quot; (as the old TV Guide used to say). Unfortunately, for those who&apos;ve had to try and correct one of those &amp;quot;obvious&amp;quot; errors, large organizations have a deep stubbornness to them, and their databases even more so. That in turn means that even though the situation might correct itself once, it&apos;s entirely possible that it repeats itself later for no apparent reason whatsoever. (Hank might convince the local Arlen branch to update his gender on his license, but it&apos;s entirely possible that the next time he renews, it&apos;s back to listing him as female because the state has him listed as female in one of their systems, thanks to the erroneous value in the Arlen branch.)&lt;/p&gt;
&lt;p&gt;Setting aside the comedic value in such situations, from a software engineer&apos;s perspective, how is this not a deeply embarrassing indictment of our industry? Think about it--we will spend weeks or months on writing code to try and keep invalid or incorrect data out of the system, yet when it happens, we shrug it off. &amp;quot;That&apos;s a data problem, nothing wrong with &lt;em&gt;my&lt;/em&gt; code,&amp;quot; engineers have been wont to say (and hide behind) during post-mortem meetings--assuming, even, that such a meeting takes place after such an error occurs. (Spoiler alert: No such meetings ever take place.) That&apos;s like pilots gathering around a TV to watch a re-enactment of a all-hands-lost plane crash and giggling at the &amp;quot;comedy of errors&amp;quot; the cockpit crew is going through, proudly claiming, &amp;quot;That&apos;s never happened on &lt;em&gt;my&lt;/em&gt; plane!&amp;quot;.&lt;/p&gt;
&lt;p&gt;While we computer scientists might try to hide behind the idea that &amp;quot;Well, it&apos;s all human error somehow&amp;quot; (which is what the NTSB almost always cites in a plane crash, by the way), but the fact is we&apos;ve spent little to no time owning the problem, and I think it&apos;s high time we should. (Keep in mind, in this post I don&apos;t really think I have solutions, but the first step to solving any problem is admitting that you have a problem!)&lt;/p&gt;
&lt;p&gt;It&apos;s not an easy problem to solve, and Lord knows it&apos;s a thankless issue that will never net anyone a Turing Award or Nobel Prize, but when&apos;s the last time you applauded when the airplane landed at the airport safely (or, even better, when the maintenance crew comes on board and delays the flight by three hours to replace a sensor in the cockpit)? Practicing these sorts of industrial discipline are never exciting or headline-generating, but when you total up the time and energy lost to chasing these kinds of gremlins, not to mention the potential downstream errors from the incorrect data (perhaps Hank&apos;s auto insurance policy goes up in cost, or even cancels altogether, because now the insurance company has him listed as a woman driver--because this is Texas, after all, and...), we really need to address this particular elephant in the room.&lt;/p&gt;
&lt;p&gt;To be clear, I don&apos;t have a proven solution here; I&apos;m speculating and making suggestions. My hope is that it sparks some kind of discussion or brainstorm, but my realistic assessment is that I&apos;m shouting into the full-throated roar of &amp;quot;Hurricane Leave-It-Alone&amp;quot;. We&apos;ve lived with this problem for fifty years (or more), so we literally have multiple generations of software developers who&apos;ve literally grown up with this problem (and can&apos;t imagine it working any other way).&lt;/p&gt;
&lt;p&gt;Before jumping into solutions, let&apos;s examine a few salient points to make that color the problem.&lt;/p&gt;
&lt;h3&gt;Axiom: Bad Data Enters the System&lt;/h3&gt;
&lt;p&gt;Humans are a wondrously unstable sort who constantly find ways around fences and gates to do the things they aren&apos;t. &amp;quot;Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.&amp;quot; (Rick Cook, &lt;em&gt;The Wizardry Compiled&lt;/em&gt;) If a human has any input into a computer program, then there&apos;s a way the human can screw it up. &lt;em&gt;We cannot eliminate human error short of eliminating the human entirely.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;That then leads us to realize that &lt;em&gt;no matter how many layers of validation exist, there will be a path that allows for semantically incorrect data to enter.&lt;/em&gt; Go back to our original example: Hank Hill being listed as &amp;quot;female&amp;quot; is not invalid data, since &amp;quot;female&amp;quot; is an acceptable value for &amp;quot;gender&amp;quot;, but it is incorrect. (This raises the important distinction that &lt;em&gt;not all valid data is correct data&lt;/em&gt;.)&lt;/p&gt;
&lt;p&gt;Thus, if errors can always happen, then &lt;em&gt;we need to stop striving to prevent the impossible, and instead promote the recovery of the incorrect&lt;/em&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Never assume it&apos;s right the first time.&lt;/strong&gt; There&apos;s some interesting parallels here between incorrect data entering a system and incorrect software being built. For different reasons, both exercises have to deal with incorrectness in the system, which is best eliminated by rapid cycles of feedback, each of which is followed by short, sharp iterations to correct what&apos;s wrong.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Axiom: Multiple Databases Exist&lt;/h3&gt;
&lt;p&gt;In any organization that is larger than a brand-new startup, there&apos;s more than one database at work. (In fact, it may even be true that most 2020-era startups have multiple simultaneously-active databases, which only underscores the point even further.) When data denormalization is the norm, even within a single database, we run the risk that a particular datum (such as Hank Hill&apos;s gender) is duplicated.&lt;/p&gt;
&lt;p&gt;We need these multiple databases for purposes of relativity, because attempts to create a &amp;quot;single-source-of-truth&amp;quot; database has been all but proven incapable of existence by this point in time. Companies that pour millions (if not billions) into &amp;quot;master data management&amp;quot; routinely find the effort extremely taxing, and the MDM model is often wildly oversimplified (a flat table of 250 columns for billions of rows, all of them NULLable, with little to no relational enforcement) &lt;em&gt;or&lt;/em&gt; wildly overcomplicated (metamodels, meta-metamodels, and meta-meta-metamodels are not unknown). Thus, each &amp;quot;significant component&amp;quot; of the enterprise (be that an organization or a service) makes use of a localized collection of the data it needs to carry out its operations: Shipping wants all the details of shipping labels, addresses, and postal codes about a customer, whereas Marketing&apos;s interest in customers is all about the order history (and none at all in where those orders went). Each component in the enterprise wants a database with the sliver of truth that&apos;s relative to its operation.&lt;/p&gt;
&lt;p&gt;We also need these multiple databases for purposes of scale, because in any non-trivial enterprise, the amount of data being tracked can easily exceed the storage capacity of a single computer system. Today&apos;s cloud-hosted systems can automatically partition data out across multiple disks, but even they have limits (operational, physical, and/or financial). Hosting ten smaller databases is vastly simpler and cheaper than trying to store and access all data within a single entity.&lt;/p&gt;
&lt;p&gt;The fact of multiple databases, each with a fraction (sometimes large, sometimes small) of the necessary data, means that at any given point in time, &lt;em&gt;a database only holds a portion of the truth of the world as captured in its system&lt;/em&gt;. Those two qualifiers are critical, by the way--&amp;quot;a portion of the truth&amp;quot; and &amp;quot;as captured in its system&amp;quot; means that a database, by definition, does not contain truth, but only a relative sliver of it, and as soon as it is captured, it is incorrect. In other words, its portion of the truth is only relevant for a period of time, and is only the truth as we knew it at that time.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What is truth?&lt;/strong&gt; Philosophers have debated this for centuries, but database engineers and DBAs seem to treat any row/column pair as sacrosanct and true until proven false, even if it disagrees with what the outside world thinks. Unfortunately, they&apos;ve propagated that mindset to everybody using the database, such that now, we assume the database to always be correct until proven otherwise, even though we &lt;em&gt;know&lt;/em&gt; that humans operate databases, and &lt;em&gt;humans make mistakes.&lt;/em&gt; Some systems are so chock-full of errors that their operators have gotten to the point of assuming the database is incorrect by default, but that&apos;s more the exception than the rule.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Axiom: Databases Must Constantly Sync with Each Other&lt;/h3&gt;
&lt;p&gt;Knowing that we must have multiple databases, and that each one is only a sliver of the truth at a given point of time, we must embrace the fact that for almost any component in the enterprise, a given database is not the single source of all data needed--we often must reference other databases for information they need in order to proceed. Consider, for example, the canonical e-commerce site. In order to ship an order, the Shipping system must reference the Orders system to get the order to process (to find what items to pull from inventory bins and the like), and also the Customer system (to find the Customer&apos;s shipping address).&lt;/p&gt;
&lt;p&gt;If you&apos;re the architect of the Shipping system, you want to keep this data handy--nothing kills your performance like trying to make multiple round trips to remote systems--but you also know that the &amp;quot;remote&amp;quot; data can change without your knowledge. So you often set up a batch approach where you&apos;ll take changes to your local database, and forward them &amp;quot;in batch&amp;quot; (that is, gather up a whole slew of changes into one bundle) to the databases that might be interested in your local changes. &lt;em&gt;We sync our local data to other data systems in order to get their updates to what they know to be the truth.&lt;/em&gt; (Or think they know, anyway.)&lt;/p&gt;
&lt;p&gt;This then, becomes the heart of the problem: Somewhere along the way, someone entered Hank&apos;s gender incorrectly, and the bundled batch pushed it downstream, because it was a change. Despite the fact that this new data might not have been verified, validated, or confirmed, it was a change, and therefore it needed to be batched and sent. And when the downstream system got the change, it faithfully updated its local copy of that data, which in turn may trigger further downstream changes.&lt;/p&gt;
&lt;p&gt;And suddenly, Hank finds himself seeing tampon ads on his phone.&lt;/p&gt;
&lt;h3&gt;Solution Ruminations&lt;/h3&gt;
&lt;p&gt;Given, then, that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;bad data enters the system&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;multiple databases continue to exist&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;databases continuously update data back and forth between them&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;... we find that &lt;em&gt;errors will continously cycle and propagate until eradicated in every database&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Given that we cannot prevent the error, we have to then embrace the idea of &lt;em&gt;identifying and correcting the error&lt;/em&gt;. A corollary to that is to do so &lt;em&gt;across all the systems it has entered&lt;/em&gt;, lest the error re-propagate back to the system in which it was just corrected.&lt;/p&gt;
&lt;p&gt;We can do that in a variety of ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;store everything in a single database (the &amp;quot;Master Database&amp;quot; Fallacy). There&apos;s a plethora of reasons why this doesn&apos;t work, some of it technical (limitations on scalability and performance) and some of it organizational (the pain incorporated when you have a single dependency across the entire organization). For these reasons (and more), most organizations find it untenable or unacceptable to take this path. (A great many more organizations still try to create a Master Database, though, and find this out the hard way.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;create a mechanism where a particular update can &amp;quot;override&amp;quot; any further updates to that datum (in other words, formalizing the &amp;quot;System of Record&amp;quot; approach). This starts to get into the business of &amp;quot;weighing&amp;quot; different facts against one another, where one fact may be given as &amp;quot;more true&amp;quot; (or perhaps, better stated, &amp;quot;more likely to be true&amp;quot;) than others. Hank&apos;s assertion that he is male should be given more weight than an update coming from a data-entry clerk three departments over, particularly if Hank has a birth certificate handy. (Of course, if this is the system storing birth certificates, maybe we weight things to favor the original input of the nurse and parents, and thus do we start to run into the Gordian Knot of weighted facts--how we decide those weights is always subject to some deep and divisive debate.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;track and make visible to users where and how database updates occur (an &amp;quot;audit log&amp;quot; approach). This is partly embraced by the &amp;quot;Event Sourcing&amp;quot; approach to the storage of data, though we still run into limitations, since the data only knows what it knows local to itself--a given ES implementation doesn&apos;t track where or when or why the update occurred, only that it occurred.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My gut tells me that there&apos;s way to factor some of this more deeply into the database implementations themselves, but I haven&apos;t spent enough time thinking about it yet to have anything concrete. That said, I&apos;d love to get some feedback on the idea, and whether or not I&apos;m missing something deeply fundamental here or the solution is staring us in the face.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Debts, Tech and Otherwise</title>
      <link>http://blogs.newardassociates.com/blog/2025/debts-tech-and-otherwise.html</link>
      <pubDate>Sun, 9 Mar 2025 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2025/debts-tech-and-otherwise.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; A colleague of mine, Scott Porad (CTO, VP Engineering) posted on LinkedIn, asking, &amp;quot;What are all the other kinds of debt like tech debt?&amp;quot; He listed out a few, then asked for others to weigh in, and the list grew... kinda long. And interesting. And made me think about the metaphor more deeply.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;&lt;a href=&quot;https://www.linkedin.com/posts/scottporad_help-me-think-something-through-what-are-activity-7303085643205681152-H6GF/&quot;&gt;His list&lt;/a&gt; included financial debt (the OG), Product debt (gaps in the product that impact revenue or lead to support costs), Ops Debt (manual processes performed by the operations team because the software doesn&apos;t support the processes), Process Debt (valuable steps of the software development process that are skipped causing quality or velocity issues), and Org Debt (key roles that are not staffed that cause quality or velocity issues).&lt;/p&gt;
&lt;p&gt;He then asked others to weigh in with their favorites, and the answers poured in. Many (I won&apos;t list them all--partly because I want you to read the original post!) were interesting, and I think they fall into a variety of different categories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Technological.&lt;/strong&gt; Whether it&apos;s the data, the UX/Design, the backend, or even the choice to over-depend on open-source without &amp;quot;giving back&amp;quot;. Documentation falls in here, too.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Procedural.&lt;/strong&gt; What processes are being done by hand that cost the team time, money, or energy? What sorts of things are being hidden by a &amp;quot;lightweight process&amp;quot; focus (a la &amp;quot;agile&amp;quot;) because companies are afraid to institute a process, lest they be called &amp;quot;not agile&amp;quot;?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mental.&lt;/strong&gt; What assumptions were made that turned out to be wrong? What assumptions were right &amp;quot;back then&amp;quot; but no longer hold? Is the organization chasing the right problems? What knowledge is missing from the people that need to know?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cultural.&lt;/strong&gt; Any group of humans forms a culture, but is that culture serving the business, or holding it back?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Talent.&lt;/strong&gt; A few of the responses mentioned &amp;quot;youth&amp;quot; or &amp;quot;experience&amp;quot; debt, as in a lack of investment into junior talent, or a refusal to recognize the value of experienced veteran talent on the team. Likewise, having &amp;quot;not enough&amp;quot; in raw terms, e.g., understaffed teams.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Support.&lt;/strong&gt; This is a more nebulous catch-all category but includes things like &amp;quot;marketing&amp;quot; (neglecting marketing practices over time, leading to damaged brand and customer relationship) or &amp;quot;legal&amp;quot; (failure to recognize the legal and/or regulatory necessities, bringing the company into legal jeopardy).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Again, I encourage readers to go check out Scott&apos;s original post. It was fascinating how much of it just poured out in the comments, and the wide-ranging nature of the responses.&lt;/p&gt;
&lt;p&gt;Which got me thinking: Are these really &amp;quot;debts&amp;quot;? Or, more to the point, are they bad?&lt;/p&gt;
&lt;h4&gt;Debt: A Metaphor&lt;/h4&gt;
&lt;p&gt;If we go back to the original definition of &amp;quot;tech debt&amp;quot;, if I remember correctly, I first heard it from Mike Clark back on the NFJS tour in the late 2000s, but &lt;a href=&quot;https://en.wikipedia.org/wiki/Technical_debt&quot;&gt;Wikipedia tells me&lt;/a&gt; that Ward Cunningham first coined the term in 1992 as a metaphor to explain to his boss how making short-term decisions can boomerang and create problems over time, and therefore investment was needed to refactor the code. In particular, the point of the analogy was that &amp;quot;While technical debt can accelerate development in the short term, it may increase future costs and complexity if left unresolved.&amp;quot; The official Wikipedia definition of &amp;quot;Technical debt&amp;quot;, by the way, is this: &amp;quot;the implied cost of additional work in the future resulting from choosing an expedient solution over a more robust one.&amp;quot;&lt;/p&gt;
&lt;p&gt;Ward put it like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite... The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation, object-oriented or otherwise.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Martin Fowler later &lt;a href=&quot;https://martinfowler.com/bliki/TechnicalDebt.html&quot;&gt;wandered into this arena&lt;/a&gt;, too, pointing out that debt is sometimes taken on deliberately (a car loan, a mortgage) for good purposes, and sometimes it&apos;s accrued accidentally (credit card debt) because of poor planning or execution. He likened it to a &lt;a href=&quot;https://martinfowler.com/bliki/TechnicalDebtQuadrant.html&quot;&gt;quadrant&lt;/a&gt; along two axes: reckless vs prudent, deliberate vs inadvertent:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://martinfowler.com/bliki/images/techDebtQuadrant.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In almost all of the &amp;quot;pain&amp;quot; cases of debt, regardless of the kind, the worst quadrant to be in was Inadvertent/Reckless: We made bad decisions without realizing it, and paid for it later, painfully. Slightly better is Deliberate/Reckless, where we knowingly made a reckless decision (which raises its own questions), and still paid for it later, painfully. The &amp;quot;painfully&amp;quot; part is why most people react so strongly to debt, and to the debt metaphor, and why it often engenders its own kneejerk reactions when the topic appears.&lt;/p&gt;
&lt;p&gt;When we look at those list of &amp;quot;debts&amp;quot;, pretty much all of them can fit into the definition pretty well: for the subject &lt;em&gt;S&lt;/em&gt;, we take on an implied cost of doing additional effort in the future in order to take on the expedient solution now, instead of the more robust one:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Technological:&lt;/strong&gt; &lt;em&gt;Data.&lt;/em&gt; We take on an implied cost of additional effort refactoring our data and breaking down the silos in order to take on the expedient solution of a denormalized database or maintaining separate independent databases now.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Technological:&lt;/strong&gt; &lt;em&gt;Architectural.&lt;/em&gt; We take on an implied cost of additional effort refactoring our architecture to be more scalable or more secure or more mobile-friendly in order to take on the expedient solution of shipping a basic three-layer CRUD app now.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Technological:&lt;/strong&gt; &lt;em&gt;UI/UX.&lt;/em&gt; We take on an implied cost of additional effort building out a more cohesive and coherent user experience in order to take on the expedient solution of shipping a clumsy functional UI now.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Talent:&lt;/strong&gt; &lt;em&gt;Youth debt.&lt;/em&gt; We take on an implied cost of additional effort mentoring more junior developers later in order to take on the expedient solution of having all senior engineers work on the project now.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Talent:&lt;/strong&gt; &lt;em&gt;Experience debt.&lt;/em&gt; We take on an implied cost of additional effort building experience in our domain or our systems later in order to take on the expedient solution of severing all the senior engineers on the project now.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;... and so on. For each of the topics brought up in Scott&apos;s post, there is a very clear sense of &amp;quot;We are taking a short-term view which hurts us in the long run&amp;quot; feeling. And yes, most of us in the IT industry have a story like this (if not several times over) that we lived, and regretted, through.&lt;/p&gt;
&lt;p&gt;But I think that&apos;s only half the story.&lt;/p&gt;
&lt;h4&gt;Debt and Evolution/Iteration&lt;/h4&gt;
&lt;p&gt;The more I go through each of these, the more I realize that there is another idea hiding in here, which is that sometimes we take on the debt &lt;em&gt;because we don&apos;t know the future.&lt;/em&gt; Think about it this way: Does it make sense to invest heavily into a particular area (application, database, vision, process, talent, ...) if we find that after a few iterations, it&apos;s a mistake to take that approach? Think of your favorite startup unicorn story, and how often those unicorns needed to &amp;quot;pivot&amp;quot;--that is, quit what they were doing and try something else entirely different--in order to stay afloat or try something else? If the company &lt;em&gt;hadn&apos;t&lt;/em&gt; taken the short-term approach, and instead invested a massive amount of time/energy/money into something that was now essentially worthless, all of that investment would now be a waste and therefore a loss.&lt;/p&gt;
&lt;p&gt;Or worse, fall prey to the Sunk Cost Fallacy, and become convinced that &amp;quot;They can&apos;t give up now!&amp;quot;, and fail to pivot entirely.&lt;/p&gt;
&lt;p&gt;The truth is, in most practical cases of &amp;quot;debt acquisition&amp;quot;, the principals involved in making the decision were faced with the basic conundrum of &amp;quot;Do we ship sooner rather than later, knowing that what we deliver sooner will have some inherent problems with it that will need to be addressed later?&amp;quot; Implicit in this question is the flip side, though, which often helps to present as part of the whole decision-making process: &amp;quot;Do we ship later rather than sooner, knowing that if we wait too long the window of opportunity will close partially or entirely and render the entire enterprise moot?&amp;quot; That &amp;quot;later&amp;quot; part of the question rarely gets uttered out loud, and &lt;em&gt;never&lt;/em&gt; gets brought up in the &lt;em&gt;post facto&lt;/em&gt; analysis of &amp;quot;We chose the expedient solution &lt;em&gt;n&lt;/em&gt; months or years ago, and we got to this point now.&amp;quot; Keep in mind, if they chose the long-term solution and failed, we&apos;re not around to discuss it! While it&apos;s easy to judge the decision &lt;em&gt;post facto&lt;/em&gt;, like all decisions at the time they are made, the &amp;quot;right&amp;quot; choice is not nearly so clear. What&apos;s worse, we don&apos;t have great clarity on the efficacy of the choice here, because we only remember one-fourth of the result quadrant:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;&amp;quot;Debt Results&amp;quot; &lt;/th&gt;&lt;th&gt; Choice: Debt/Expediency &lt;/th&gt;&lt;th&gt; Choice: No debt/&amp;quot;Right&amp;quot;&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Failure result &lt;/td&gt;&lt;td&gt; No data/discussion &lt;/td&gt;&lt;td&gt; No data/discussion&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Success result &lt;/td&gt;&lt;td&gt; &amp;quot;Agh, the pain!&amp;quot; &lt;/td&gt;&lt;td&gt; No pain to discuss&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;In other words, 25% of the squares on the above graph get 100% of the discussion and the angst. Which, by any reasonable interpretation of this data, suggests that the main reason we spend so much time castigating people for making the Debt choice is because that&apos;s the only one we talk about.&lt;/p&gt;
&lt;h4&gt;Debt as a Metaphor&lt;/h4&gt;
&lt;p&gt;I think, overall, that the debt metaphor works, and works well. It obviously applies to more than just &amp;quot;technical&amp;quot; debt, though, and as Scott&apos;s post suggests, there&apos;s alot of different kinds of debt we can incur as an organization. Fowler&apos;s Reckless-Prudent-Inadvertent-Deliberate quadrant helps categorize the conscious decision around debt, but clearly relies on the individuals involved to describe the differences between &amp;quot;reckless&amp;quot; and &amp;quot;prudent&amp;quot;. In the moment, it may feel prudent to be focusing on the here-and-now solution--which, to be fair, it often is, as exemplified by the whole YAGNI (You Ain&apos;t Gonna Need It) movement of the agile mindset--and only later does it feel reckless. But that sort of &lt;em&gt;post facto&lt;/em&gt; analysis is itself a privilege, because it means we&apos;ve had the success thus far to be able to go back and reflect on those decisions and attempt to recover/refactor them.&lt;/p&gt;
&lt;p&gt;Or look at it this way: How many of us would be perpetual renters had we not taken on the mortgage to buy our first home? How many people could actually get to the point where they had $500k, $1m, or even more, saved up in a bank, waiting to buy the home outright? Debt in of itself isn&apos;t bad; it&apos;s when it&apos;s Inadvertent/Reckless debt that we find the angst.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Shapes of Data: Tabular</title>
      <link>http://blogs.newardassociates.com/blog/2025/the-shapes-of-data-tabular.html</link>
      <pubDate>Wed, 5 Feb 2025 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2025/the-shapes-of-data-tabular.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; One of the &amp;quot;OG&amp;quot; data formats, the tabular data structure, aka &amp;quot;the flat file&amp;quot;, is still today a handy and reasonable way of exchanging data in an automatable fashion without significant integration work required. Its shape is ideal for a multitude of data molecules that all share the exact same contents.&lt;/p&gt;
&lt;!--more--&gt;
&lt;!-- Let&apos;s use some MermaidJS for some diagrams here, shall we? --&gt;
&lt;script type=&quot;module&quot;&gt;
import mermaid from &apos;https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs&apos;;
mermaid.initialize({ startOnLoad: true });
&lt;/script&gt;
&lt;h3&gt;Refresher&lt;/h3&gt;
&lt;p&gt;In a serialized representation of the tabular format, such as a CSV file:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;each &amp;quot;line&amp;quot; (that is, sequence of characters terminated by the platform&apos;s recognized end-of-line sequence, such as a CR or CRLF pair) defines a single record&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;convention holds that the first (&amp;quot;0th&amp;quot;) line defines the &amp;quot;atom names&amp;quot; (aka &amp;quot;column&amp;quot; or &amp;quot;field&amp;quot; names) within the record&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;each atom is separated by a delimiting character, which must itself be escaped somehow if the delimiter is a valid data value (the comma is most popular, but TAB characters are also a common choice since TABs rarely show up in the actual data)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;each line is expected to have some kind of value defined for each atom that comprise the record&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;there is no uniqueness constraint anywhere in the representation--no keys and no identifiers&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;different &amp;quot;molecules&amp;quot; (types) must appear in different tabular spaces&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;there is no &amp;quot;reference&amp;quot; mechanism anywhere in the tabular shape&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;most tabular data storage is done solely as files--there are few-to-no &amp;quot;tabular databases&amp;quot; that provide query/edit capabilities (though, to be fair, since many relational databases can import/export tables as tabular files, it becomes a relatively easy task to import the flat data, query/modify it, then export it as a tabular file again)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Shape analysis&lt;/h3&gt;
&lt;p&gt;Within most programming languages, the tabular shape is often most easily represented as an array or list of strongly-typed records/structs. However, there are some distinct differences. In most O-O languages, an &amp;quot;array of objects&amp;quot; doesn&apos;t actually store the object, but only stores pointers/reference to objects, which allows for aliased repetition of an object in a collection:&lt;/p&gt;
&lt;p&gt;Example 1:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;// This is pseudo-Java/C#/C++:

Person p = new Person(&amp;quot;Fred&amp;quot;, &amp;quot;Flintstone&amp;quot;, 39);
List&amp;lt;Person&amp;gt; people = new List&amp;lt;Person&amp;gt;();
people.append(p); // Here&apos;s Fred!
people.append(p); // Uh, here&apos;s Fred again!
people.append(p); // Wait, Fred, third time?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that while we assume the array looks like this:&lt;/p&gt;
&lt;pre class=&quot;mermaid&quot;&gt;
flowchart TB
    people--&gt;p1[Fred]
    people--&gt;p2[Fred]
    people--&gt;p3[Fred]
&lt;/pre&gt;
&lt;p&gt;In truth it&apos;s more like this:&lt;/p&gt;
&lt;pre class=&quot;mermaid&quot;&gt;
flowchart TB
    people--&gt;p1[cell 0]--&gt;person[Fred]
    people--&gt;p2[cell 1]--&gt;person[Fred]
    people--&gt;p3[cell 2]--&gt;person[Fred]
&lt;/pre&gt;
&lt;p&gt;In other words, each cell in the array is pointing to the same object. We certainly could create the more &amp;quot;tabular-correct&amp;quot; representation, like so:&lt;/p&gt;
&lt;p&gt;Example 2:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;// This is pseudo-Java/C#/C++:

List&amp;lt;Person&amp;gt; people = new List&amp;lt;Person&amp;gt;();
people.append(new Person(&amp;quot;Fred&amp;quot;, &amp;quot;Flintstone&amp;quot;, 39)); // Here&apos;s Fred!
people.append(new Person(&amp;quot;Fred&amp;quot;, &amp;quot;Flintstone&amp;quot;, 39)); // Uh, here&apos;s Fred again!
people.append(new Person(&amp;quot;Fred&amp;quot;, &amp;quot;Flintstone&amp;quot;, 39)); // Wait, Fred, third time?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But this now has three distinct instances of Fred running around, and that duplication might cause havoc in other ways.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Hmm, I think they actually did an episode of the Flintstones where that exact thing happened.... &lt;a href=&quot;https://flintstones.fandom.com/wiki/Ten_Little_Flintstones!&quot;&gt;Yup, season 4, episode 104!&lt;/a&gt; )&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;While the difference here is subtle, the key is that in the object/language scenario, we have references to Fred, rather than copies of Fred, such that if we change Example 1 slightly to read:&lt;/p&gt;
&lt;p&gt;Example 1A:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;// This is pseudo-Java/C#/C++:

Person p = new Person(&amp;quot;Fred&amp;quot;, &amp;quot;Flintstone&amp;quot;, 39);
List&amp;lt;Person&amp;gt; people = new List&amp;lt;Person&amp;gt;();
people.append(p); // Here&apos;s Fred!
people.append(p); // Uh, here&apos;s Fred again!
people.append(p); // Wait, Fred, third time?
people[0].firstName = &amp;quot;Wilma&amp;quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the array appears to contain three Wilma Flintstones. This is clearly different than in Example 2, where have distinct copies of each means only the first Person is modified.&lt;/p&gt;
&lt;p&gt;In addition, the lack of any reference mechanism means that if we widen the definition of &amp;quot;Person&amp;quot; to include a spouse as a fourth atom, we run smack into the problem that we cannot reference another Person in the tabular format; the best we can do is copy some of the atoms and do a &amp;quot;fixup&amp;quot; later, a la:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;FirstName &lt;/th&gt;&lt;th&gt; LastName &lt;/th&gt;&lt;th&gt; Age &lt;/th&gt;&lt;th&gt; SpouseFirstName &lt;/th&gt;&lt;th&gt; SpouseLastName&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Fred &lt;/td&gt;&lt;td&gt; Flintstone &lt;/td&gt;&lt;td&gt; 39 &lt;/td&gt;&lt;td&gt; Wilma &lt;/td&gt;&lt;td&gt; Flintstone&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Wilma &lt;/td&gt;&lt;td&gt; Flintstone &lt;/td&gt;&lt;td&gt; 35 &lt;/td&gt;&lt;td&gt; Fred &lt;/td&gt;&lt;td&gt; Flintstone&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Barney &lt;/td&gt;&lt;td&gt; Rubble &lt;/td&gt;&lt;td&gt; 38 &lt;/td&gt;&lt;td&gt; Betty &lt;/td&gt;&lt;td&gt; Rbuble&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Betty &lt;/td&gt;&lt;td&gt; Rubble &lt;/td&gt;&lt;td&gt; 35 &lt;/td&gt;&lt;td&gt; Barney &lt;/td&gt;&lt;td&gt; Flintstone&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;(Column labels appear only as a convenience to us humans.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Notice, however, that the mistakes (one syntactically incorrect, one semantically incorrect) in the Rubbles&apos; records are completely acceptable to the tabular data store, leaving it up to the developer to catch &amp;quot;by hand&amp;quot;. This lack of verification/validation is a rampant problem in any flat-file-based data interchange, and has plagued developers for years.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Shapes of Data: Relational</title>
      <link>http://blogs.newardassociates.com/blog/2025/the-shapes-of-data-relational.html</link>
      <pubDate>Tue, 4 Feb 2025 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2025/the-shapes-of-data-relational.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Relational data is, contrary to popular belief, characterized not by &amp;quot;tables&amp;quot;, but by sets and relational variables (also known as &amp;quot;relvars&amp;quot;), and making use of a relational algebra and predicate calculus to make it easier to do set-oriented operations.&lt;/p&gt;
&lt;!--more--&gt;
&lt;!-- Let&apos;s use some MermaidJS for some diagrams here, shall we? --&gt;
&lt;script type=&quot;module&quot;&gt;
import mermaid from &apos;https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs&apos;;
mermaid.initialize({ startOnLoad: true });
&lt;/script&gt;
&lt;h3&gt;Refresher&lt;/h3&gt;
&lt;p&gt;Because most developers come to relational databases via SQL, usually either studied briefly in classes at university or as-necessary to get the work done while on the job, they often don&apos;t realize the relational model is much more academic and foundational than the flavor of SQL they&apos;ve come to use and know. [Date13] &lt;sup id=&quot;fnref-1&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; and [Fussell] &lt;sup id=&quot;fnref-2&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; define the relational model as characterized by &lt;em&gt;relation&lt;/em&gt;, &lt;em&gt;attribute&lt;/em&gt;, &lt;em&gt;tuple&lt;/em&gt;, &lt;em&gt;relation value&lt;/em&gt; and &lt;em&gt;relation variable&lt;/em&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A &lt;em&gt;relation&lt;/em&gt; is, at its heart, a truth predicate about the world, a statement of facts (&lt;em&gt;attributes&lt;/em&gt;) that provide meaning to the predicate. For example, we may define the relation &amp;quot;PERSON&amp;quot; as &lt;code&gt;{SSN, Name, City}&lt;/code&gt;, which states that &amp;quot;there exists a PERSON with a Social Security Number SSN who lives in City and is called Name&amp;quot;. Note that in a relation, attribute ordering is entirely unspecified.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A &lt;em&gt;tuple&lt;/em&gt; is a truth statement within the context of a relation, a set of attribute values that match the required set of attributes in the relation, such as &amp;quot;&lt;code&gt;{PERSON SSN=&apos;123-45-6789&apos; Name=&apos;Catherine Kennedy&apos; City=&apos;Seattle&apos;}&lt;/code&gt;&amp;quot;. Note that two tuples are considered identical if their relation and attribute values are also identical. (This is in contrast to an object system in which two objects are only identical if they have the same unique identifier--typically a memory address.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A &lt;em&gt;relation value&lt;/em&gt;, then, is a combination of a relation and a set of tuples that match that relation, and a &lt;em&gt;relation variable&lt;/em&gt; is, like most variables, a placeholder for a given relation, but can change value over time. Thus, a relation variable &lt;code&gt;People&lt;/code&gt; can be written to hold the relation &lt;code&gt;{PERSON}&lt;/code&gt;, and consist of the relation value&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{ {PERSON SSN=&apos;123-45-6789&apos; Name=&apos;Catherine Kennedy&apos; City=&apos;Seattle&apos;},
  {PERSON SSN=&apos;321-54-9876&apos; Name=&apos;Charlotte Neward&apos; City=&apos;Redmond&apos;},
  {PERSON SSN=&apos;213-45-6978&apos; Name=&apos;Cathi Gero&apos; City=&apos;Redmond&apos;} }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Thanks to our familiarity with tabular storage models, we ofen write this relation variable in a tabular format like so:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;SSN &lt;/th&gt;&lt;th&gt; Name &lt;/th&gt;&lt;th&gt; City&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;123-45-6789 &lt;/td&gt;&lt;td&gt; Catherine Kennedy &lt;/td&gt;&lt;td&gt; Seattle&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;321-54-9876 &lt;/td&gt;&lt;td&gt; Charlotte Neward &lt;/td&gt;&lt;td&gt; Redmond&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;213-45-6978 &lt;/td&gt;&lt;td&gt; Cathi Gero &lt;/td&gt;&lt;td&gt; Redmond&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Keep in mind, however, that in the model itself, the tuple is not exactly a row, and each tuple knows both the name and the value of each of its atoms.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We can then operate against these relation values using using a set of operators (described in some detail in Chapter 7 of [Date04] &lt;sup id=&quot;fnref-3&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;): restrict, project, product, join, divide, union, intersection and difference. We modify &lt;code&gt;People&lt;/code&gt; by using the union binary operator (let&apos;s call it &lt;code&gt;+&lt;/code&gt;) on it and a second, unnamed, relation variable containing a single tuple:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;People = People + {PERSON SSN=&apos;312-54-8796&apos; Name=&apos;Ted Neward&apos; City=&apos;Redmond&apos;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After this operation, &lt;code&gt;People&lt;/code&gt; now holds four tuples. Additional operators can be used to create &lt;em&gt;derived relation values&lt;/em&gt;, relations that are calculated from other relation values in the database--for example, we can create a relation value that demonstrates the number of people living in individual cities by making use of the project and restrict operators across the &lt;code&gt;People&lt;/code&gt; relation variable defined above.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The other half of relational models is the deep understanding they have of relationships between relational variables.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The other half of the relational model is that of the formal relationships that can be expressed and understood by the database; we can define a relational value to have a unique identifying value (a primary key), and then reference that value within tuples.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Shape analysis&lt;/h3&gt;
&lt;h3&gt;Popular implementations&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Databricks&lt;/li&gt;
&lt;li&gt;IBM DB2&lt;/li&gt;
&lt;li&gt;H2&lt;/li&gt;
&lt;li&gt;MariaDB&lt;/li&gt;
&lt;li&gt;Microsoft Access&lt;/li&gt;
&lt;li&gt;Microsoft SQL Server&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;Oracle DB&lt;/li&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;li&gt;Snowflake&lt;/li&gt;
&lt;li&gt;SQLite&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;&lt;em&gt;Relational Theory for Computer Professionals&lt;/em&gt;, C.J. Date, OReilly 2013&lt;/p&gt;
&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;Can&apos;t remember this reference right now&lt;/p&gt;
&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;&lt;em&gt;Introduction to Database Systems&lt;/em&gt; (8th Ed), C.J. Date, Addison-Wesley 2004&lt;/p&gt;
&lt;a href=&quot;#fnref-3&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

	</description>
    </item>
    <item>
      <title>The Shapes of Data: Object</title>
      <link>http://blogs.newardassociates.com/blog/2025/the-shapes-of-data-object.html</link>
      <pubDate>Mon, 3 Feb 2025 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2025/the-shapes-of-data-object.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Objects, despite being the most common tool form of mainstream programming languages, are often not as well-understood as a data concept as one might think. In an object data model, entities are defined as unions of state and behavior (and behavior is often of much less concern to the data modeler) that in turn can be related to other objects through a variety of mechanisms (type, ownership, association, and so on).&lt;/p&gt;
&lt;!--more--&gt;
&lt;!-- Let&apos;s use some MermaidJS for some diagrams here, shall we? --&gt;
&lt;script type=&quot;module&quot;&gt;
import mermaid from &apos;https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs&apos;;
mermaid.initialize({ startOnLoad: true });
&lt;/script&gt;
&lt;h3&gt;Refresher&lt;/h3&gt;
&lt;p&gt;Object systems are typically characterized by some basic components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;State&lt;/em&gt; is a pretty self-explanatory concept, most closely akin to &amp;quot;the data&amp;quot;. Typically this is made up of a series of named atoms that are closely bound.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Identity&lt;/em&gt; is an implicit concept in most O-O languages, in that a given object has a unique identity that is distinct from its state (the value of its internal fields)--two objects with the same state are still separate and distinct objects, despite being bit-for-bit mirrors of one another. This is the &amp;quot;identity vs. equivalence&amp;quot; discussion that occurs in languages like C++, C# or Java, where developers must distinguish between &amp;quot;a == b&amp;quot; and &amp;quot;a.equals(b)&amp;quot;; where the first indicates whether the two references are pointing to the same objects, and the second determines whether the two objects contain the same state. It is an important caveat to any object system that while identity implies state, state doesn&apos;t imply identity.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Identity then also gives rise to &lt;em&gt;association&lt;/em&gt;, in that objects can be referenced from one another through the use of either an implicit or explicit pointer as either an explicit or implicit atom within the object. Note that associations in most (if not all) object systems are one-way: If Person holds a reference to Address, the Address has no implicit knowledge of that association and if we wish to navigate from the Address back to the Person that references it, we must explicitly create and manage that atom in Address. (Note that in most object systems any non-atomic state is held through association, with the exception of &amp;quot;value types&amp;quot; in .NET or just in C++ in general, where the ownership is more explicit via pointers/references.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;em&gt;behavior&lt;/em&gt; of an object is fairly easy to see, a collection of operations clients can invoke to manipulate, examine, or interact with objects in some fashion. (This is what distinguishes objects from passive data structures in a procedural language like C.) Ironically, this is also one area that frequently has zero impact in object database systems, since every OODBMS released thus far has zero ability to execute object behavior--only retrieve/store/modify a collection of objects.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Many object systems also support either an explicit or implicit form of &lt;em&gt;inheritance&lt;/em&gt;, in which an object &amp;quot;inherits&amp;quot; the properties of another, either &amp;quot;by value&amp;quot; (by creating full standalone copies of atoms from the parent in the child, such as what we see in Java or C# or C++) or &amp;quot;by reference&amp;quot; (by holding a reference to the parent, such as what we see in Javascript).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Shape analysis&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The one-way nature of references in object systems often creates some design opportunities and restrictions.&lt;/em&gt;&lt;/strong&gt; For example, in the following code:&lt;/p&gt;
&lt;p&gt;In other words, working with a Person type that looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;class Person {
    private String name;
    private Person spouse;
    private List&amp;lt;Person&amp;gt; children;
}

Person ted = new Person(&amp;quot;Ted&amp;quot;);
Person charlotte = new Person(&amp;quot;Charlotte&amp;quot;);
ted.spouse = charlotte;
charlotte.children.append(new Person(&amp;quot;Michael&amp;quot;));
charlotte.children.append(new Person(&amp;quot;Matthew&amp;quot;));
ted.children = charlotte.children; // deliberately point to same List
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... not only is marriage not implicitly reflexive, but neither is parentage.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Inheritance is another form of object association.&lt;/em&gt;&lt;/strong&gt; Like the other forms, this associative relationship is usually one way; that is, children know their parents but not the other way around. In O-O programming, the parent can remain entirely ignorant of any derived classes through the use of dynamic dispatch (virtual methods), but this doesn&apos;t typically apply as a need in an object database. (An object query language obviates much of the need here.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;While identity often appears in other storage systems&lt;/em&gt;&lt;/strong&gt; (most notably relational databases, where identity is captured via primary key)***, in object systems it tends to be more subtle***, where the object identifier (OID) is often implicitly defined and stored. (This is similar to the &amp;quot;ROWID&amp;quot; that is often found in relational tables that serves as the unique identifier for the row in the table, regardless of primary key definitions.) This implicit identity can sometimes be a little confusing around objects that are equivalent but not identical, in the same way that it can be confusing in object languages.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Most object databases supported some form of query language&lt;/em&gt;&lt;/strong&gt;, either a SQL derivative and/or utilizing the syntax of the programming language (&lt;a href=&quot;https://en.wikipedia.org/wiki/Db4o&quot;&gt;db4o&lt;/a&gt; called this &apos;naive&apos; queries), and/or using a language-level API to build an exemplar object by which to search (called &apos;query by example&apos; or QBE). This also often included a subtle parameter called &amp;quot;fetch depth&amp;quot;, which essentially described how many object-association &amp;quot;links&amp;quot; to go down when retrieving the graph of objects to retrieve. For example, a fetch depth of 0 meant fetch the object queried and nothing else (leaving any associations empty or lazily-loaded), whereas a fetch depth of 1 meant fetch the object queried as well as the objects directly referenced from that object, and a fetch depth of 2 meant go to the objects directly referenced from the objects directly referenced from the object queried, and so on.&lt;/p&gt;
&lt;p&gt;In other words, working with a Person type that looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;class Person {
    private String name;
    private Person spouse;
    private List&amp;lt;Person&amp;gt; children;
}

Person ted = new Person(&amp;quot;Ted&amp;quot;);
Person charlotte = new Person(&amp;quot;Charlotte&amp;quot;);
ted.spouse = charlotte; charlotte.spouse = ted;
charlotte.children.append(new Person(&amp;quot;Michael&amp;quot;));
charlotte.children.append(new Person(&amp;quot;Matthew&amp;quot;));
ted.children = charlotte.children; // deliberately point to same List
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We would get a graph that looks like:&lt;/p&gt;
&lt;pre class=&quot;mermaid&quot;&gt;
flowchart TB
    ted[Ted]--&gt;charlotte[Charlotte]
    charlotte--&gt;ted
    ted--&gt;kids[List]
    charlotte--&gt;kids
    kids--&gt;michael[Michael]
    kids--&gt;matthew[Matthew]
&lt;/pre&gt;
&lt;p&gt;Note that if Persons know their parents, things get pretty messy pretty fast:&lt;/p&gt;
&lt;pre class=&quot;mermaid&quot;&gt;
flowchart TB
    ted[Ted]--&gt;charlotte[Charlotte]
    charlotte--&gt;ted
    ted--&gt;kids[List]
    charlotte--&gt;kids
    kids--&gt;michael[Michael]
    michael--&gt;ted
    michael--&gt;charlotte
    kids--&gt;matthew[Matthew]
    matthew--&gt;ted
    matthew--&gt;charlotte
&lt;/pre&gt;
&lt;p&gt;But this also highlights that in an object system, there is not a single well-defined root/starting point. The collection of objects can, and frequently is, a cyclic graph that can be &amp;quot;entered&amp;quot; (for query purposes) from anywhere--this is in contrast to associative systems (where we can only query by the key) or hierarchical systems (where we must work from the document&apos;s root node on down).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Most object database query engines also understand inheritance implicitly&lt;/em&gt;&lt;/strong&gt;, so in a simple hierarchy like this:&lt;/p&gt;
&lt;pre class=&quot;mermaid&quot;&gt;
classDiagram
    class Animal
    Vehicle &lt;|-- Car
    Vehicle &lt;|-- Boat
    Vehicle &lt;|-- Airplane
&lt;/pre&gt;
&lt;p&gt;... the database understood that a query of &amp;quot;select all Vehicles&amp;quot; would retrieve Car instances, Boat instances, and Airplane instances, as well as any Vehicle instances. This could lead to some very fine-grained queries (&amp;quot;select all Vehicles that have a passenger compartment of 1 and a range of over 500 miles except for motorcycles and rocket ships&amp;quot;), which could also create some indexing nightmares.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;In many cases, an object database could only retrieve whole objects&lt;/em&gt;&lt;/strong&gt;, even if only a subset of the object graph was necessary/desired to satisfy the request. This could lead to some performance issues, but from a design perspective mostly meant that any activity had to be thought in terms of &amp;quot;whole objects&amp;quot;. For example, we often employ a &amp;quot;master-detail&amp;quot; approach, where we fetch a list of entities (such as students at a university) and display their identifying characteristics (first and last name, and student identifier) in a large list, prompting the user to select one for in-depth (displaying all of the selected student&apos;s information) examination. In a system which supports &amp;quot;partial results&amp;quot;, such as SQL where we can &amp;quot;select id, fname, lname from students&amp;quot; and retrieve only three columns out of however many are defined on students, we can efficiently retrieve only the data we wish to display on that &amp;quot;master&amp;quot; UI. In a &amp;quot;whole results&amp;quot; system like a traditional object store, we have to fetch all of the student objects, displaying first the full collection&apos;s first and last names then after that the selected student&apos;s details. This means fetching the entirety of the student object in the bulk query, but also means no further round trips to the storage engine are required.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Thought Experiment: We often saw the desire in database systems for local code execution within the same node or process as the database server--in the RDBMS world we call them &amp;quot;stored procedures&amp;quot; and managed them through the database SQL interface--but the same concept never really took off within the OODBMS, where it would make actually much more sense. Some object query languages could invoke an object method as part of a query expression, but in general that didn&apos;t allow for object modification. It&apos;s intriguing to imagine what the overall experience of an OODBMS would be like if it could be a full object execution node, and not just data storage. Might even start resembling more of the old &amp;quot;distrubed objects&amp;quot; space, which is both a good thing and a bad thing....&lt;/p&gt;
&lt;p&gt;Thought Experiment: Although unconventional, we&apos;ve found in the hierarhical database world (namely, XML) that a query language (XPath) used against an in-memory collection of entities (an Infoset document, usually in a DOM) to be a powerful way to interact with only the dataset I&apos;m interested in. Curiously, what would happen if we tried to apply a similar thought process to large in-memory object collections? Feels like it could be useful....&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Implementations&lt;/h3&gt;
&lt;p&gt;A full list of object databases, apparently all of which remain in current use, can be found at &lt;a href=&quot;https://db-engines.com/en/ranking/object+oriented+dbms&quot;&gt;https://db-engines.com/en/ranking/object+oriented+dbms&lt;/a&gt; . Note that this list does mix multi-model databases with object ones, which seems to be a common theme in a lot of lists like this.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;db4o - Used to be an open-source product from a company of the same name, then Versant bought them, released one or two more versions, then abandoned it. Last source drop (2015) is available at &lt;a href=&quot;https://sourceforge.net/projects/db4o/&quot;&gt;SourceForge&lt;/a&gt;, though there&apos;s some GitHub mirrors out there too.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.objectdb.com/&quot;&gt;ObjectDB&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Sadly, wandering through object-shaped datastore implementations is like walking through a graveyard in the middle of the night--so many reactions of the &amp;quot;Oh, man, I&apos;m sad to see them gone&amp;quot; and &amp;quot;Oh, what might&apos;ve been if only....&amp;quot; sort.&lt;/em&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Shapes of Data: Hierarchical</title>
      <link>http://blogs.newardassociates.com/blog/2025/the-shapes-of-data-hierarchical.html</link>
      <pubDate>Sun, 2 Feb 2025 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2025/the-shapes-of-data-hierarchical.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Hierarchically-shaped data is characterized around strictly acyclic data that are arranged in a parent-child relationship, starting from a single well-known root data node. The relationship between nodes is explicit, with the roles of parent and child clearly delineated, but the actual association between parent and child is typically implicit and immutable.&lt;/p&gt;
&lt;!--more--&gt;
&lt;!-- Let&apos;s use some MermaidJS for some diagrams here, shall we? --&gt;
&lt;script type=&quot;module&quot;&gt;
import mermaid from &apos;https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs&apos;;
mermaid.initialize({ startOnLoad: true });
&lt;/script&gt;
&lt;h3&gt;Refresher&lt;/h3&gt;
&lt;p&gt;Hierarchical data is most easily recognized as a &amp;quot;tree&amp;quot;, such as that taught in every Computer Science course anywhere, where a well-defined root node has pointers to child nodes, each of which is also potentially a parent to other child nodes, &lt;em&gt;ad infinitum&lt;/em&gt; (or at least until we run out of memory). In the data world, this is most easily seen in the &lt;a href=&quot;https://www.w3.org/TR/2004/REC-xml-infoset-20040204/&quot;&gt;XML Infoset&lt;/a&gt;, which is an abstract discussion and description of this hierarhical model.&lt;/p&gt;
&lt;p&gt;Careful readers of the Infoset specification will note that the descriptions are all abstract and at no point refer to &amp;quot;tags&amp;quot; or &amp;quot;angle-brackets&amp;quot;; the traditional thinking around XML, that of a markup syntax similar to HTML, is but one way of serializing an Infoset document, and some of the later attempts at &lt;a href=&quot;https://en.wikipedia.org/wiki/Binary_XML&quot;&gt;binary&lt;/a&gt; &lt;a href=&quot;https://www.ibm.com/support/pages/binary-xml-specification&quot;&gt;XML&lt;/a&gt; &lt;a href=&quot;https://learn.microsoft.com/en-us/openspecs/sql_server_protocols/ms-ssas/2b2a5c94-769e-4039-bef8-4fdbeaa14ecc&quot;&gt;serialization&lt;/a&gt; serve as an interesting separation of &amp;quot;data model&amp;quot; from &amp;quot;data representation&amp;quot;.&lt;/p&gt;
&lt;p&gt;However, while many readers will be willing to accept XML as the canonical example of hierarchical data, they may not be quite so willing to accept the link between &amp;quot;JSON&amp;quot; or document databases as hierarchical data formats. I make this assertion based on the following axiomatic statements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;JSON documents start from a well-formed root.&lt;/strong&gt; Any JSON document must start with either an array (&lt;code&gt;[...]&lt;/code&gt;) or object (&lt;code&gt;{ ... }&lt;/code&gt;). Any attempt to have multiple roots in a JSON document is considered an error and unparsable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;JSON documents can only represent parent-child associates.&lt;/strong&gt; A JSON document cannot have a cyclic graph anywhere within it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both of these statements can be verified either by casual reading of the &lt;a href=&quot;https://ecma-international.org/publications-and-standards/standards/ecma-404/&quot;&gt;JSON specification&lt;/a&gt;, also explained in more graphical and plain prose &lt;a href=&quot;https://www.json.org/json-en.html&quot;&gt;here&lt;/a&gt;, and/or casual experimentation at the &lt;a href=&quot;https://jsonlint.com/&quot;&gt;JSON linter&lt;/a&gt; website.&lt;/p&gt;
&lt;p&gt;In addition, with respect to document databases, we note that a given document database, such as MongoDB or CouchDB, is formed of collections of documents, and each collection, like JSON itself, can be seen as an array of these JSON documents, such that the collection now serves as its own root. The database as a whole is often modeled in turn as a collection-of-collections, making the whole &amp;quot;collection of collections of documents&amp;quot; a hierarchical model, particularly when we consider that none of the popular document databases offer any &amp;quot;pointer&amp;quot; data types that can be silently traversed during query/retrieval.&lt;/p&gt;
&lt;h3&gt;Shape analysis&lt;/h3&gt;
&lt;p&gt;The shape of hierarchical data is wrapped, not surprisingly, around the top-down nature of a hierarchy. That is to say, that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;there is one well-known and well-formed root that serves as the starting point for navigation&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;every node, with the exception of the root, has a parent, and may have children; no other references, such as to siblings, are present&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;no cyclic references are allowed; in particular, no node may have a child node that is also its parent (or grandparent or great-grandparent or ...)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;data is typically stored as nodes in the tree, sometimes with &amp;quot;special&amp;quot; flags&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;in some hierarchical stores (notably XML), each node may have one or more name-value pairs further describing the node (XML calls these &lt;em&gt;attributes&lt;/em&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The hierarchical nature of the data, then, makes it an excellent choice for managing &amp;quot;top-down&amp;quot; kinds of systems, a la&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;company hierarchies&lt;/li&gt;
&lt;li&gt;military organization&lt;/li&gt;
&lt;li&gt;decision trees&lt;/li&gt;
&lt;li&gt;biological taxonomies&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ironically, though, some of the data systems that start out feeling hierarchical, like human genealogy charts (I mean, parents have children, the end, right?) actually turn out to not be strictly hierarchical, owing largely to the fact that marriages can be dissolved, spouses can die, children can marry their uncles, and even more bizarre behavior. (I invite anyone who thinks a genealogical tree can be best represented as a hierarchy to map out the English royalty of the 1500s through the 1900s in a nice, well-ordered, singly-rooted tree--just try to figure out who the root is, to start!)&lt;/p&gt;
&lt;p&gt;One thing that&apos;s interesting is that hierarchical data is actually one of the &lt;em&gt;oldest&lt;/em&gt; ways to model information, which is partly why we have such an easy familiarity with it. We see hierarchies everywhere we turn in life, and as such it becomes an easy tool to reach for. Trying, however, to model a hierarchy in a relational database, as we often tried to do in the late 90s/early 00s, usually ended up in a massively complicated system, where much fo the complexity lay in navigating the hierarchy. This was partly why XML was viewed as such a godsend when it emerged as a data-centric tool in the early 00s. Pain points with XML led to the desire for a &amp;quot;simpler&amp;quot; approach, which led to JSON, which is just another hierarchy but with fewer options. (And it uses curly braces, which is more comforting to C++/C#/Java developers anyway.)&lt;/p&gt;
&lt;p&gt;One other important note about hierarchical systems is that they are &lt;em&gt;not&lt;/em&gt; intrinsically object systems. It&apos;s a common mischaracterization, since we often see classes in hierarchies (particulary inheritance-based), and a node can have attributes, just like objects can have fields. However, in an object system we can have a reference to another object--any other object--within the system without regard for its relationship to this object. This allows us to create cyclic graphs (among other things) which are impossible to represent accurately in a strict hierarchy.&lt;/p&gt;
&lt;p&gt;For example, imagine the classic Person object:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Person {
    String firstName;
    String lastName;
    int age;
}
ted = new Person(&amp;quot;Ted&amp;quot;, &amp;quot;Neward&amp;quot;, 50);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is pretty straightforward, whether Java or C# or C++ (or some other object language). If we try to model this in a hierarchy, it seems to flow well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;person&amp;gt;
    &amp;lt;firstname&amp;gt;Ted&amp;lt;/firstname&amp;gt;
    &amp;lt;lastname&amp;gt;Neward&amp;lt;/lastname&amp;gt;
    &amp;lt;age&amp;gt;50&amp;lt;/age&amp;gt;
&amp;lt;/person&amp;gt;

{
    &amp;quot;ted&amp;quot;: {
        &amp;quot;firstName&amp;quot;: &amp;quot;Ted&amp;quot;,
        &amp;quot;lastName&amp;quot;: &amp;quot;Neward&amp;quot;,
        &amp;quot;age&amp;quot;: 50
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But when we represent the fact that Persons can get married, we encounter this object-relationship conundrum:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Person {
    String firstName;
    String lastName;
    int age;
    Person spouse;
}

ted = new Person(&amp;quot;Ted&amp;quot;, &amp;quot;Neward&amp;quot;, 50);
charlotte = new Person(&amp;quot;Charlotte&amp;quot;, &amp;quot;Neward&amp;quot;, 39);
ted.spouse = charlotte;
charlotte.spouse = ted;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We would get a graph that looks like:&lt;/p&gt;
&lt;pre class=&quot;mermaid&quot;&gt;
flowchart TB
    ted[Ted]--&gt;charlotte[Charlotte]
    charlotte--&gt;ted
&lt;/pre&gt;
&lt;p&gt;But the hierarchical model gets twisted--we have to have a single root, so naively we would think that maybe we nest the &amp;quot;spouse&amp;quot; Person inside of the Person that references it, but that runs into the basic fact that there&apos;s two Person objects, so which is the root object? Which of these two spouses is &amp;quot;on top&amp;quot;, so to speak? XML is going to get stuck right there, but JSON stands up and says, &amp;quot;Aha! I&apos;m not a problem, watch!&amp;quot;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &amp;quot;ted&amp;quot;: {
        &amp;quot;firstName&amp;quot;: &amp;quot;Ted&amp;quot;,
        &amp;quot;lastName&amp;quot;: &amp;quot;Neward&amp;quot;,
        &amp;quot;age&amp;quot;: 50
        &amp;quot;spouse&amp;quot;: &amp;quot;charlotte&amp;quot;
    },
    &amp;quot;charlotte&amp;quot;: {
        &amp;quot;firstName&amp;quot;: &amp;quot;Charlotte&amp;quot;,
        &amp;quot;lastName&amp;quot;: &amp;quot;Neward&amp;quot;,
        &amp;quot;age&amp;quot;: 39,
        &amp;quot;spouse&amp;quot;: &amp;quot;ted&amp;quot;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... except that this is ducking the problem entirely, because JSON doesn&apos;t actually know about the relationship between these two objects--the &amp;quot;ted&amp;quot; and &amp;quot;charlotte&amp;quot; are essentially object identifiers (OIDs) that whomever or whatever is deserializing this JSON has to put bback together &amp;quot;by hand&amp;quot;. This also means that the top-level of the JSON document becomes a flat namespace in which all of the Persons in the system are stored, with no intrinsic hierarchy to the data whatsoever. We can do the exact same thing with XML, by the way, if we chose to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;objects&amp;gt;
    &amp;lt;Person oid=&amp;quot;ted&amp;quot;&amp;gt;
        &amp;lt;firstname&amp;gt;Ted&amp;lt;/firstname&amp;gt;
        &amp;lt;lastname&amp;gt;Neward&amp;lt;/lastname&amp;gt;
        &amp;lt;age&amp;gt;50&amp;lt;/age&amp;gt;
        &amp;lt;spouse reference=&amp;quot;charlotte&amp;quot; /&amp;gt;
    &amp;lt;/Person&amp;gt;
    &amp;lt;Person oid=&amp;quot;charlotte&amp;quot;&amp;gt;
        &amp;lt;firstname&amp;gt;Charlotte&amp;lt;/firstname&amp;gt;
        &amp;lt;lastname&amp;gt;Neward&amp;lt;/lastname&amp;gt;
        &amp;lt;age&amp;gt;39&amp;lt;/age&amp;gt;
        &amp;lt;spouse reference=&amp;quot;ted&amp;quot; /&amp;gt;
    &amp;lt;/Person&amp;gt;
&amp;lt;/objects&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For whatever it&apos;s worth, this is a large part of the reason why the original SOAP specification (v1.1) punted on the details of how to represent an object hierarchy, and deferred that work to XML Schema (XSD), which then... punted on how to represent an object hierarchy in favor of being able to validate XML/hierarchical data. This &lt;em&gt;object-hierarchical impedance mismatch&lt;/em&gt; was a large part of why XML services were labeled as &amp;quot;too complicated&amp;quot; and &amp;quot;too messy&amp;quot; and got everybody excited about JSON, which... punts on capturing object references just like XML did. But now we don&apos;t care as much for some reason.&lt;/p&gt;
&lt;p&gt;Note that if Persons know their parents, things get pretty messy pretty fast:&lt;/p&gt;
&lt;pre class=&quot;mermaid&quot;&gt;
flowchart TB
    ted[Ted]--&gt;charlotte[Charlotte]
    charlotte--&gt;ted
    ted--&gt;kids[List]
    charlotte--&gt;kids
    kids--&gt;michael[Michael]
    michael--&gt;ted
    michael--&gt;charlotte
    kids--&gt;matthew[Matthew]
    matthew--&gt;ted
    matthew--&gt;charlotte
&lt;/pre&gt;
&lt;p&gt;Representing this in XML is going to be flat-out impossible without out-of-band OIDs, and the same is true essentially of JSON.&lt;/p&gt;
&lt;p&gt;We can see each of these points quite clearly in the XML Infoset Specification, but as an exploratory discussion, let&apos;s consider the following XML document:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;department name=&amp;quot;Engineering&amp;quot;&amp;gt;
    &amp;lt;manager&amp;gt;
        &amp;lt;employee id=&amp;quot;1234&amp;quot;&amp;gt;
            &amp;lt;firstname&amp;gt;Fred&amp;lt;/firstname&amp;gt;
            &amp;lt;lastname&amp;gt;Flintstone&amp;lt;/lastname&amp;gt;
        &amp;lt;/employee&amp;gt;
    &amp;lt;/manager&amp;gt;
    &amp;lt;employee id=&amp;quot;2345&amp;quot;&amp;gt;
        &amp;lt;firstname&amp;gt;Barney&amp;lt;/firstname&amp;gt;
        &amp;lt;lastname&amp;gt;Rubble&amp;lt;/lastname&amp;gt;
    &amp;lt;/employee&amp;gt;
&amp;lt;/department&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have a single root node, the &lt;code&gt;department&lt;/code&gt; node. It has associated with it several children: two &amp;quot;element&amp;quot; nodes (one containing the &amp;quot;manager&amp;quot; node and one containing the &amp;quot;employee&amp;quot; node) and an &amp;quot;attribute&amp;quot; node (&amp;quot;name&amp;quot;). The Infoset is quite clear that these nodes aren&apos;t classified as &amp;quot;manager&amp;quot; or &amp;quot;employee&amp;quot;, but as XML-typed nodes (&amp;quot;element&amp;quot;, &amp;quot;attribute&amp;quot;) which in turn have descriptors that convey the parts that we has humans recognize (an &amp;quot;element&amp;quot; has a &amp;quot;name&amp;quot; containing the text that appears between the angle brackets). The text &amp;quot;Fred&amp;quot; is itself in a &amp;quot;text&amp;quot; node, although technically these could be four sibling &amp;quot;text&amp;quot; nodes, each containing &amp;quot;F&amp;quot;, &amp;quot;r&amp;quot;, &amp;quot;e&amp;quot;, and &amp;quot;d&amp;quot; respectively.&lt;/p&gt;
&lt;p&gt;As with the example, we often think about company organization/topology as a strictly-hierarchical arrangement, but this practice frequently falls down in the face of experience--companies will sometimes have co-CEOs, &amp;quot;matrix&amp;quot;ed teams, and even sometimes have employees reporting to more than one manager/department simultaneously.&lt;/p&gt;
&lt;h3&gt;Query capabilities&lt;/h3&gt;
&lt;p&gt;Querying a hierarchical system historically was a matter of writing a bunch of navigational code by hand, maneuvering up and down the tree as desired, until the XPath (and later XQuery) specification(s) appeared, describing a query language that had at its core the foundational knowledge of traversing the hierarchy. XPath uses a fundamental concept of one or more &amp;quot;expressions&amp;quot;, where each expression is evaluated to yield an object, which can be either an &amp;quot;atomic data value&amp;quot; (boolean, number, or string) or a &amp;quot;node-set&amp;quot; (a collection of non-duplicate nodes). Each expression&apos;s yield is then carried over into the subsequent expression as part of a stateful &amp;quot;context&amp;quot; which is then used to evaluate the next expression. These expressions, known as &amp;quot;location steps&amp;quot;, are formed of an &amp;quot;axis&amp;quot;, a &amp;quot;node test&amp;quot;, and zero or more &amp;quot;predicates&amp;quot;, which further restrict the path.&lt;/p&gt;
&lt;p&gt;So, for example, an XPath of &lt;code&gt;/child::*&lt;/code&gt; evaluates the &amp;quot;child&amp;quot; axis (which means &amp;quot;examine the current node&apos;s immediate child nodes&amp;quot;), and the &amp;quot;node test&amp;quot; of &amp;quot;&lt;em&gt;&amp;quot; (which means &amp;quot;accept anything&amp;quot;), yielding that singular &amp;quot;department&amp;quot; node. (Technically the &amp;quot;/&amp;quot; is itself a location path, meaning &amp;quot;take the root node&amp;quot;, which is what forms the context of the subsequent &amp;quot;child::&lt;/em&gt;&amp;quot; step.) This leads to a mental model that feels similar to filesystem directory paths; however, unlike on a filesystem, we can have multiple nodes returned as part of a query. Thus, &lt;code&gt;/descendant::*&lt;/code&gt; query will return every node in the document, regardless of its location in the tree. If we then write &lt;code&gt;/descendant::*/name()&lt;/code&gt;, we will ask every node in the tree for its name.&lt;/p&gt;
&lt;p&gt;Unfortunately, one of the biggest weaknesses with a hierarchical query capability is often not with the query language, but wtih the perception of those who use it--because they often see parallels between &amp;quot;filesystem hierarchy&amp;quot; and &amp;quot;data hierarchy&amp;quot;, they implicitly assume that a language such as XPath yields only a single node at each &amp;quot;step&amp;quot; in the query resolution process, when in fact each resolution can be a collection; in other words, if filesystem shells supported this kind of behavior, we could do something like &lt;code&gt;ls -la /usr/lib/*/lib*.sa&lt;/code&gt; and get back all of the files prefixed with &lt;code&gt;lib&lt;/code&gt; and having an extension &lt;code&gt;sa&lt;/code&gt; in any directory that is a child of &lt;code&gt;/usr/lib&lt;/code&gt;. Frankly that&apos;s super-powerful, but it takes a moment to wrap one&apos;s mind around it sometimes.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Shapes of Data: Associative</title>
      <link>http://blogs.newardassociates.com/blog/2025/the-shapes-of-data-associative.html</link>
      <pubDate>Sat, 1 Feb 2025 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2025/the-shapes-of-data-associative.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; The shape of data that&apos;s associative, or the key-value data store, is a style of single-dimensional, making the key the biggest part of the shape.&lt;/p&gt;
&lt;!--more--&gt;
&lt;!-- Let&apos;s use some MermaidJS for some diagrams here, shall we? --&gt;
&lt;script type=&quot;module&quot;&gt;
import mermaid from &apos;https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs&apos;;
mermaid.initialize({ startOnLoad: true });
&lt;/script&gt;
&lt;h3&gt;Refresher&lt;/h3&gt;
&lt;p&gt;In a key-value store, like Redis, data is stored in a collection made up of tuples of keys and values. Keys must always be unique, at least within a single &amp;quot;database&amp;quot;. (Some data stores may support multi-tenancy &amp;quot;databases&amp;quot;, where each is entirely isolated from one another.) Keys are typically complex data types in their own right, often made up of multiple parts, much like filesystem directory paths are made up of pieces. Values are not given any special treatment within the database, treated entirely as an opaque binary byte array.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Key &lt;/th&gt;&lt;th&gt; Value&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;K1  &lt;/td&gt;&lt;td&gt; AAA&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;K2  &lt;/td&gt;&lt;td&gt; Call me Ishmael.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;K3  &lt;/td&gt;&lt;td&gt; CCC123DDD456&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Different key-value stores will have different semantics around this fundamental data structure. Some will treat the parts of the key as a physical segregation of the dataset into smaller (and more easily retrieved) collections, while others will keep all the tuples in one large collection. Still others may allow for distinct collections, essentially providing a means to provide multi-tenancy, similar to how a relational database can host different named &amp;quot;databases&amp;quot; each with its own schema.&lt;/p&gt;
&lt;p&gt;Key-value stores typically are entirely schemaless beyond the basic key-value data structure. Because the database infers no structure on the value, the values themselves have no database-enforced requirements on length, content, or structure.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A Thought Experiment: A schema&apos;ed key-value store could put schematic requirements on the value, verifying that the value follows some kind of file format, like BMP or JPG, or other binary format, like Java or .NET object serialization formats. Describing the binary formatting requirements would necessitate a highly-flexible descriptor language, maybe something akin to how other binary formats are specified (there&apos;s a history of different formats and IDLs here to choose from), and it would ideally be something open-ended to allow for pluggable run-time verification (maybe), but the idea is intriguing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Query capabilities&lt;/h3&gt;
&lt;p&gt;This one&apos;s pretty easy, since realistically, there are none: the database typically allows for retrieval of the value by looking up the key, and that&apos;s it.&lt;/p&gt;
&lt;p&gt;Some databases will return a multivalued response, allowing the query to put wildcards in for some part of the key (much as &lt;code&gt;ls /Users/Ted/Documents/*&lt;/code&gt; returns a list of the files and directories in that location).&lt;/p&gt;
&lt;p&gt;Because the associative data shape doesn&apos;t do any inference in the value half of the tuple, there&apos;s really little to nothing we can do with anything except the key itself. The key, as noted earlier, can be seen as a kind of partitioning element to segregate the collection(s) in some sort of logical manner, but fundamentally this is a hierarchical partitioning, at best.&lt;/p&gt;
&lt;p&gt;As for the value, most (if not all) associative data stores support zero sort of filtering criteria on the value. We query on the key--that&apos;s it.&lt;/p&gt;
&lt;h3&gt;Shape analysis&lt;/h3&gt;
&lt;p&gt;In many respects, the programming model here is very similar as the &amp;quot;untyped collections&amp;quot; that popularized the Java and .NET communities early in their respective lifecycles (C#/.NET 1.0, where Java didn&apos;t get strongly-typed collections until Java5). In both Java and C#, programmers clamored for type-parameterizable collections, citing the concern over errors introduced by accidental insertion of unanticipated types in the collections held. However, it&apos;s also important to note that in the &amp;quot;untyped&amp;quot; programming languages Javascript, Python, and Ruby, the same call for type-safety hasn&apos;t been as strong, likely because those developers write their code in such a way to verify their expectations before use.&lt;/p&gt;
&lt;p&gt;With the compound nature of keys, different &amp;quot;parts&amp;quot; of the key can be hierarchically variable; for example, if the stored value is &amp;quot;user session data&amp;quot;, the key can be written to consist of both static and variable parts, the static being &lt;code&gt;users&lt;/code&gt; and the variable being the user profile ID, such that the overall appearance of the key looks like &lt;code&gt;users:{user-profile-ID}&lt;/code&gt;. This can also easily mirror what we see in URL slugs, a la &lt;code&gt;topic:{topic-name}:articles:{article-id}&lt;/code&gt;. &lt;em&gt;So long as the key&apos;s parts are inherently hierarchical, the key makes for a convenient means to segregate the space.&lt;/em&gt; As a result, any desirable filter criteria should be encoded into the key.&lt;/p&gt;
&lt;p&gt;As one of the simplest &amp;quot;shapes&amp;quot; in the database world, the associative shape&apos;s entire ignorance of the value offers some interesting options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;rather than being seen as a single value, the value can instead be an open-ended collection of values, such as a list or an array. Here we assume either some sort of structure or defining element markers (such as the comma in a comma-delimited list) which the programmer will parse after retrieving.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;in a logical extension of the above, we can treat the value associated with a specific key as an &amp;quot;append-only&amp;quot; and/or &amp;quot;growable&amp;quot; storage--take the value, append additional data to it, and re-store it under the same key.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;the extreme flexibility of values means the keyspace can be entirely heterogenous, storing &amp;quot;a little bit of anything&amp;quot;, creating an unparalleled flexibility, but which in turn will require the most amount of programmer-required validation, verification, or maintenance, because the database offers absolutely zero guarantees about what can (or is) stored. This flexibility is also what makes associative datastores popular as caching systems.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Tuple_space&quot;&gt;&lt;em&gt;tuplespace&lt;/em&gt;&lt;/a&gt; systems, as exemplified by the academic sysem Linda and its semi-commercial spinoffs TSpaces (from IBM) and JavaSpaces (from Sun) were essentially associative storage, using the identity of an object (extended in this case to include the node in the network from whence it came) as the key and a serialized (often binary, using the object serialization capabilities of the Java language) representation of the object as the value. Microsoft&apos;s &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/orleans/overview&quot;&gt;Orleans&lt;/a&gt; seems to be operating along similar lines, calling the key-value tuple a &amp;quot;grain&amp;quot; and offering several different flavors of keys:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;* IGrainWithGuidKey: Marker interface for grains with Guid keys.
* IGrainWithIntegerKey: Marker interface for grains with Int64 keys.
* IGrainWithStringKey: Marker interface for grains with string keys.
* IGrainWithGuidCompoundKey: Marker interface for grains with compound keys.
* IGrainWithIntegerCompoundKey: Marker interface for grains with compound keys.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because of the specific key-based nature of the database operations, &lt;strong&gt;&lt;em&gt;most associative stores are extremely fast, and often highly scalable&lt;/em&gt;&lt;/strong&gt;, since the likelihood of two separate processes operating on the same key are highly unlikely. Some databases will, in fact, trust the developer to manage concurrency entirely. This also suggests that the data stored in an associative system should be more or less independent of one another, since &lt;em&gt;modifying two key-value tuples at once may not have transactional semantics&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;Variant: Tupled data stores&lt;/h3&gt;
&lt;p&gt;A variant of the associative data approach is that of the &amp;quot;tupled&amp;quot; data, such as an &lt;a href=&quot;https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model&quot;&gt;Entity-value-attribute mode&lt;/a&gt; store, or a &lt;a href=&quot;https://en.wikipedia.org/wiki/Triplestore&quot;&gt;&amp;quot;triplestore&amp;quot;&lt;/a&gt;, such as RDF triplets. Here, the association is a multi-part mesh of data elements, such as in RDF, which is &amp;quot;subject-predicate-object&amp;quot; (a la &amp;quot;Bob is 35&amp;quot; or &amp;quot;Bob knows Fred&amp;quot;), or more formally in the entity-attribute-value model, wherein an &lt;em&gt;entity&lt;/em&gt; has an &lt;em&gt;attribute&lt;/em&gt; that holds a &lt;em&gt;value&lt;/em&gt; (such as &amp;quot;Bob-age-35&amp;quot; or &amp;quot;Bob-list(knows)-[Fred, Barney, Wilma]&amp;quot;).&lt;/p&gt;
&lt;p&gt;The interesting thing about these &amp;quot;tupled data shapes&amp;quot; is that they are significantly flexible, since the metadata is inherent in the structure; a &amp;quot;Person&amp;quot;, for example, would be an object consisting of three tuples or entity-attribute-value triplets, so that the &amp;quot;person&amp;quot; object would look something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ted-firstname-&amp;quot;Ted&amp;quot;
ted-lastname-&amp;quot;Neward&amp;quot;
ted-age-50
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In some ways, this feels like a traditional object-field-value, but the inherent dynamic nature of the tuples means that not every &amp;quot;person&amp;quot;-shaped object must have the same set of attributes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cher-name-&amp;quot;Cher&amp;quot;
cher-age-&amp;quot;timeless&amp;quot;

meghan-firstname-&amp;quot;Meghan&amp;quot;
meghan-lastname-&amp;quot;Markle&amp;quot;
meghan-title-&amp;quot;Princess&amp;quot;
meghan-court-&amp;quot;England&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;More importantly, each of these is (somewhat) independent of any others, we can add new tuples/triplets at any point, making this effectively a highly &amp;quot;dynamically-typed&amp;quot; way to think about the organization of data and objects. That said, thogh, it&apos;s still important to remember that these are not &amp;quot;objects&amp;quot;, per se, but a list, essentially of tuples/triplets that, taken collectively, can be viewed as objects.&lt;/p&gt;
&lt;p&gt;Or, if desired, as tables:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1-firstname-&amp;quot;Ted&amp;quot;
1-lastname-&amp;quot;Neward&amp;quot;
1-age-50
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... where we assume the &amp;quot;entity&amp;quot; in the entity-attribute-value tuple is a primary key value.&lt;/p&gt;
&lt;p&gt;The reason this feels like it falls under the associative data style is that we can map another tuple, like &lt;code&gt;person-primarykey-1&lt;/code&gt;, which, so long as this tuple is unique to the associative store, we gain an interesting degree of flexibility. We can also imagine that tuple as parts of the key, as well, such that we can envision the data looking like the following:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Key &lt;/th&gt;&lt;th&gt; Value&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;person / 1 / firstname &lt;/td&gt;&lt;td&gt; &amp;quot;Ted&amp;quot;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;person / 1 / lastname &lt;/td&gt;&lt;td&gt; &amp;quot;Neward&amp;quot;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;person / 1 / age &lt;/td&gt;&lt;td&gt; 50&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;person / 2 / name &lt;/td&gt;&lt;td&gt; &amp;quot;Cher&amp;quot;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;person / 3 / firstname &lt;/td&gt;&lt;td&gt; &amp;quot;Meghan&amp;quot;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;person / 3 / lastname &lt;/td&gt;&lt;td&gt; &amp;quot;Markle&amp;quot;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;person / 3 / title &lt;/td&gt;&lt;td&gt; &amp;quot;Princess&amp;quot;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;... and so on. This can create some interesting flexibility in structure.&lt;/p&gt;
&lt;h3&gt;Popular implementations &lt;sup id=&quot;fnref-1&quot;&gt;&lt;a class=&quot;footnote-ref&quot; href=&quot;#fn-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/h3&gt;
&lt;p&gt;In alphabetical order:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.aerospike.com/&quot;&gt;Aerospike&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/dynamodb/&quot;&gt;Amazon DynamoDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ignite.apache.org/&quot;&gt;Apache Ignite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://azure.microsoft.com/en-us/services/cosmos-db/&quot;&gt;Azure CosmosDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dgraph.io/badger&quot;&gt;BadgerDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.oracle.com/us/products/database/berkeley-db/overview/index.html&quot;&gt;BerkeleyDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.couchbase.com/&quot;&gt;Couchbase Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.dragonflydb.io/&quot;&gt;DragonflyDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://etcd.io/&quot;&gt;Etcd&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.foundationdb.org/&quot;&gt;FoundationDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cloud.google.com/datastore&quot;&gt;Google Cloud Datastore&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hazelcast.com/products/imdg/&quot;&gt;Hazelcast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/google/leveldb&quot;&gt;LevelDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.lmdb.tech/doc/&quot;&gt;LMDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.memcached.org/&quot;&gt;Memcached&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.oracle.com/database/technologies/related/nosql.html&quot;&gt;Oracle NoSQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tanzu.vmware.com/gemfire&quot;&gt;Pivotal GemFire&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/wbolster/plyvel&quot;&gt;Piyvel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://redis.io/&quot;&gt;Redis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://basho.com/products/riak-kv/&quot;&gt;Riak KV&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rocksdb.org/&quot;&gt;RocksDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.scylladb.com/&quot;&gt;ScyllaDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.tarantool.io/en/&quot;&gt;Tarantool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://unqlite.org/&quot;&gt;UnQLite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.project-voldemort.com/voldemort/&quot;&gt;Voldemort&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.yugabyte.com/&quot;&gt;YugabyteDB&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://www.dragonflydb.io/guides/key-value-databases&quot;&gt;https://www.dragonflydb.io/guides/key-value-databases&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

	</description>
    </item>
    <item>
      <title>Reflections on an Involuntary Sabbatical</title>
      <link>http://blogs.newardassociates.com/blog/2025/involuntary-sabbatical-reflections.html</link>
      <pubDate>Fri, 31 Jan 2025 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2025/involuntary-sabbatical-reflections.html</guid>
      	<description>
	&lt;p&gt;At the end of 2021, my time at Rocket Mortgage came to an (amicable) end; the things they had asked me to do were done (more or less--there was more work to be done, but others could pick it up and run with it), and the next things I thought worth doing at Rocket were not things they were interested in. So, we parted ways, and I set back off into the wild blue yonder to find my next role. What followed was what I call my &amp;quot;involuntary sabbatical&amp;quot;--three years of job hunting and interviewing, a bizarre mix of freedom and frustration, and more than a few &amp;quot;false starts&amp;quot; that felt solid yet evaporated. It&apos;s been quite possibly the strangest time of my career thus far.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Now, as I prepare to re-enter the full-time workforce, I find myself thinking and feeling and reflecting on the last three years, and I thought I&apos;d share because I live in the perpetual belief that somebody on the Internet might find this useful. (Or, perhaps, you just want a deeper insight into the maelstrom of crazy that is me.)&lt;/p&gt;
&lt;p&gt;Rather than try to string a narrative out of this, I think it a little easier to just post ad-hoc blurbs and admissions.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;This was not fun, but it wasn&apos;t terrible, and it might&apos;ve been necessary.&lt;/em&gt;&lt;/strong&gt; I think I got infected with the &amp;quot;I&apos;m in tech, I can get a job anytime I want&amp;quot; fever that I&apos;ve seen infect so many of us, and it was probably a good wake-up call. The tech sector isn&apos;t the same as it was--which is good, we were in a huge bubble, and arguably still are--and that means that everyone in it has to adjust their expectations for how long a job search at a senior executive level is going to take. (And I&apos;m nowhere near the top of the &amp;quot;executive level&amp;quot; to boot.) I probably still have one or two more of these in my future before official (voluntary!) retirement kicks in, but even if I spend the rest of my career at Capital One, I think it&apos;s important to realize that we aren&apos;t in &amp;quot;Oh, I&apos;ll just interview tomorrow and get a job&amp;quot; mode anymore.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Having alternative income streams is really helpful.&lt;/em&gt;&lt;/strong&gt; For the last three years (actually the past ten, but the last three are what&apos;s relevant here), I&apos;ve been teaching part-time at UW-Seattle, and that helped a great deal with expenses. Having that part-time gig helped extend the runway a lot. (Plus, it was nicely distracting and gave me something to be doing instead of climbing the walls and driving everyone around me crazy.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Three years is simultaneously forever and not that long.&lt;/em&gt;&lt;/strong&gt; In some ways, it feels like just yesterday that I was saying farewell to my teams at Rocket; in other ways, it feels like that was a lifetime ago. I can&apos;t tell if that&apos;s a factor of my age, the length of time between gigs, or what.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Ageism: Did it have a role in your search? How did you deal with it?&lt;/em&gt;&lt;/strong&gt; Oh, boy, this one. My wife and I are definitely split on this; she&apos;s convinced that it factored very heavily into comapanies&apos; evaluation of me for a role, and I&apos;m not as sure as she is. Sure, there&apos;s a fairly hefty amount of ageism in the industry, but most of that is in the &amp;quot;tech bro&amp;quot; sector, where the twenty-somethings who are bum-rushing the startup/VC/Y-Combinator scene are absolutely convinced that now that they are armed with {fill-in-the-blank-current-hot-thing} they have all the answers they need for any problem that beckons. Frankly, I have zero interest in working with those folks anyway, so if they&apos;re discriminating against me, it&apos;s probably pre-emptive (I&apos;d be discriminating against them in turn, in case that wasn&apos;t already obvious), reflexive (it&apos;s mutual discrimination), and convenient (saves us both some time).&lt;/p&gt;
&lt;p&gt;What I &lt;em&gt;do&lt;/em&gt; think is happening, though, is more economic in nature. Let&apos;s be honest, with 30+ years of software experience under my belt, if I&apos;ve made any progress at all in my career I&apos;m not cheap. If the job calls for somebody who&apos;s a mid-level manager and I apply for it (either deliberately or by mistake), I&apos;m very possibly overqualified--which in itself may not be a problem--and overcompensated--which is very definitely going to be a problem. Is that an ageist thing? No, except in that &amp;quot;very senior&amp;quot; will generally only be a label applicable to people who&apos;ve been around longer, and are therefore older.&lt;/p&gt;
&lt;p&gt;I&apos;m not saying ageism doesn&apos;t exist, and I&apos;m not saying that I haven&apos;t been on the receiving end of it--I can think of a few jobs where it &lt;em&gt;might&lt;/em&gt; have played a factor. But I can&apos;t tell for sure, and obviously no company on the planet is going to admit that out loud.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Consulting: Did you consider going back to (individual) consulting?&lt;/em&gt;&lt;/strong&gt; Well, in one sense, I absolutely did, because a few roles (including the one at Capital One) started with a contract relationship, sometimes deliberately as a let&apos;s-try-before-we-buy. I also did some spot consulting for companies that had no interest in me long-term (and vice versa, to be honest). But in general? Nah, I&apos;m not interested in trying to build out my consulting practice--frankly, I did it, I got the T-shirt, and I&apos;m very happy with the idea of working for somebody else, so long as I professionally respect that manager. That&apos;s what I&apos;ve discovered about me: Regardless of what the company does (with a few exceptions) or who runs it (with a few exceptions), I don&apos;t really care about the company. I care much more about the people around me in the company--who am I working for, who is working for me, who am I working with, and am I having some kind of impact there.&lt;/p&gt;
&lt;p&gt;That last point, by the way, I&apos;ve found to be way more important than I would&apos;ve guessed of myself ten or twenty years ago. It matters to me that I&apos;m making a difference inside the company, much more than what that actual difference is. I don&apos;t need to be saving the whales, but I do need to be making somebody else&apos;s life better somehow.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;LinkedIN is a terrible platform for finding a job.&lt;/em&gt;&lt;/strong&gt; Although this will come as no surprise to many people, I have determined that the social media platform that was ostensibly designed for professionals to engage with one another is now quite terrible at it. I can honestly say that in the three-year timeframe, after clicking the &amp;quot;EasyApply&amp;quot; button hundreds of times--choosing both to share my LinkedIN profile and fill in their online application form--I got exactly one interview out of it. (And that was to a game company early in 2022, which ironically was something of a &apos;why not&apos; kind of apply.) Even the &amp;quot;new model approach&amp;quot; to LinkedIN, where you not only click the EasyApply but message the CEO/CTO/hiring manager/recruiting manager/anybody-and-everybody–you-know-at-that-company, doesn&apos;t work. Maybe it&apos;s all the ghost job postings, maybe it&apos;s the fact that it&apos;s too easy for anybody to click the button, but whatever it is, LinkedIN as a vector to getting an interview and a job is pretty much entirely obsolete and probably should be shut down for many candidates. (Ironically, LinkedIN making it easier for people to apply did exactly that--made it easier for people to apply--and as a result now recruiters are swamped beyond any reasonable human capacity. Which means that LinkedIN didn&apos;t make it easier to apply, it just means that now the gates are further back.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Networking remains king.&lt;/em&gt;&lt;/strong&gt; Almost all the roles I got a chance to interview for came from my connections/network. Many of those connections came from staying in touch with people on LinkedIN, so I can&apos;t say that the platform is worthless, and it does help with a professional focus, so it&apos;s more effective to connect with other professional-type folks on LinkedIN than say BlueSky or Mastodon, so there&apos;s that. And to all of you who said, &amp;quot;Hey, I bet my company could use a little Ted in their life,&amp;quot; thank you! From the bottom of my heart, yours were the only real leads I ever got.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;AI doesn&apos;t help.&lt;/em&gt;&lt;/strong&gt; Seriously. Resumes written with AI are awful, entirely too easy to spot (from the recruiter&apos;s perspective), and don&apos;t catch anyone&apos;s eye (in terms of standing out from the crowd). Using AI as your interview buddy is also not a great tool--it takes too long to type in prompts, and trying to make the responses sound like natural spoken language is just... bad.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Full disclosure: I&apos;ve never actually done the &apos;cheat with ChatGPT&apos; in a real interview, but I did try it as a &apos;practice&apos; attempt--as in, I sat in my office when no one was around, and I played both sides of the interview. I asked myself a question, then typed it into ChatGPT and tried to read--aloud--the response in a way that didn&apos;t sound forced or awkward. Ironically, part of the problem is the fact that ChatGPT actually uses full sentences, which is the first clue that somebody&apos;s reading something out loud. Almost nobody does that in an impromptu spoken conversation. Seriously, listen to any interview on TV. We swtich thoughts in the middle of a sentence all the time, and rarely can we hear the punctuation in the response. It&apos;s why AI transcription services get so many things wrong--humans are nondeterministic!)&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Be prepared for an emotional rollercoaster.&lt;/em&gt;&lt;/strong&gt; It wasn&apos;t the first time I&apos;d been without a gig, so the first six to nine months were pretty chill--like most tech professionals, I sort of assumed that &amp;quot;something will come along&amp;quot;. (I mean, I didn&apos;t just sit back and wait for the offers to pour in, I&apos;m not &lt;em&gt;that&lt;/em&gt; arrogant.) But when it got to twelve months and nothing had worked out yet, I started getting a little nervous, and by about the eighteen-month mark, I got depressed. I knew, intellectually, that it wasn&apos;t just me--the market&apos;s been a mess since the pandemic started--but even then, &lt;em&gt;and&lt;/em&gt; with amazingly supportive spouse, family, and friends, it was still hard to not listen to those dark voices that said, &amp;quot;You&apos;re done, you&apos;re all washed up, you&apos;re worthless, nobody will ever hire you again, go pick out your spot under the freeway, you failed everyone you ever loved.&amp;quot; (Seriously, that&apos;s what my internal dark voice was saying.) It helped that I could give voice to that and have people around me react to that.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Keep in mind your friends want to help.&lt;/em&gt;&lt;/strong&gt; I admit it, sometimes my friends were more interested in being sympathetic when I wanted them to tell me how to fix it, and sometimes they tried to tell me how to fix it when I just wanted validation. It happens. It&apos;s not their fault, either. I&apos;m certain if I&apos;d said, &amp;quot;Hey, just validate me on this, eh?&amp;quot; they&apos;d have done so, or if I&apos;d asked, &amp;quot;How would you fix this?&amp;quot; they would make suggestions. Heck, once or twice I did ask for suggestions, and they did, or sometimes admitted they had no quick fixes for me. Key thing is, they were always trying to help, even if sometimes it wasn&apos;t what I wanted. (And, to be fair, sometimes I didn&apos;t realize what I&apos;d wanted until later in the conversation!) There were still times I got frustrated when they didn&apos;t give me what I was looking for, though, and it took a moment for me to remember that they couldn&apos;t know what to give me because I didn&apos;t ask.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;More to the point, friends show up.&lt;/em&gt;&lt;/strong&gt; More than anything else, though, what I&apos;ve figured out (I think) is that the real meaning of a friendship is that they just show up. They don&apos;t have to know what to say or do or how to fix things. They just have to show up. Most of the time, there really was nothing they could say or do. But having them show up, even if it was to just shoot the breeze or talk about their lives for a while, it was way more important than I&apos;d thought it would be.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;I should&apos;ve been more focused in my search.&lt;/em&gt;&lt;/strong&gt; I can do a lot of different things: architect/&amp;quot;thought leader&amp;quot; IC, VP Engineering, VP Developer Relations, CTO, and/or lead a practical R&amp;amp;D effort. (I&apos;ve done all of those things, though the titles varied from company to company, in keeping with their salary bands.) I initially thought that would be helpful, allowing me to shape myself to whatever-sized &amp;quot;hole&amp;quot; a company needed filling. &lt;strong&gt;NOPE.&lt;/strong&gt; It actually became a hindrance, as I found recruiter after recruiter who simply couldn&apos;t figure out what kind of role I was interviewing for. It got even worse when recruiters would ask, &amp;quot;What&apos;s your ideal role? What&apos;s the kind of things that make you get up in the morning?&amp;quot; (In other words, &amp;quot;What&apos;s your passion, so we can make sure this job has it so we don&apos;t have to worry about motivating you ever again?&amp;quot;) No matter how I answer that question, I was in trouble:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Honestly, as in, &amp;quot;I have all these different interests and thinigs I like to pursue.&amp;quot; Recruiter: &amp;quot;Wow, there&apos;s no way this role can give you all that. You&apos;re probably not a good fit. Thanks, and good bye.&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Clinically, as in, &amp;quot;Look, I&apos;m not trying to find a passion job, because I&apos;m seasoned enough of a veteran to know that no job is perfect, and I bring my &apos;A&apos; game no matter what the job has me doing.&amp;quot; Recruiter: &amp;quot;You&apos;re dodging my passion question, so you must not be super-pumped for this role. You&apos;re probably not a good fit. Thanks, and good bye.&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dishonestly, as in, &amp;quot;I have always longed to be working in a role just like this one.&amp;quot; Recruiter: &amp;quot;You sound &apos;off&apos;, like you&apos;re not being truthful or honest with me. Bringing your &apos;whole self&apos; to work is important to us. You&apos;re probably not a good fit. Thanks, and good bye.&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I eventually got to a point where I would just go through this little diatribe with the recruiter, and leave it at that. Which itself presented problems because now my answer doesn&apos;t fit on their scoring rubric and artificially marks my candidacy as less-appealing.&lt;/p&gt;
&lt;p&gt;What I probably should&apos;ve done is created six different forms of resume, one for each of the different kinds of things I was interested in doing, &amp;quot;tuned&amp;quot; to that particular role. Not job-specific, mind you, but a generalized &amp;quot;VP of Engineering resume&amp;quot;, a &amp;quot;CTO resume&amp;quot;, a &amp;quot;VP of DevRel resume&amp;quot;, and so on, taking a particular slant on the things I&apos;ve done and how my experience set me up well for that particular role.&lt;/p&gt;
&lt;p&gt;It really surprised me, discovering this, because I&apos;d always assumed that being multifaceted would be viewed as an asset to the company, but instead, it really played off as more of a liability. Despite the rhetoric, it really seems like companies are more interested in single-dimensional people than they are people with a variety of skills.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Speaking of interviewing, lots of companies do it really, really badly.&lt;/em&gt;&lt;/strong&gt; I had a few conversations with recruiters who were genuinely amazed at my resume, portfolio, books, and GitHub repositories... and then still insisted I needed to go do their LeetCode coding test. Seriously?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Also, I suck at interviewing.&lt;/em&gt;&lt;/strong&gt; I&apos;m not going to blame the companies entirely here; over the course of many of them, I&apos;ve come to realize that I am nowhere near as good at the skill as I&apos;d assumed. Had I to do it over again, if it were a job I really, really, &lt;em&gt;really&lt;/em&gt; wanted, I&apos;d practice it with somebody else. (Literally, write out the STAR-like interview questions, have somebody ask them, deliver the response, and then together workshop the result and try again if necessary.) For the record, I&apos;ve &lt;em&gt;never&lt;/em&gt; practiced interviewing before--and I probably lost a few jobs because of it.&lt;/p&gt;
&lt;p&gt;Also, let me make it very clear to everybody out there doing interviews: If the candidate can offer you credible evidence that they are, in fact, capable of writing code (GitHub projects that aren&apos;t forks, blog posts they&apos;ve written with code in it, publicly-recorded user group talks, whatever), just do yourself a favor and &lt;em&gt;believe them&lt;/em&gt;. The amount of effort it would take to &amp;quot;fake it&amp;quot; at a public level, when coupled with the trivial effort required to poke through the falsehood, vastly exceeds the payoff. I honestly think the concern at some (most?) companies isn&apos;t &amp;quot;We don&apos;t want to hire somebody who isn&apos;t technical&amp;quot; as much as it is &amp;quot;I don&apos;t want to be the one fooled by some shyster who pretended to know code because then it reflects badly on my ability to judge technical skills and that could hurt my career in some undefinable way and at the very least means I will have to endure the mockery of my peers&amp;quot;. But don&apos;t take my word for it--try it! Try to fake your way through an interview on a subject on which you know absolutely nothing and have no experience. It&apos;s way, way harder than you might think.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Recruiters, stop trying to insist you&apos;re not transactional.&lt;/em&gt;&lt;/strong&gt; Of course you are. Over three years, I had dozens and dozens of conversations with (company-employed or -retained) recruiters who insisted that they wanted to stay in touch after the interview cycle fell apart, and the exact number of those recruiters who actually did? Zero. Nada. Big Goose Egg. I won&apos;t judge you for it, but in return, just stop pretending.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Executive headhunters (where they work on behalf of the candidate, not the company) are extremely rare.&lt;/em&gt;&lt;/strong&gt; I found exactly one that wasn&apos;t an agency (or an outright scam), and just as I was about to work with them, my circumstances changed for the happier. (In truth, I want to bring them something just to try and keep the connection warm; sort of keep them on speed-dial, just in case.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;I wish I could&apos;ve come away from this timeframe with something to show for it.&lt;/em&gt;&lt;/strong&gt; I mean, three years of quality time with my spouse and family is great, but for so long I&apos;ve had this running mental thread that keeps whispering, &amp;quot;I could totally do &lt;em&gt;interesting side project idea&lt;/em&gt; if only I had the time to do it.&amp;quot; Well, I &lt;em&gt;had&lt;/em&gt; the time, three years&apos; worth, and I got so few of those side projects done. I suppose I could chalk it up to, &amp;quot;Looking for a job is emotionally draining, and I needed to keep my mental health charged,&amp;quot; but part of it is, I spent way more time playing StarCraft II and Heroes of the Storm than I&apos;d like to admit. (On the other hand, I did spend a lot of time tending my &lt;a href=&quot;https://research.tedneward.com&quot;&gt;research garden&lt;/a&gt; and then later working on the DevRel book, so it&apos;s not like I was just twiddling my thumbs the whole time. Still... would&apos;ve been nice to finish up a language or write that game or... something. Even just getting into a gym habit would&apos;ve been nice.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;I&apos;m finding that I&apos;m kinda looking forward to retirement now.&lt;/em&gt;&lt;/strong&gt; If retirement is essentially the last three years minus the worry about financial future (aka, we know that we&apos;re covered for the monthly expenses), then yeah, retirement&apos;s going to be pretty cool. I was always worried that I&apos;d go a little stir-crazy with nothing concrete handed to me to do. I still might, but I have a better idea of how I want to approach it and what I want to do during it. Next time around, I&apos;m definitely looking for ways to do it differently, but that&apos;s because I now understand just what the weight of &amp;quot;Eh, I don&apos;t have to be up early today, I&apos;m going back to bed (and sleeping &apos;til noon)&amp;quot; every day feels like.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Redmond, WA, really needs a 24-hour Coke joint.&lt;/em&gt;&lt;/strong&gt; All the Denny&apos;s in town shut down years ago, and nobody has stepped up to take over that slice of existence. It&apos;s where I wrote most of my MSDN and developerWorks articles back in the day, and while yeah, pandemic shook a bunch of things up, I&apos;m surprised that we haven&apos;t seen a 24-hour diner joint fill in the Denny&apos;s-shaped hole here in Eastside Seattle. (BTW, it has to be a Coke joint--Pepsi is dirty garbage water that any day now will be reclassified as toxic waste.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I don&apos;t know if any of those help anyone, or if they just trigger an automatic &amp;quot;WTF are you talking about?&amp;quot; or what. This post was more for me than for anybody else anyway, so if you made all the way through to the end here, well, thanks for reading.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(&lt;strong&gt;NOTE&lt;/strong&gt;: Edited again on 1 Feb 2025 to address a few questions Adam messaged me over LinkedIN that I realized I wanted to add here, and correct a few typos Ron was kind enough to point out.)&lt;/em&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Shapes of Data</title>
      <link>http://blogs.newardassociates.com/blog/2025/the-shapes-of-data.html</link>
      <pubDate>Fri, 31 Jan 2025 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2025/the-shapes-of-data.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Dating all the way back to the earliest of databases, data has had a &amp;quot;shape&amp;quot; to it, a natural schematic form that defines the various &amp;quot;atoms&amp;quot; and &amp;quot;molecules&amp;quot; that the database understands naturally. Relational data, such as that described by SQL and relational databases, is only one such shape; the various &amp;quot;NoSQL&amp;quot; databases often offer a different shape, but it&apos;s not always the same. What&apos;s more, just because a database uses a non-relational shape doesn&apos;t mean it&apos;s a natural fit to your object-programming language&apos;s code. When it doesn&apos;t, you have an impedance mismatch, which has to be solved somewhere (usually to the detriment of your code and complexity budget).&lt;/p&gt;
&lt;!--more--&gt;
&lt;!-- Let&apos;s use some MermaidJS for some diagrams here, shall we? --&gt;
&lt;script type=&quot;module&quot;&gt;
import mermaid from &apos;https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs&apos;;
mermaid.initialize({ startOnLoad: true });
&lt;/script&gt;
&lt;p&gt;&lt;em&gt;(BTW, much of this material is stuff I&apos;ve covered in the past in talks and other materials, but never really with this level of focus; if it sounds familiar, you&apos;ve probably already heard me yak on about it before, so you might choose to move on.)&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;The Atom of Data: The Bit&lt;/h3&gt;
&lt;p&gt;Fundamentally, all data boils down to a single bit, 1 or 0. Everything that ever crosses a CPU, resides in RAM, or is stored on disk, is made up of dozens, hundreds, thousands, millions or even billions of these. Beyond that, though, the bit is entirely uninteresting, because with the very rare exception of either writing assembly code by hand or working with bitmasks in a higher-level language (lookin&apos; at you, C), we don&apos;t really deal with bits very often. Even native boolean types are often &amp;quot;widened&amp;quot; out to a larger value.&lt;/p&gt;
&lt;h3&gt;Er, I mean...&lt;/h3&gt;
&lt;p&gt;So while the bit is useful and necessary to understand at a foundational level, its purpose here is to combine in various ways to create higher-level data types, which are usually made atomic at the language or data-storage level:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If we string bits together, we can use each bit in a binary numeric system to represent whole numbers. Depending on how many bits we use, we can get a pretty wide range of values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;8 bits together is a &lt;em&gt;byte&lt;/em&gt;, which can represent up to 256 (0 to 255) different values. Sometimes the first bit in the pattern is used to indiciate a positive or negative value, which makes this a &lt;em&gt;signed byte&lt;/em&gt;, capable of storing -127 to +128.&lt;/li&gt;
&lt;li&gt;Sometimes we string 16 bits together in a programming language and call that a &lt;em&gt;short integer&lt;/em&gt;, or &lt;em&gt;short&lt;/em&gt; for short (pun intended), and it can store 2-to-the-16 different values, which is a range of 0 to 65,535, or 64k. It also can be signed, which changes the range from -32k to +32k.&lt;/li&gt;
&lt;li&gt;32 bits together is an &lt;em&gt;integer&lt;/em&gt; in most circa-2000 programming languages, and again it can be unsigned (0 to 4,294,967,296), or signed (-2,147,483,648 to 2,147,483,647).&lt;/li&gt;
&lt;li&gt;64 bits, a &lt;em&gt;long integer&lt;/em&gt; or &lt;em&gt;long&lt;/em&gt;, gives us something like 18,446,744,000,000,000,000 possible values; that&apos;s 1.8446744e+19 for those of you who prefer scientific notation. (By the way, somebody double-check me on those two numbers, I tried to count the zeros and decimal places and lost track three times.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We can also string bits together in 32- and 64-bit formats, but this time use a different encoding mechanism to capture floating-point values.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But these are just numbers; a good chunk of our data is stored in human text, a la &lt;em&gt;strings&lt;/em&gt;, which are collections of 8-bit bytes (if it&apos;s stored in ASCII) or 16- to 64-bit Unicode Transfer Format chunks; this is where UTF-8, UTF-16, and/or UTF-32 comes into play. And, in many cases, since we don&apos;t know how long a string should be (are we storing a single word from the dictionary, or the entire collected works of Shakespeare?), we have to either set a special value aside to indicate the end of the string (C used the value 0, or NULL, to indicate the end of its byte-wide strings storing ASCII characters, hence giving us the term &amp;quot;NULL-terminated ASCII string&amp;quot;), or we have to capture the length somewhere (Pascal put the length in the first byte, so that the first character in the string was always at index 1, which neatly offset the C quirk of the first byte being at index 0, but also led to a max size of 255 characters for the string), or we just have to set a fixed size and assume the string falls under that length, or something.&lt;/p&gt;
&lt;h3&gt;Wait, we were talking about databases&lt;/h3&gt;
&lt;p&gt;Any database system worth its weight in weightless bits will define a set of &amp;quot;native&amp;quot; types that it understands atomically, just as programming languages do. The SQL standard, for example, defines a set of types like VARCHAR, a length-unlimited string type, or VARCHAR(2000), a string that can store up to 2000 characters. There&apos;s usually some performance- or feature-related consequences for choosing one over another, but these types form some of the core &amp;quot;atoms&amp;quot; of what we can store in the database.&lt;/p&gt;
&lt;p&gt;Then, the database typically defines some kind of &amp;quot;higher&amp;quot;, &amp;quot;molecule&amp;quot;-like, thing that allows for programmers to &amp;quot;assemble&amp;quot; larger things (often called &amp;quot;entities&amp;quot;, since that&apos;s a nice vendor-agnostic term) out of the core atoms. So, for example, if we want to store demographic information about a person, we might want to store:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Given (first) name: a string of up to some reasonable length&lt;/li&gt;
&lt;li&gt;Family (last) name: a string up up to some reasonable length&lt;/li&gt;
&lt;li&gt;Age: an integer value that can store 0 through, say, 150 or 200&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;mermaid&quot;&gt;
erDiagram
    PERSON {
        string familyName
        string givenName
        int age
    }
&lt;/pre&gt;
&lt;p&gt;We sometimes even get a little nutty and suggest that persons can be in a relationship to one another:&lt;/p&gt;
&lt;pre class=&quot;mermaid&quot;&gt;
erDiagram
    PERSON  |o--o| PERSON : marries
    PERSON {
        string familyName
        string givenName
        int age
    }
&lt;/pre&gt;
&lt;p&gt;It&apos;s not all that unlike creating user-defined types in programming languages (be they &lt;em&gt;classes&lt;/em&gt;, &lt;em&gt;records&lt;/em&gt;, &lt;em&gt;unions&lt;/em&gt;, whatever). The really &lt;em&gt;interesting&lt;/em&gt; question is if and/or how the database provides support for the definition of this user-defined type. If, for example, the database natively understands that &amp;quot;marries&amp;quot; relationship defined above, then we can use the database&apos;s native facilities (query language, for example) to retrieve the data we need more precisely (and more quickly and more scalably and more efficiently and...).&lt;/p&gt;
&lt;p&gt;(Of course, in many scenarios, scalability, efficiency, or performance aren&apos;t high-need requirements--of course they&apos;re always nice to have, but sometimes you just don&apos;t care about that as much as you do other concerns, like &amp;quot;development time&amp;quot;. In those cases, developers should of course use whatever tools are most appropriate--in a shop that knows Postgresql really well, use Postgres for everything! Just be aware that there&apos;s always some cost to navigating between these different &amp;quot;shapes&amp;quot;--the &amp;quot;impedance mismatch&amp;quot;--and after a certain point, that cost will want to be recuperated.)&lt;/p&gt;
&lt;h3&gt;Schema vs schemaless&lt;/h3&gt;
&lt;p&gt;Those databases which allow us to define a formal definition for these user-defined types are said to support the notion of a database-enforced schema, and the most common examples of these are the relational databases of the world. (As a matter of fact, I can&apos;t think of an RDBMS that doesn&apos;t enforce, nay &lt;em&gt;require&lt;/em&gt;, a schema definition for the database.) The database will have you define what your user-defined entities look like, and then go to great lenths to make sure that whatever gets stored in the database is in agreement with what&apos;s defined in the schema.&lt;/p&gt;
&lt;p&gt;Contrast this with the recent spate of &amp;quot;NoSQL&amp;quot; databases, most of which not only changed the shape of the data they were storing, but also removed the notion of schema from the picture, because it turns out that most developers weren&apos;t really all that frustrated with SQL (well, not really), but with the fact that the databse was enforcing that the schema had to be defined, and then enforcing what was in the schema. Developers were finding that as they iterate on a project, they often need to refactor the &amp;quot;things&amp;quot; (classes, tables, files, whatever) they&apos;re defining, and while programming languages had pretty decent refactoring support, schema-enforcing relational databases did not. So the NoSQLs said, &amp;quot;Let&apos;s drop the schema!&amp;quot; And developers said, &amp;quot;Awesome!&amp;quot; (And then a typo wrecked the developers&apos; whole week when they missed it in testing and it made its way into Prod, but that came later.)&lt;/p&gt;
&lt;p&gt;The point to understand here is &lt;em&gt;schema is not a property of the data&apos;s shape&lt;/em&gt;. We could have schema-less relational databases (we often call them CSV files), and we could have schema-enforced databases of other shapes (XML, for example, defined XSD, aka &amp;quot;XML Schema&amp;quot;, to do exactly this). We don&apos;t see the full spectrum of all the combinations mostly because... well, I dunno why. Just seems like developers aren&apos;t interested in what some of those other combinations are (which, to be clear, I think is a mistake--those other combinations are fascinating).&lt;/p&gt;
&lt;p&gt;Now, the last &amp;quot;atomic&amp;quot; type the database typically understands, natively, is some kind of &lt;em&gt;association&lt;/em&gt; between atoms. It might be something as simple as a key-value pairing (associating the key to the value), or it might be as complicated as a foreign-key relationship in a relational data model, but typically each database understands that things have to relate to one another in some fashion.&lt;/p&gt;
&lt;p&gt;And it&apos;s these relationships that typically define the &amp;quot;interesting&amp;quot; parts of what makes up the shape of the data in the database.&lt;/p&gt;
&lt;h3&gt;The known universe&lt;/h3&gt;
&lt;p&gt;As near as I can count, there&apos;s only a few data shapes, which I&apos;ll go over in separate posts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;./the-shapes-of-data-associative.html&quot;&gt;Associative&lt;/a&gt;, aka &amp;quot;key-value&amp;quot; (&lt;a href=&quot;&quot;&gt;Wikipedia&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Graph (&lt;a href=&quot;https://en.wikipedia.org/wiki/Graph_database&quot;&gt;Wikipedia&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;./the-shapes-of-data-hierarchical.html&quot;&gt;Hierarchical&lt;/a&gt;, aka &amp;quot;document&amp;quot; (XML, JSON) (Wikipedia - &lt;a href=&quot;https://en.wikipedia.org/wiki/Hierarchical_database_model&quot;&gt;Hierarchical&lt;/a&gt;, &lt;a href=&quot;https://en.wikipedia.org/wiki/XML_database&quot;&gt;XML&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;./the-shapes-of-data-object.html&quot;&gt;Object&lt;/a&gt; (OODBMS) (&lt;a href=&quot;https://en.wikipedia.org/wiki/Object_database&quot;&gt;Wikipedia&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;./the-shapes-of-data-relational.html&quot;&gt;Relational&lt;/a&gt; (RDBMS) (&lt;a href=&quot;https://en.wikipedia.org/wiki/Relational_database&quot;&gt;Wikipedia&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;./the-shapes-of-data-tabular.html&quot;&gt;Tabular&lt;/a&gt;, aka &amp;quot;flat files&amp;quot; (CSV, TSV) (&lt;a href=&quot;https://en.wikipedia.org/wiki/Flat-file_database&quot;&gt;Wikipedia&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;(I haven&apos;t finished writing up the graph and hierarchical notes yet, those are next)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There&apos;s often some variance between particular examples of each, but fundamentally, these appear (to me!) to be the high-level distinguishing models. (Of course, if more models make themselves appear, I&apos;ll add them to the list.)&lt;/p&gt;
&lt;p&gt;One of the older data shapes is that of the &lt;a href=&quot;https://en.wikipedia.org/wiki/Navigational_database&quot;&gt;navigational&lt;/a&gt; or &lt;a href=&quot;https://en.wikipedia.org/wiki/Network_model&quot;&gt;&amp;quot;network&amp;quot;&lt;/a&gt; data model, but I think, after some initial analysis/thought, that the network shape really is either entirely subsumed inside the object or graph shapes, or it sits somewhere in between the two on the Venn diagram, overlapped by each of the other two, and lying entirely within the space of the two combined. (I might be convinced otherwise, but somebody would have to work at it.)&lt;/p&gt;
&lt;p&gt;There&apos;s also a class of database products that try to embrace more than one of these shapes simultaneously, calling themselves &amp;quot;multi-model&amp;quot; databases. In my limited experience with them, I&apos;ve found that they usually embrace one model at the heart of their internal operation, and then project other models on top of that singular, internal model. (Which usually means that in a head-to-head shootout with a database product that &amp;quot;natively&amp;quot; understands a shape, the &amp;quot;projected&amp;quot; shape multimodel database loses. Badly.)&lt;/p&gt;
&lt;p&gt;By the way, let&apos;s also make one thing very clear: How we represent these models in memory may look somewhat different from how they are serialized and stored to disk. For example, when I &lt;code&gt;new&lt;/code&gt; up two objects in (pick-your-favorite-OO-language-here) and point them to each other, I don&apos;t see the pointer value of their location in memory because the language hides that from me (typically). If I were to store these two to disk, though, we&apos;d need to (a) identify them and (b) put those identifiers someplace where they could be turned back into pointers later. The pointers are natively understood by the language (and, by extension, the database engine that we&apos;re talking about), so they&apos;re a &amp;quot;natural&amp;quot; part of the database&apos;s model/&amp;quot;shape&amp;quot;.&lt;/p&gt;
&lt;p&gt;Along those same lines, it&apos;s also important to recognize that the shape of the data understood by the database is not always going to be entirely reflected in how the data is stored on disk; lots of databases do some very interesting things at the storage engine level in order to gain performance, and then &amp;quot;make things right&amp;quot; when they load data into memory for analysis or processing. (In other words, the magic behind highly-performant storage engines is out-of-scope for what I&apos;m trying to discuss here!) In other words, just because every major relational database stores their data in a B-tree (or -derived) format on disk doesn&apos;t make every relational database a hierarchical, graph, or associative shape. If we go down the stack far enough, we discover that everything is just made up of 1s and 0s! I choose to draw the line at how the data looks and interacts at the level at which the developer sees it, through either its query interface (SQL, OQL, Cypher, whatever), its API, or its storage format (if there is no consistent API--this applies to XML, JSON, CSV, TSV, and others).&lt;/p&gt;
&lt;p&gt;And yes, we can convert the database&apos;s native format into another format, often using tools found in the database itself--most RDBMSes in 2025 can return a SQL query in JSON or XML, if you ask it nicely enough. Far from invalidating this post, though, I think it actually justifies it: If it was trivial to consume the results in the desired manner, why does the database need to provide the feature? :-)&lt;/p&gt;
&lt;h3&gt;Thought experiments&lt;/h3&gt;
&lt;p&gt;In this section, I&apos;m going to idly wonder about other models and/or thoughts around the shape of data in general or implementation ideas. Some thought experiments appear in each of the specific data shapes, too, if they&apos;re closely aligned to a particular shape. I don&apos;t know if I have any particular point or solution here--call this the &amp;quot;thinking out loud&amp;quot; section.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Columnar.&lt;/em&gt;&lt;/strong&gt; One obvious absence is that of the &amp;quot;wide-column&amp;quot; or columnar data store, in which we store data in such a way that it feels more column-oriented than row-oriented (which would be tabular). There&apos;s some pretty significant implementation differences when we do this, but I&apos;m not 100% sure if the &lt;em&gt;shape&lt;/em&gt; is any different than a tabular one--just take the table and rotate it 90 degrees, and lo, we have a columnar format. Am I missing something here?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Multi-dimensional.&lt;/em&gt;&lt;/strong&gt; In a non-relational table or collection, we identify unique values along a single dimension--the key has to be unique across all possible values. Relational databases have allowed for compound keys for decades, however, which leads rise to a shaped model of data that resembles either a two-dimensional cartesian grid or even three- (or four-? five-?) dimensional model of data. It&apos;s highly likely these could be represented by an associative data store with multipart keys corresponding to each axis in the model, but one thing about three-dimensional models is that you can turn them in various directions and look along any axis &amp;quot;first&amp;quot;--in an associative model the keys are structured hierarchically, but what if we want to see the plane of data where Z is known but X and Y are variable? Like, roughly speaking, imagine an analogy to a three-dimensional grid, where we can write queries like &amp;quot;select where x=0, y=0, z=0&amp;quot; to retrieve a particular cell, or &amp;quot;select where x=0, y=0&amp;quot; to retrieve a line, or &amp;quot;select z=0&amp;quot; to retrieve a plane. Now imagine a four-dimensional database and specifiying three of the axes to retrieve a cube, and it&apos;s starting to fold on top of itself in the same way relational queries can. (Twenty years ago, people in the data space talked about &amp;quot;hyperdimensional&amp;quot; databases, is this that same idea?)&lt;/p&gt;
&lt;p&gt;For starters as a thinking point, what if we took a traditional tabular instance, and added a second dimension, time, to it, making it into a cube of sorts? That would make any tabular shape into a temporal one, which would obviously make it harder to store in a flat-file, but again, the shape is often more important than its storage or its serialized representation. (After all, we can&apos;t really represent a fully-normalized relational database in a CSV file, and we &amp;quot;get&amp;quot; that.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; &lt;em&gt;(1 Feb 2025)&lt;/em&gt; Wikipedia ha an entry for &lt;a href=&quot;https://en.wikipedia.org/wiki/Array_DBMS&quot;&gt;array databases&lt;/a&gt; and it seems to follow much of what I was imagining here. From an implementation standpoint, it would seem like this is an interesting area of exploration. From the Wikipedia entry, it sounds like this is used a fair amount in geo-spatial data, but this is all new to me so I can&apos;t be sure if I&apos;m reading that correctly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Temporal.&lt;/em&gt;&lt;/strong&gt; Speaking of time.... Many databases were exploring/operating around time as an implicit or explicit key in the storage of values, which makes me wonder if that&apos;s its own data model or a variation of multi-dimensional. Chris Date and Hugh Darwen had some thoughts on this, as did Rich Hickey, but I&apos;m not sure how all of this plays out inside my head yet. I think I tend more towards the Cassandra style of &amp;quot;every atom in the database has a time value attached to it&amp;quot;, but I find myself thinking that may be oversimplifying it immensely.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Branching.&lt;/em&gt;&lt;/strong&gt; Git made the branching model of data storage popular, and it&apos;s started to creep into database products. But is this really a new model of data, or is it simply an associative model that has a partiucarly-constructed key? That is to say, each &amp;quot;project&amp;quot; is a major-part key, and each &amp;quot;commit&amp;quot; is a minor-part to that key, and the complete (binary) commit is the value?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Unstructured.&lt;/em&gt;&lt;/strong&gt; Just like the absence of light is still a color (black), the absence of structure can still be data, although we can get really philosophical about this really quickly. Consider: Even though free text (like this blog post) is considered &amp;quot;unstructured&amp;quot;, it still has structure, in that there are grammatical rules that explain the punctuation, style rules that govern the larger structure of the post, and spelling rules that govern the way the letters are made to work together. Below the surface, there&apos;s the Markdown syntax with which this post was written. So is data ever really &apos;unstructured&apos;, or is it that some structures are just hard to diagram/explain and others are hard to parse? (It&apos;s not just text, either--&amp;quot;unstructured binary data&amp;quot; can mean &amp;quot;it&apos;s structured, but not something we want to parse&amp;quot; all the way through &amp;quot;it&apos;s random sensor data and we&apos;re trying to infer structure where we&apos;re not sure if there is any&amp;quot;.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

	</description>
    </item>
    <item>
      <title>Distributed Systems and Organization Design</title>
      <link>http://blogs.newardassociates.com/blog/2025/org-design-distrib-systems.html</link>
      <pubDate>Wed, 22 Jan 2025 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2025/org-design-distrib-systems.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Engineers (and their managers) have spent much of the last forty years learning (and sometimes re-learning and re-learning and re-learning...) the various repercussions and implications of distributed systems. As an engineering manager, I&apos;ve discovered that there is a remarkable similarity between distributed systems design and engineering organization design.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;For most engineering managers, if they know much about &amp;quot;org design&amp;quot;, it&apos;s either &lt;a href=&quot;https://en.wikipedia.org/wiki/Conway%27s_law&quot;&gt;Conway&apos;s Law&lt;/a&gt; (&amp;quot;A software architecture will mirror the organization that produced it&amp;quot;) or it&apos;s what they learned from the book &lt;a href=&quot;https://teamtopologies.com/book&quot;&gt;&lt;em&gt;Team Topologies&lt;/em&gt;&lt;/a&gt;. (By the way, if you were wondering about the &amp;quot;truthiness&amp;quot; of Conway&apos;s Law, check out &lt;a href=&quot;https://www.hbs.edu/ris/Publication%20Files/08-039_1861e507-1dc1-4602-85b8-90d71559d85b.pdf&quot;&gt;this paper&lt;/a&gt; by Harvard Business Review; tl;dr, yes, it holds up.) Beyond that, though....&lt;/p&gt;
&lt;p&gt;It&apos;s a little beyond the scope of this post, but suffice it to say, there&apos;s a whole area of study around organizational design, and much of it has the same kind of rigor and analysis to it that we do around distributed system design. That is to say, some people (particularly academics) study it with a great deal of rigor and discipline, and the rest of us wait for somebody to summarize their findings so we can completely ignore it later in favor of some hot new tool or technique. I fully admit to being no expert on org systems, but over the last decade, as I&apos;ve seen (both observed and led) more organizations from a managerial viewpoint, I&apos;ve come to realize that there&apos;s a lot of parallels between the two.&lt;/p&gt;
&lt;p&gt;If we make the basic assumption that a &amp;quot;team&amp;quot; in an org chart is the rough equivalent to a &amp;quot;server&amp;quot; or &amp;quot;compute node&amp;quot; in a distributed system diagram, and that a &amp;quot;team member&amp;quot; is roughly a compute process, we start to find some very interesting parallels.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Work is done much faster by an individual (&amp;quot;process&amp;quot;) than by committee (&amp;quot;cluster of processes&amp;quot;).&lt;/li&gt;
&lt;li&gt;Where a process in distributed system will &amp;quot;make API calls&amp;quot; or &amp;quot;pass data&amp;quot; or &amp;quot;send a message&amp;quot;, people will &amp;quot;collaborate&amp;quot; or &amp;quot;hand off&amp;quot; or &amp;quot;send a message&amp;quot; to each other.&lt;/li&gt;
&lt;li&gt;It&apos;s much faster for an individual to have data memorized (cached) than to have to look it up in a book or some other external storage (database).&lt;/li&gt;
&lt;li&gt;Changing the data that&apos;s currently memorized by an individual requires that individual spend a non-trivial amount of time to re-memorize the new information, starting from notifying them about the change (cache updates and propagation).&lt;/li&gt;
&lt;li&gt;Passing information is exponentially more expensive the further away the intended recipient is, whether in the next chair, next room, next building, or next continent.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;... and so on.&lt;/p&gt;
&lt;p&gt;And it&apos;s really hard &lt;em&gt;not&lt;/em&gt; to notice that a distributed system topology--a collection of nodes with links connecting some or all of them--is a remarkably similar diagram to a process flow diagram--a collection of nodes (teams) with links (communication or process handoffs) connecting some or all of them. It seems no accident that we refer to &amp;quot;workflow&amp;quot; as a term that covers both human actions and/or interactions and computer actions and/or interactions.&lt;/p&gt;
&lt;p&gt;In the distributed systems world, it turns out to be helpful to think about the Eight Fallacies of Distributed Computing as a framework to think about distributed systems. Using these as guideposts, or more likely, warning signs, we can often ship a reasonable distributed system without having to get too academic or methodical. So, in the spirit of the Eight Fallacies of Distributed Computing, we can derive the Eight Fallaies of Distributed Teams:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The organization is reliable.&lt;/em&gt;&lt;/strong&gt; We all know that nodes in a network can drop on a regular basis. Gratned, with modern computing trends and safeguards, it&apos;s rare, but it still happens. Similarly, even though we know most people will show up to work most days, there&apos;s still that non-zero possibility that a given individual won&apos;t. They&apos;ll be sick, they&apos;ll be distracted, they&apos;ll be re-tasked to something different by their management, and so on. If that weren&apos;t enough, we can of course never ignore the possibility that they&apos;ll be there at work, ready to carry out your request, if only they&apos;d received your email/text message/inter-office memo/voicemail, because somewhere along the communication path your message was just flat-out lost. (Who says ACKs are just for low-level network protocols?)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Latency is zero.&lt;/em&gt;&lt;/strong&gt; The time required to engage in communication between two people is very obviously non-zero. In fact, it can take quite a bit of time to get what&apos;s in my head over into your head. Sometimes this is because of the time required by the medium of communication (&lt;em&gt;ahem&lt;/em&gt; inter-office memos), but....&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Bandwidth is infinite.&lt;/em&gt;&lt;/strong&gt; In the human case, it&apos;s not communication bandwidth we worry about as it is an individuals mental bandwidth. Most people cannot juggle more than one or two things simultaneously. Even those of us gifted with Attention Deficit Disorder find that we have limits to the number of things we can keep our minds on, and we&apos;re better at multitasking than most. A human will eventually need to prioritize and serialize the things they&apos;re working on, which means that some work goes to the bottom of the pile.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The network is secure.&lt;/em&gt;&lt;/strong&gt; Sure, HR isn&apos;t going to write down a performance-management report on a piece of paper, find the first person outside their office, hand them that piece of paper, and ask that person to hand-deliver the message to the VP of Sales over in the next building--such a practice would be entirely unprofessional, deeply illegal, wildly impersonal, and hugely unethical. We get that. However, if HR is having a conversation with the VP of Sales, who else is listening to their conversation as the HR rep is sitting in the middle of the open-office plan? More importantly, when two loan officers are discussing a mortgage client&apos;s financials, who is listening in? (A long, long time ago, Intel found itself in an interesting quandry when they discovered tech news journalists were simply riding the shuttle flight between San Jose and Sacramento (where Intel had fabrication plants, in Folsom), simply listening in to the seat chatter between Intel employees, who were easily identifiable by the Intel work badges they proudly wore.) If nodes in your org chart must communicate to one another, how are they doing it?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Topology doesn&apos;t change.&lt;/em&gt;&lt;/strong&gt; Organization charts are famously instable, perhaps even more so than computer network topologies. If team A depends on team B for some of the work that team A needs to get done, what happens when team B is re-orged into an entirely different division?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;There is one administrator.&lt;/em&gt;&lt;/strong&gt; Well, technically, if everybody works for the same company, there&apos;s the CEO, but the larger point here is that frequently teams need to collaborate &amp;quot;across&amp;quot; the org chart, where the only point where both teams are under the same manager is well up the org chart--when Product and Engineering work together, for example, the Engineering team will ultimately report to a VP of Engineering, and the Product team to a VP of Product, who in turn each report to the CEO. This means that there is no one individual close to the teams that can resolve any inter-personal conflicts or &amp;quot;turf battles&amp;quot;--the teams must sort the issues out among themselves. Neither side can effectively make an appeal to authority for resolution. This means the teams are going to have to each feel some pressure to make things work, even if they have a intellectual or moral disagreement on some part of the collaboration.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Transport cost is zero.&lt;/em&gt;&lt;/strong&gt; In the original Fallacies, this one is often seen as related to the &amp;quot;Latency is zero&amp;quot; fallacy--where the first focuses on the time required to actually transmit the data, and this fallacy focuses more on the work required to prepare the data for transmission as well as interpret the data upon receipt. (In RPC terminology, for example, we talk about &amp;quot;serializing and deserializing&amp;quot; the objects transmitted across the wire.) In an organizational scenario, this transport cost is often the vastly larger time-consumer, as sometimes teams will have to create bespoke presentations or documents solely for the purpose of communicating one or more complex ideas to their collaborators (not to mention the delays introduced while we wait for everybody who must be in the meeting to have a free spot on their calendar to be able to discuss the topic at hand!).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The network is homogenous.&lt;/em&gt;&lt;/strong&gt; In the distributed systems fallacies, James Gosling introduced this one to point out that (almost) no computer network is actually made up of the same kind of hardware/OS combination (it&apos;s never all-Intel/Windows, it&apos;s never all-ARM/macOS, it&apos;s never all-anything). His argument, then, was to suggest &amp;quot;This is why everything should be written in Java!&amp;quot;, since that would render the fallacy moot. And, of course, we promptly wrote everything in Java, C#, Ruby, Smalltalk, Go, Dart, some C++, a little COBOL.... In the organizational sense, it&apos;s important to realize that not only is each team built for different purposes than one another, each person within the team often has different skills and perspectives from each other. This has the positive quality that a team that can take advantage of its members&apos; strengths can often overperform to its expectations, but it also means that a team that doesn&apos;t recognize that &amp;quot;not everybody is great at accounting&amp;quot; is going to run into problems when it tries to swap one individual for another without taking into account their individual skillsets. (I&apos;m looking very squarely at you, &amp;quot;full-stack engineer&amp;quot;-hunting recruiters....)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note that these don&apos;t all capture all of the Dos-and-Donts of organization design (not by a tenth), but it does certainly establish an interesting start to an interesting thought project, that being, &lt;em&gt;What if we thought about human-centric processes and workflows in the same way that we think about distributed systems design and architecture?&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It would give us some familiar tools by which to document and/or analyze processes, a la those &amp;quot;workstream&amp;quot; efforts that certain process coaches love to conduct. (I call them &amp;quot;process&amp;quot; coaches because some of them do so in service to agile efforts, while others do them in service to efforts that are anything but guided by the Agile Manifesto.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It helps set some expectations around expectations when work leaves an individual, a team, or an organization. (In other words, if you hand it off to another team, it&apos;s best to expect that to be orders of magnitude longer before you get a response when compared to something that you&apos;re doing yourself.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We might want to prevent &amp;quot;chatty&amp;quot; exchanges between individuals, and we definitely want to think twice about such exchanges between teams, if we need something processed quickly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Most of all, it behooves us to look for ways to collect everybody working on a particular large-scale task to be relatively close together on the org chart, to minimize the latency (#2) and transport cost (#6) between the teams.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It feels like this is a topic worth exploring in more detail, to me at least.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2025 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2025/2025-tech-predictions.html</link>
      <pubDate>Mon, 6 Jan 2025 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2025/2025-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;It&apos;s that time of the year again, when I make predictions for the upcoming year. As has become my tradition now for almost two decades, I will first go back over last years&apos; predictions, to see how well I called it (and keep me honest), then wax prophetic on what I think the new year has to offer us.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;As per previous years, I&apos;m giving myself either a &lt;strong&gt;+1&lt;/strong&gt; or a &lt;strong&gt;-1&lt;/strong&gt; based on a purely subjective and highly-biased evaluational criteria as to whether it actually happened (or in some cases at least started to happen before 31 Dec 2024 ended). If you want to skip to the new predictions, &lt;a href=&quot;#2025&quot;&gt;scroll down&lt;/a&gt; to the next major heading.&lt;/p&gt;
&lt;p&gt;In the large, 2024 was... ugh. We thought 2023 was tumultuous, but then 2024 said, &amp;quot;Hold my beer.&amp;quot; The job market for the tech sector started to look up, then started to look terrible again, then people said, &amp;quot;No, it&apos;s really getting better&amp;quot; even as others said &amp;quot;No this is the worst it&apos;s ever been&amp;quot; and most of the rest of us just threw our hands up in the air and stopped trying to guess. Anecdotally, I keep seeing lots of people on LinkedIN on their last months&apos; reserves, but at the same time LinkedIN keeps sending me all sorts of interesting openings that, when contacted, yield nothing but whispers. I kinda gave up trying to figure out where we are--though I&apos;m still looking for something full-time myself. (If you find my analysis here to be interesting or intriguing--even if you disagree with it--perhaps there&apos;s a role in which I can do this kinds of strategic and executive thinking on your company&apos;s behalf? Would love to hear from you.)&lt;/p&gt;
&lt;h2&gt;In 2024...&lt;/h2&gt;
&lt;p&gt;... I wrote a lot of stuff. (That always seems to happen when I do these.) So let&apos;s get to it; as I do each year, I&apos;ll include the full text of what I wrote in each bullet point first, then put the &lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; after it with whatever insights or comments seem relevant. (Arguably none of them are, but hey, it&apos;s my set of predictions, so....) As always, evidence is highly opinionated, mostly anecdotal, and entirely from my (and some from my professional network&apos;s) perspective, so &lt;em&gt;caveat emptor&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Not surprisingly, a &lt;em&gt;lot&lt;/em&gt; of what I wrote was about &amp;quot;AI&amp;quot;. (I put the term in quotes both because I have no illusions about machines becoming actually intelligent, nor do I think the current area of research into Large Language Models and generative AI are the sum total of AI research. Where&apos;s my &amp;quot;fuzzy logic&amp;quot; from the 1990s, people?) And, by the way, I guarantee that AI didn&apos;t write a word of this post, or any other. (When I use the word &amp;quot;delve&amp;quot;, it&apos;s because I damn well wanted to!)&lt;/p&gt;
&lt;h4&gt;Hiring will open up. (Probability &lt;em&gt;p&lt;/em&gt; 0.8)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;The interesting thing about the layoffs is that while they continue to trickle out from various companies all the way to December of 2023, it&apos;s a trickle compared to the flood that happened in 1Q, particularly in January. More interestingly, the &lt;em&gt;kinds&lt;/em&gt; of people that are going to be hired will shift slightly--right now (end of 2023), companies are focusing on hiring ICs to fit into existing holes in their current org tree. But with the new year, and a bit of optimism in the market, they&apos;ll start growing new branches to that tree, and that will require more in the way of engineering management and &amp;quot;ancillary units&amp;quot; like developer relations, R&amp;amp;D, and so on. It&apos;ll take a while, and it&apos;ll never be like 2019, but before too long things will get stronger.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; Well.... I really don&apos;t quite know how to score this one. On the one hand, some statistics suggest that hiring &lt;em&gt;did&lt;/em&gt; open up (&lt;a href=&quot;https://www.jobvite.com/lp/employ-job-seeker-nation-report-2024/&quot;&gt;&amp;quot;According to the Bureau of Labor Statistics, 829,000 jobs were added in Q1 2024&amp;quot;&lt;/a&gt;), but obviously lots of people aren&apos;t feeling it. The thought process here is that yes, the jobs started to come back, but it turns out that there&apos;s a &lt;em&gt;lot&lt;/em&gt; of people still looking, and so the jobs are disappearing quickly, either to internal candidates, overqualified candidates, or &lt;a href=&quot;https://en.wikipedia.org/wiki/Ghost_job&quot;&gt;even never being likely to hire in the first place&lt;/a&gt;. I&apos;m thinking this is a &lt;strong&gt;-1&lt;/strong&gt; to my predictions score, even if technically I might have been right.&lt;/p&gt;
&lt;h4&gt;WebAssembly will gain more traction. (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;I haven&apos;t really paid much attention to WebAssembly for the past few years, because I wasn&apos;t sure where things were going. The 1.0 specification is done, but it&apos;s pretty minimal compared to other richer, more full-featured virtual instruction sets (like the JVM or the CLR). Truthfully, it&apos;s a ridiculously bare-bones spec. But, even as I say this, there&apos;s some interesting infrastructure that&apos;s targeting LLVM more and more (most notably LLVM and GraalVM), making it easier and easier for WASM to gently &amp;quot;slide in&amp;quot; to a deeper role within a dev toolchain and do some interesting things. That said, though, WASM still has yet to really demonstrate where it&apos;s real value lies--why write something to WASM binary, which generally means targeting the browser, when there&apos;s so many Javascript-centric options already? Where&apos;s the compelling value-add from the developer perspective? This is the hinge on which WASM&apos;s broad-scale applicability matters: If WASM can show how using language-X-compiled-to-WASM enables a new kind of feature or a faster/easier workflow to get to &amp;quot;done&amp;quot;, then WASM could very well begin to emerge as the infrastructure backplane for browser-based applications all over the Internet. I don&apos;t know what that compelling reason is yet, though, which is why I leave this at a 0.5 &lt;em&gt;p&lt;/em&gt;.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; Well.... Yeah, no, WebAssembly remains something of a niche space here at the start of 2025. It&apos;s almost ironic: You know how everybody in the Linux world keeps saying, &amp;quot;THIS is the year for Linux on the desktop!&amp;quot;? Well, I think they&apos;re about to be challenged by the WebAssembly crowd for the title of &amp;quot;Most Consistent Prediction that Never Comes True&amp;quot;. There&apos;s some interesting technology here, but WASM just can&apos;t seem to catch a &amp;quot;hook&amp;quot; to catapult it to catapult it out of &amp;quot;Interesting-Yet-Uncompelling&amp;quot; territory it seems mired in. Which, we will note, I pointed out: &lt;em&gt;&amp;quot;WASM still has yet to really demonstrate where it&apos;s real value lies--why write something to WASM binary, which generally means targeting the browser, when there&apos;s so many Javascript-centric options already? Where&apos;s the compelling value-add from the developer perspective?&amp;quot;&lt;/em&gt; Still, it&apos;s a &lt;strong&gt;-1&lt;/strong&gt; to my prediction.&lt;/p&gt;
&lt;h4&gt;Generative AI will lose its luster. (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;It already has started, in many ways--memes now are common across the Internet showing ChatGPT conversation windows in which it responds to the question, &amp;quot;How do I use GitHub?&amp;quot; with &amp;quot;In order to push code to the remote server, issue the command &lt;code&gt;git branch&lt;/code&gt;...&amp;quot; in a completely erroneous and mistake-riddled answer. The stories of the lawyers who used ChatGPT to write legal briefs that turned out to be filled with inaccuracies and errors--for which they were disbarred, by the way--have cast some serious doubt on the ability of these generative AIs to &amp;quot;fire all the peons&amp;quot; whose work ChatGPT and its ilk were supposedly going to replace.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; Well.... The tech world is pretty clearly dividing into the &amp;quot;anti-AI&amp;quot; (aka &amp;quot;AI haters&amp;quot;) and &amp;quot;pro-AI&amp;quot; (aka &amp;quot;venture capitalists&amp;quot;) crowds, and frankly the more we see playing out in front of us, the more it looks like generative AI has reached its limits. (When OpenAI says they need more money than has ever been produced in the history of mankind in order to progress, you kinda get to draw that conclusion.) But then we also had something of &lt;a href=&quot;https://www.hollywoodreporter.com/business/business-news/scarlett-johansson-ai-legal-threat-1235905899/&quot;&gt;a Hollywood scandal drop&lt;/a&gt;, and suddenly it was mainstream news to talk about how AIs need to train off of existing data. ScarJo&apos;s lawsuit remains unresolved (as far as I know) at this point, but it definitely sent a ripple through a lot of the entertainment industry. I&apos;m going to give myself a &lt;strong&gt;+1&lt;/strong&gt; for this one, because when it makes the 5o&apos;clock news, and not in a good way, it&apos;s &amp;quot;lost its luster&amp;quot;. (She wasn&apos;t alone, by the way--others, like John Grisham and George R. R. Martin, filed a class-action lawsuit as well. This is definitely not &amp;quot;finished&amp;quot; discussion.)&lt;/p&gt;
&lt;h4&gt;We will begin to disambiguate between generative AI and large language models (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;It happens with AI every decade or so--something new comes along, it takes our imagination by storm, and we start chanting &amp;quot;AI! AI! AI!&amp;quot; like an amped-up-on-booze-and-caffeine-pills crowd at a wrestling match. Then, as we get disenchanted with the results, the various AI firms--who have yoked their success to the success of their AI work--will start to point out that they were never &amp;quot;AI&amp;quot; companies, they were &amp;quot;large language model&amp;quot; companies and therefore never a part of the hype machine that&apos;s now augering in.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; It&apos;s very faint, but you can start to hear it in some of the tech punditry. There&apos;s some interesting things going on with generative AI (one of my D&amp;amp;D gaming buddies discovered &lt;a href=&quot;https://suno.com&quot;&gt;https://suno.com&lt;/a&gt; and has started creating ballads and epic dirges about our campaign), and we&apos;re not talking about language at all. I think, realistically, this scores at a &lt;strong&gt;0&lt;/strong&gt; but it&apos;s definitely going to get more differentiated in 2025.&lt;/p&gt;
&lt;h4&gt;Custom AI models will begin to gain traction. (&lt;em&gt;p&lt;/em&gt; 0.6)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;Making use of a large company&apos;s model for your natural language analysis needs is great, but over time, companies are going to figure out that the cost of that model will probably be smaller if it can be hosted locally, rather than constantly going to the cloud and back again. (See the economies-of-scale discussion earlier, as well as the performance and reliability implications, a la &amp;quot;The Eight Fallacies of Distributed Computing&amp;quot;.) Slowly, quietly, companies with some room in their budgets are going to start looking to develop their own models, and in many cases may find that the model&apos;s they&apos;re building don&apos;t need to be quite so large (and heavy), that in fact a &amp;quot;medium&amp;quot; language model, or even a &amp;quot;small&amp;quot; language model would work, allowing for a local presence on the same node as the rest of the processing. OpenAI and other firms are going to combat this by constantly releasing new models with new excitement and fanfare, but like the cloud itself, the basic path here will be &amp;quot;start with the hosted LLM, then as your success and budget grows, look to build--and tune--your own&amp;quot;. It&apos;ll be &amp;quot;Buy vs Build&amp;quot; decision-making, all over again.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; The &amp;quot;quietly&amp;quot; part of that prediction is what trips it up--if companies are starting to build out their own models, they&apos;re not talking. Perhaps the best thing at this point is to punt on it for a year, and give myself a &lt;strong&gt;0&lt;/strong&gt; and say, &amp;quot;Let&apos;s see where it is in 2025.&amp;quot;&lt;/p&gt;
&lt;h4&gt;New and interesting languages will begin to make waves. (&lt;em&gt;p&lt;/em&gt; 0.6)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;I&apos;ve been saying this for years, but I keep holding out hope. Frankly, I think some of the development will be to raise the abstraction levels of what we do, because ChatGPT&apos;s success at writing code is due to the fact that 95 times out of 100, we&apos;re writing the same basic CRUD crap over and over and over again. The Pareto Principle holds here: 80% of all mobile applications (as an example) are doing the same stuff, it&apos;s just that it&apos;s a different 80% from all the rest. A language/stack that can embrace an onion-style architectural approach (allowing for &amp;quot;trap doors&amp;quot; to drop down a level of abstraction when/if necessary, such as how C/C++ allowed for inline assembly way back in the day) will be the answer here.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;The other element I imagine will/could be interesting to explore will be the intersection of what natural language models and compiler front-ends will look like--if we can get a language to start looking more like a natural language, it might enable some interesting DSL-type scenarios for end-users, and reduce the demands/pressures on developers to respond to every little change.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; Hello, &lt;a href=&quot;https://www.winglang.io/&quot;&gt;Wing&lt;/a&gt;. Hello, &lt;a href=&quot;https://wasp-lang.dev/&quot;&gt;Wasp&lt;/a&gt;. You&apos;re not quite what I was expecting or anticipating, but you&apos;re starting to get some interesting traction, and you&apos;re certainly not alone. You&apos;re also not natural-language-based like I&apos;d anticipated (or hoped!), but languages take a while to bake. I personally have some ideas on how this should look, but mine is but a small whisper of an idea, and I expect there will be vastly brighter people than me going into this space. Still, I&apos;m feeling generous to myself: &lt;strong&gt;+1&lt;/strong&gt;.&lt;/p&gt;
&lt;h4&gt;Cracks in the &amp;quot;full-stack developer&amp;quot; facade will grow. (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;The demand for the &amp;quot;full-stack developer&amp;quot; is mostly a cop-out on the part of managers, who don&apos;t want to artificially restrict their employee search because &amp;quot;hiring is hard&amp;quot;. So, instead of carefully considering what skills the current team lacks that needs shoring up, they instead scribble &amp;quot;full stack developer&amp;quot; on the job description, and proceed to rattle off every single technology that the team has ever used.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; &lt;a href=&quot;https://www.edureka.co/blog/demand-for-full-stack-web-developers/&quot;&gt;Some folks are definitely not seeing it.&lt;/a&gt; Of course, many of those folks are tech-training companies, whose business depends on developers (or their managers) feeling inadequate and needing training. Others, however, are &lt;a href=&quot;https://www.mavensolutions.tech/blog/how-full-stack-development-can-ruin-your-business/&quot;&gt;pointing out the obvious flaws in the approach&lt;/a&gt;, that &amp;quot;FSDs&amp;quot; can&apos;t really scale out as well as specialists can. Still, it seems that the recruiting posts and hiring managers still have &amp;quot;FSD on the Brain&amp;quot; syndrome, despite the clear drawbacks to trying to hire jacks-of-all-trades, so I have to give myself a &lt;strong&gt;-1&lt;/strong&gt; here.&lt;/p&gt;
&lt;h4&gt;AR/VR will start showing glimmers of life (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;If AR/VR is going to achieve anything of any substantial value, it really needs to do so soon, before it is relegated to the &amp;quot;Interesting Things That Were Out Of Their Time&amp;quot; bin, like the Apple Newton and the Xerox PARC. This year might--&lt;em&gt;might&lt;/em&gt;--be the year it presents us with something, particularly given the rise in interest in wearables. Certainly, with Meta going all-in on the whole &amp;quot;Metaverse&amp;quot; thing (whoever came up with that should be fired), there&apos;s going to be no shortage of money thrown at the problem, the big question is, will there be any actual innovation around UI? Because so long as the AR/VR thing is solely game-centric, it&apos;s fairly safe to assume that the AR/VR will go right into that bin without too much hesitation. I know, games are huge industry (measured in the trillions now?), but it&apos;s not enough to support hardware; witness the difficulties even conventional gaming hardware (for example, joysticks--today&apos;s flight sims are vastly more complicated than the ones twenty years ago, yet nary a joystick to be found) has had over the decades. If AR/VR (which requires hardware specific to it) is going to reach a point that justifies buying specific hardware for it, it has to be for something more than just gaming (and please don&apos;t say &amp;quot;education&amp;quot;, because if there&apos;s one place in the world that has almost no budget, it&apos;s education).&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; Oh, Ted. Sometimes you just have to stick to your guns on a theory, and not try to offer a tech a way out of its fate. With &lt;a href=&quot;https://www.macrumors.com/2024/12/31/vision-pro-may-be-out-of-production/&quot;&gt;Apple basically shutting down the Vision Pro&lt;/a&gt;, and Microsoft already out of the HoloLens business, it seems like AR/VR is probably &amp;quot;done&amp;quot; for the forseeable future. Meta is still a player here, though, and they&apos;re large enough to continue to throw good money after bad, so there&apos;s still hope, I suppose, that Oculus will suddenly make a splash... but I doubt it. &lt;strong&gt;-1&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;&amp;quot;Car apps&amp;quot; will begin to become &amp;quot;a thing&amp;quot; (&lt;em&gt;p&lt;/em&gt; 0.6)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;More and more vehicles out there are coming with computers in the console, offering easy connection to your mobile device. What&apos;s been lacking has been any sort of apps for it, beyond the basics (maps, audio entertainment, etc). Now that there&apos;s more of a target market, perhaps we are reaching a critical mass of potential customers to justify the investment in building apps specificall for vehicles.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;If this does start to take hold, it will be interesting to see what sorts of apps get built (I could imagine some CRM apps for certain kinds of salespeople, for example) and what form user interaction takes hold (voice control and interaction would be very important for drivers, for example). Frankly, though, the hard part will be the core innovation itself--what sort of apps do we want when we&apos;re driving?&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; &amp;quot;Car apps&amp;quot;? What was I thinking? &lt;strong&gt;-1&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;Kotlin will remain an &amp;quot;Android-only&amp;quot; language (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;This one is a hard one to call, but I&apos;m flipping a coin and landing on the pessimistic side of the &amp;quot;Will Kotlin break out of Android-only?&amp;quot; question. For those who weren&apos;t following the Kotlin story at home, Kotlin has recently done a couple of things to make it more than just &amp;quot;that language you use for Android&amp;quot; by developing &lt;a href=&quot;https://kotlinlang.org/docs/multiplatform-get-started.html&quot;&gt;Kotlin Multiplatform&lt;/a&gt; and &lt;a href=&quot;https://kotlinlang.org/docs/native-overview.html&quot;&gt;Kotlin Native&lt;/a&gt;. These open up the Kotlin language for use in more situations, but their success will really hinge on how many developers actually &lt;em&gt;want&lt;/em&gt; to use Kotlin in more places than just their Android codebase.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;Historically, multiplatform languages have not done well, with the sole (arguable) success being that of Java--whose &amp;quot;Write once, run anywhere&amp;quot; campaign didn&apos;t really accomplish much. (Remember, most of Java&apos;s success was in the server room, not the desktop.) Native might have more possibility for success, but either one gaining any traction would be an interesting development and potentially grow Kotlin beyond just &amp;quot;an Android thing&amp;quot;.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; Kotlin remains firmly in the Android space, near as I can tell, and nobody seems all that interested in Kotlin Multiplatform. &lt;strong&gt;-1&lt;/strong&gt; It&apos;s certainly possible that the interest can build, but if there&apos;s not much of a splash at its introduction, it&apos;s hard to build later (without some kind of compelling shift in the market, anyway). Remember, the only reason we&apos;re talking about Kotlin today is because Google adopted it as its language of choice for Android (in order to get clear of Java, some might suggest).&lt;/p&gt;
&lt;h4&gt;C# and Java will continue to &amp;quot;pile on&amp;quot; with features (&lt;em&gt;p&lt;/em&gt; 0.8)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;Both languages have reached a point where the weight of the language is really beyond the ability of any one person to keep track of what&apos;s there, yet each time a new release comes out, it comes with a whole slew of new proposed features designed to bring new syntax into an already-existing part of the language or an attempt to cram yet-another-interesting-idea into an already &amp;quot;overloaded-collection-of-features&amp;quot;-oriented language. (Can you really look at either C# or Java and tell me that they are &amp;quot;object&amp;quot;-oriented anymore? You can go quite a ways with either and never see or hear an object anywhere along the way by this point.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;Look, maybe this is my &amp;quot;Gitoffamahlawn&amp;quot; moment to these predictions, but both of these languages are old enough to drink, they each spun up powerful and resilient platforms that have a number of newer, simpler, more-concise languages, and at a certain point in time, it&apos;s reaasonable to say, &amp;quot;This one is done. There&apos;s nothing new we need to add.&amp;quot; To keep cramming new stuff in is a terrible addiction--it&apos;s a way to show that &amp;quot;We&apos;re still hip! We&apos;re still doing cool stuff (...and therefore justify why companies should still be paying us license fees!)&amp;quot; We keep &lt;a href=&quot;https://medium.com/swlh/stop-adding-new-features-to-your-product-bed86aa5114&quot;&gt;telling startups&lt;/a&gt; &lt;a href=&quot;https://www.komododigital.co.uk/insights/feature-addiction-can-ruin-a-digital-product/&quot;&gt;not to do it&lt;/a&gt;, but our two major providers of software development tools can&apos;t seem to get the lesson themselves.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;Spend some time with F#. With Clojure. With Kotlin. Play with some of the new ideas (Mint, Io, Alloy). Or even go back and experiment with some of the classics (Smalltalk, Self, LISP, Scheme). But, for your own sake, stop enabling the relentless pounding of the feature surf on the beach of your brain by breathlessly hanging on &amp;quot;What comes next&amp;quot;, because in time, you&apos;ll be battered into sand.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; Yeah, lawn, off, get. &lt;strong&gt;+1&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;Crypto falls even further. Blockchain struggles to reinvent. (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;Look, faith in cryptocurrency is really at an all-time low, except for the people who are caught holding the bottom of the Ponzi pyramid, and they desperately want to hype the hell out of it so they can pass the bag on to the next level down. That won&apos;t change. Blockchain, the world&apos;s worst-designed distributed database, will continue to wrestle with the goal of finding a reason to exist, and hey, could maybe even find one bullseye, given enough darts. (Many companies that invested in Blockchain have either decided to walk away from the dartboard or else that they&apos;re going to load up on a &lt;em&gt;lot&lt;/em&gt; of darts--and maybe a shotgun or two--until they hit that bullseye.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;I really would love for these two to just go away entirely, but they won&apos;t, because nothing ever dies completely. But this is the last year they&apos;re going to get much--if any--serious time in the tech press, despite the fevered efforts of a precious few on LinkedIn. (Yes, Andreeson-Horowitz is going big into it; yes, they&apos;ve been big into it since it&apos;s start; yes, there will always be people who see what they want to see, instead of following actual evidence; and yes, folks, there&apos;s still time to dive in and turn your profit, just don&apos;t be the last one holding the pyramid up!)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;And, for me, 2024 will be the last year I talk about this in any form.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; Well, this was well on the way to a +1... and then Trump decided to breathe new life into the whole mess by starting to tease greater legitimacy for cryptocurrencies by &lt;a href=&quot;https://www.axios.com/2025/01/02/bitcoin-gold-trump&quot;&gt;declaring a &amp;quot;strategic bitcoin reserve&amp;quot;&lt;/a&gt;. That&apos;s got the whole space &lt;a href=&quot;https://www.ft.com/content/af23fffc-e560-42eb-84a0-f25ca8d693c0&quot;&gt;chittering with excitement&lt;/a&gt;, and naturally the &lt;a href=&quot;https://www.forbes.com/sites/digital-assets/2024/12/31/delusional-trump-bitcoin-price-warning-suddenly-rocks-crypto-market/&quot;&gt;markets went haywire&lt;/a&gt;. This seems like a good idea? Sadly, I fear even my &amp;quot;this will be the last year I talk about this in any form&amp;quot; prediction can&apos;t even hold true. &lt;strong&gt;-1&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;Phishing attacks go ballistic (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;Thanks, AI! With all these generative natural language tools (like ChatGPT), it will be easier than ever to generate emails intended to trick users into surrendering their credentials to fake sites. That will lead to more breaches, more private info leaks, and more of all the wonderful things that come with those.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;What will make it even worse will be all the security companies that roll out &amp;quot;AI-based&amp;quot; security tools, claiming that the AI will somehow be able to better protect against those very same attacks--but while generative AI can create really good-looking human-facsimile output, it&apos;s not always great at recognizing artificially-created human-facsimile input. Which means the attackers just got a boost to their toolset, and the defenders will be looking to try and keep up this year.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; &lt;a href=&quot;https://abc7chicago.com/post/ai-phone-scam-calls-mimicking-voice-scam-family/14847406/&quot;&gt;Turns out, it&apos;s not your kid in jail needing bail money, after all.&lt;/a&gt; Fortunately, &lt;a href=&quot;https://www.cnn.com/2024/11/26/business/daisy-ai-granny-scammers-o2-intl/index.html&quot;&gt;AI can also fight the scammers, by boring them to death!&lt;/a&gt; JFC. &lt;strong&gt;+1&lt;/strong&gt;, but I hate myself a little bit over all this.&lt;/p&gt;
&lt;h4&gt;Databases will incrementally improve (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;... as opposed to releasing something drastic. There is some interesting ideas percolating over in the world of &lt;a href=&quot;https://dbos-project.github.io/&quot;&gt;DBOS&lt;/a&gt;, spearheaded by one of the principals in the Postgres world, but I have a feeling that it&apos;ll take a little bit for those ideas to brew before there&apos;s really something there to evaluate. (Hope I&apos;m wrong, though.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;Meanwhile, though, players in the RDBMS world will slip a new feature into the mix by polluting the relational model just that wee bit more, the NoSQL players will pick just a tiny bit more from the relational world and add that, and developers will continue to choose which player they want to play with based on criteria that touches maybe 1% of the feature set of the player they choose.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; DBOS continues to churn along, and overall, relational databases continue to introduce interesting ideas into SQL and get further away from the relational purity Codd and Date and the others sought back in the 70s. JSON is now a fixture in most SQL dialects, and it wouldn&apos;t surprise me (or anybody) if an LLM shows up in there somewhere, maybe shoehorned between the XML-generation code and Java bindings. (You &lt;em&gt;did&lt;/em&gt; read &lt;a href=&quot;https://blog.ansi.org/sql-standard-iso-iec-9075-2023-ansi-x3-135/&quot;&gt;parts 14 and 13 of the SQL specification&lt;/a&gt;, didn&apos;t you?) &lt;strong&gt;+1&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;I&apos;m publishing a book (&lt;em&gt;p&lt;/em&gt; 0.8)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;I and a few other folks are working on a book based on the Developer Relations Activity Patterns catalog that I drafted a ways back, expanding on the material there in a big way. That&apos;ll come out in 2024, &lt;em&gt;almost&lt;/em&gt; guaranteed.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;+1&lt;/strong&gt;... almost. It&apos;s almost done, so it&apos;ll come out, just not &lt;em&gt;quite&lt;/em&gt; in 2024.&lt;/p&gt;
&lt;h4&gt;Final tally&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;six wins (&amp;quot;+1&amp;quot;s)&lt;/li&gt;
&lt;li&gt;one, maybe two &amp;quot;draws&amp;quot; (&amp;quot;0&amp;quot;s)&lt;/li&gt;
&lt;li&gt;six losses (&amp;quot;-1&amp;quot;s)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;... which puts me squarely in the middle of the bell curve. Good thing this isn&apos;t my day job!&lt;/p&gt;
&lt;div id=&quot;2025&quot; /&gt;
So now let&apos;s turn our head to 2025.
&lt;p&gt;As I do every year, each prediction comes with a probability factor (&lt;em&gt;p&lt;/em&gt;) that ranges anywhere from 0.0 to 1.0, with most predictions appearing in the 0.3 to 0.8 range. This is a trick I picked up from my International Relations days, where political prediction briefings often came with a similar kind of probability as a way of offering a &amp;quot;confidence&amp;quot; factor. Anything higher than a 0.8 means &amp;quot;We&apos;re pretty damn sure&amp;quot;, and anything less than 0.3 means &amp;quot;We&apos;re including it mostly out of completeness but we don&apos;t expect it.&amp;quot;&lt;/p&gt;
&lt;h4&gt;The 2025 Tech Predictions are going to be &lt;em&gt;wild&lt;/em&gt; (&lt;em&gt;p&lt;/em&gt; 0.8)&lt;/h4&gt;
&lt;p&gt;Sometimes as part of writing these predictions, I take a look around the Internet (thanks Google!) with what other people are predicting, and let me tell you, the predictions for this upcoming year are off the &lt;em&gt;hook&lt;/em&gt;. Autonomous robots. Human-computer brain augmentation. AI-generated AI creating new AI. If you ever saw it in a sci-fi movie, somebody out here on the Internet is predicting &amp;quot;this is the year&amp;quot;! (BTW, did you know that this year is going to be the year of Linux on the desktop? It&apos;s true! I read it on the Internet!) And the corresponding benefits are even more wild: Humans will be replaced by the singularity. No, humans will be able to all of us retire thanks to the singularity. No, humans &lt;em&gt;are&lt;/em&gt; the singularity. More than any year, 2025 really seems to be catching fire in peoples&apos; imaginations, and they&apos;re letting their tech-freak flag &lt;em&gt;fly&lt;/em&gt;.&lt;/p&gt;
&lt;h4&gt;&amp;quot;Developers are obsolete&amp;quot; prose will peak, then dwingle (&lt;em&gt;p&lt;/em&gt; 0.8)&lt;/h4&gt;
&lt;p&gt;Look, let&apos;s be honest: Lots of people have a vested interest in seeing software development&apos;s &amp;quot;hold&amp;quot; over the creation of software broken. Startup founders desperately want to believe they don&apos;t need a CTO or any of those really expensive &amp;quot;full-stack&amp;quot; people to build out their idea. Non-FAANG tech-adjacent companies look at their labor costs and think, &amp;quot;Do we &lt;em&gt;really&lt;/em&gt; need to have all these expensive people on our payroll?&amp;quot; AI venture capitalists (who want to see their investment make fortune quickly, so they can bail and reap the high stock price) want people to buy into the idea that AI can replace... pretty much anybody... without waiting for actual evidence of the success of replacing humans with AI. It&apos;s all going to hit a fever pitch this year, as the &amp;quot;pro-AI&amp;quot; crowd tries to drown out the growing surge of &amp;quot;anti-AI&amp;quot; evidence, then the bubble will burst, the AI startups will start to collapse, and the VCs will start hunting up their next hype to invest-pump-dump.&lt;/p&gt;
&lt;h4&gt;AI startups are going to start failing (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;It may be this year, or it may be next year, but the AI venture-capital-gravy-train is about to run out. Fully 25% of all VC money went into &amp;quot;something something AI&amp;quot;, and it&apos;s eerily reminiscient of the &amp;quot;dot-com&amp;quot; years, when a huge percentage of all investment and VC money went into &amp;quot;something something Internet&amp;quot; and gave us such wonderful profit-avoidant monstrosities like &amp;quot;pets.com&amp;quot;. (Seriously. The sock puppet. It&apos;s all that&apos;s left of what was one of the most trumpeted startups in the early 2000s.) But eventually, your business has to actually make money (even you, Sam Altman), and when the profits aren&apos;t there, the shutdowns follow.&lt;/p&gt;
&lt;h4&gt;ARM is going to start eating into Intel in a huge way (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;In the beginning, there was the x86. And Intel rode that line into massive, generational-spanning profits. But slowly, over time, the ARM chip architecture has been slowly but steadily eroding the bulwark that x86/x64 erected (&amp;quot;You&apos;d have to recompile everything! Nothing would run out of the box! Dogs and cats will merge to form a master race that will enslave humanity!&amp;quot;), such that by the end of 2024, not was any shipping device without a built-in keyboard running ARM internally, Microsoft had a version of Windows running on the ARM chip. This upcoming year, there&apos;s literally no barriers left to ARM&apos;s complete dominance of the CPU market. The &amp;quot;Apple Silicon&amp;quot; MacBooks were just the vanguard in the horde of new ARM-based laptops that are going to come out and essentially take over. (As a caveat, if you&apos;re a native-language developer, as in you use C, C++, Swift, Rust, Go, Nim, Zig, and so on--if you&apos;ve not started learning what ARM assembly looks like and behaves, now&apos;s a good time to start learning it.)&lt;/p&gt;
&lt;h4&gt;Java and C# aren&apos;t going to introduce anything significant (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;Look, I&apos;ve been saying this for a few years now, and I&apos;m going to make this the last year I do so, but these languages are so mainstream right now that nobody (except for conference speakers, who constantly mine the feature lists for &amp;quot;What&apos;s New&amp;quot; talks for the coming year) really (a) pays much attention to their &amp;quot;v.Next&amp;quot; featureset, or (b) cares. The price of mainstream status is a desire for &amp;quot;sustainability&amp;quot;, which means most Java shops are not moving versions unless it&apos;s an &amp;quot;LTS&amp;quot; release, and most .NET shops are in the same mindset. (BTW, most iOS shops have lost track of all the new &amp;quot;bright shiny&amp;quot;s that Swift keeps getting, and what&apos;s worse, each release seems entirely incompatible with the previous.)&lt;/p&gt;
&lt;h4&gt;TypeScript jumps the shark (&lt;em&gt;p&lt;/em&gt; 0.6)&lt;/h4&gt;
&lt;p&gt;The TypeScript language started life as an attempt to add a strongly-typed type system to the JavaScript ecosystem, in order to provide greater and greater up-front verification of code in order to get better errors earlier. (That&apos;s the general goal of any strongly-typed language, and while we can debate whether that&apos;s a good idea or not, what&apos;s not debatable is that a significant number of programmers buy into it, one of them being Anders.) But TypeScript also discovered that it could do a &lt;em&gt;lot&lt;/em&gt; of type-level things, and TypeScript has gotten more and more complex and complicated and confusing with each release. (I&apos;ve commented, elsewhere, that I lost faith in the language when the team chose not to create a language spec for it anymore, choosing instead to just say, &amp;quot;The code is the spec&amp;quot; and publish a new blog post with each release desribing new features in a casual and imprecise way.) This is the year (though it could be next year, although some have said it was already last year) that TypeScript starts compiling (or not compiling) expressions that absolutely confuse the hell out of anybody without a PhD in type theory. (For whatever it&apos;s worth, two years ago &lt;a href=&quot;https://dev.to/tylim88/series/20966&quot;&gt;somebody put together&lt;/a&gt; a list of &apos;WTF moments&apos;, and they&apos;re... interesting.)&lt;/p&gt;
&lt;h4&gt;Python type hinting goes mainstream (&lt;em&gt;p&lt;/em&gt; 0.6)&lt;/h4&gt;
&lt;p&gt;Quietly, while nobody was looking for it, &lt;a href=&quot;https://peps.python.org/pep-0484/&quot;&gt;Python introduced &amp;quot;type hinting&amp;quot;&lt;/a&gt;, where Python code can be given Pascal-style type hints to parameters and return types, allowing tools like IDEs and editors to be able to provide better edit-time support. Most of the Python tutorials, it seems, ignored this for a while, but starting last year it seems the notion of writing type-hinted Python is becoming more and more acceptable to the Python community, though it seems that the majority of the community kept to &amp;quot;untyped&amp;quot; Python. My guess is, this is the year that the balance shifts, and &amp;quot;typed&amp;quot; Python begins to outweight the &amp;quot;untyped&amp;quot; Python. Legacy &amp;quot;untyped&amp;quot; codebases will of course exist for centuries to come, but I suspect that this coming year might be when companies start scouring their Python codebase and thinking, &amp;quot;Maybe we should put type hints in...?&amp;quot;.&lt;/p&gt;
&lt;p&gt;(BTW, Pythonistas, you really need to read--nay, study--the PEP in detail. It&apos;s massive.)&lt;/p&gt;
&lt;h4&gt;JetBrains tries very hard to push Kotlin Multiplatform (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;JetBrains put a ton of time and energy into KMP, and thus far it looks like there&apos;s been absolutely zero uptake from anyone outside of the building. If JetBrains is going to be able to call this any kind of success, they&apos;re going to need 2025 to be the year that KMP emerged as a credible competitor to React Native or Flutter.&lt;/p&gt;
&lt;h4&gt;Flutter begins its quiet slide into obscurity (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;Speaking of which, Flutter&apos;s going to start being quiesced by Google. First there was the layoffs (200-some people in October of last year), which signaled pretty strongly that Google&apos;s &amp;quot;done&amp;quot; with Flutter, all the PR statements notwithstanding. Then the &lt;a href=&quot;https://github.com/join-the-flock/flock&quot;&gt;community fork&lt;/a&gt; that came out of that news led a number of folks to think, &amp;quot;Wow, Google&apos;s &lt;em&gt;really&lt;/em&gt; done with Flutter&amp;quot;, since nobody would think to create a community fork of something that&apos;s being actively developed and maintained by the multi-trillion-dollar entity that created it. That makes the companies who make money on the things developers build (as opposed to those companies who make money on building things for developers) get &lt;em&gt;very&lt;/em&gt; nervous about adopting or continuing to invest in Flutter, and we can expect Flutter&apos;s usage numbers and interest level to plummet as a result. Yes, the open-source tools are there, and yes, people will continue to work on them, but hey by the way, how&apos;s the &lt;a href=&quot;https://parseplatform.org/&quot;&gt;Parse&lt;/a&gt; community looking these days? Or &lt;a href=&quot;https://loopback.io/doc/index.html&quot;&gt;LoopBack&lt;/a&gt;?&lt;/p&gt;
&lt;h4&gt;Swift will release a new version, and it will have incompatibilities (&lt;em&gt;p&lt;/em&gt; 0.8)&lt;/h4&gt;
&lt;p&gt;Like the rain in Seattle, Apple always releases a new version of Swift every year, and every year, there&apos;s something in there that&apos;s not backwards-compatible with the previous version. There is zero reason to expect that 2025 will be any different on that score.&lt;/p&gt;
&lt;h4&gt;Rust will not replace C++ (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;Oh, I know the downsides to C++. I really do. I programmed in the language for a half-decade (back in the &amp;quot;bad ol&apos; days of pre-C++08, waaay back in the late 90s), so I&apos;m well aware of all the dangers of pointers and what-not. But Rust isn&apos;t a high-level language, and there&apos;s way too much C and C++ code out there for companies to credibly consider rewriting all that code. We can ache and moan about computer security and stability all we like, but doing that rewrite is not a simple line-for-line replacement, precisely &lt;em&gt;because&lt;/em&gt; of the pointer guarantees that Rust enforces--all of those pointers have to be debated, decided, and declared, and it has to be consistent across multi-million-line codebases. Rust may make some inroads in getting new system-level development, but it&apos;s not going to make C++ &amp;quot;go away&amp;quot; any time soon, not this year or the next (or the one after that, or even the one after that).&lt;/p&gt;
&lt;h4&gt;Odin, Nim and Zig will gain some attention (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;All of these are system-level languages in the tradition of C++ or Rust, and all of them are interesting in their own rights. I suspect some of the enthusiasm for Rust will get siphoned off into these, and before long the &amp;quot;Rust will replace C++&amp;quot; crowd will turn into the &amp;quot;Rust/Odin/Nim/Zig will replace C++&amp;quot; crowd, before they start fighting among themselves which of those four will do the replacing (because, of course, there can only be one, right?).&lt;/p&gt;
&lt;h4&gt;DIY databases will start gathering attention (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;There&apos;s been a quiet surge of interest in SQLite recently, since it ships pretty much everywhere (it&apos;s already on every mobile device on the planet, and its C codebase and bindings make it super-easy to FFI out to if there aren&apos;t already language-level bindings for your chosen language) and it&apos;s a pretty feature-complete subset of SQL-92. That&apos;s gotten a number of folks intrigued with the idea of &amp;quot;local database&amp;quot;-based functionality, which in turn has sparked some interest in &amp;quot;Wait, what exactly makes up a database, again...?&amp;quot; because if I can get the storage engine and bypass the SQL-ish query and talk directly to the query engine and.... Well, suddenly people are starting to wonder if the database has to be the black box we&apos;ve always assumed it to be. I think in 2025 we&apos;re going to start cracking it apart and doing a little plug-and-play of the components as part of, or behind, their service interfaces.&lt;/p&gt;
&lt;h4&gt;Our book will ship! (&lt;em&gt;p&lt;/em&gt; 0.9)&lt;/h4&gt;
&lt;p&gt;Seriously! It will! I promise!&lt;/p&gt;
&lt;h4&gt;Maybe I&apos;ll have a full-time gig again? (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;Three years and counting. I wouldn&apos;t mind the &amp;quot;enforced retirement&amp;quot; so much, were it not for all these people coming around my place, telling me I owe them money.... Fortunately I keep finding the odd thing to do every so often, but it&apos;d be nice to not have to answer questions that start with &amp;quot;Tell me of a time when....&amp;quot;.&lt;/p&gt;
&lt;h4&gt;I&apos;ll start either a YouTube channel or some video training (&lt;em&gt;p&lt;/em&gt; 0.4)&lt;/h4&gt;
&lt;p&gt;The probability goes up if I don&apos;t have something full-time landed by the end of January.&lt;/p&gt;
&lt;h4&gt;I&apos;ll speak at a brand-new (to me) conference (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;I have no idea which one, but I&apos;d love for some suggestions and/or requests. I love the shows I hit regularly, but I wouldn&apos;t mind going someplace entirely new and talking to people who&apos;ve never heard me speak before.&lt;/p&gt;
&lt;p&gt;As always, feel free to comment and tell me why I&apos;m crazy, in whatever forums feel comfortable. In the meantime, talk to you all next year... if not sooner.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Farewell, Twitter</title>
      <link>http://blogs.newardassociates.com/blog/2024/farewell-twitter.html</link>
      <pubDate>Sat, 16 Nov 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/farewell-twitter.html</guid>
      	<description>
	&lt;p&gt;Over time, people change, and it becomes necessary to part ways because of that change. So, too, with organizations and, in this particular case, social media platforms. When it began, Twitter was a bastion of hope and optimism, the center of the pro-democracy &amp;quot;Arab Spring&amp;quot; and a (naive, perhaps) belief that ordinary people communicating with one another frankly and openly could provoke serious change in the world. Then, Elon bought Twitter, and it accelerated its slide into the dumpster fire it has become.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;I joined Twitter back in the 2007/2008 timeframe, egged on by a few speaker colleagues who&apos;d discovered it. I had no idea what to do with this &amp;quot;microblogging&amp;quot; platform, as I had a blog, and I was just fine with posting long-form content. When I started, I wrote haiku on it--not my idea, Neal Ford&apos;s--because I couldn&apos;t really figure out what you do with less than 140 characters at a time. But it became apparent that this was becoming something of a magical place, making connections and exchanging ideas. More than once I made a connection on Twitter that, over time, turned into an online friendship that, in a few cases, turned into a &amp;quot;real-life&amp;quot; friendship.&lt;/p&gt;
&lt;p&gt;Those days are long past. X has now, thanks to Elon&apos;s &amp;quot;stewardship&amp;quot;, turned into a cesspool of right-wing aspiration, far-right harrassment, and incessant click-baiting and rage-baiting posts. When the moderation team was entirely fired shortly after his purchase of the platform, I had my concerns, but I thought, &amp;quot;Maybe I need to stick it out and stand up, use my follower count as a counter against the ideologuery that is building.&amp;quot;&lt;/p&gt;
&lt;p&gt;But not anymore. It&apos;s exhausting, and I don&apos;t see the point of it anymore. This isn&apos;t a physical property or an ancestral homeland that needs defending--it&apos;s all just bits living in servers and phones someplace. The only value is in the engagement, if there&apos;s no engagement, then there&apos;s no point. And I simply refuse to be engaged by political forces that are more interested in anointing an American aristrocracy than in preserving democracy. So, it&apos;s time.&lt;/p&gt;
&lt;p&gt;I will not abandon my account--that would give somebody else an opportunity to use my handle for their own purposes. Instead, I&apos;ll just quiesce my participation on the platform, neither posting nor &amp;quot;liking&amp;quot; or in other ways engaging. The more of us that flee the platform, the less attractive it becomes as a place for advertisers and marketers. The less attractive it becomes, the less money people will spend on it. Hey, if Elon wants to use his fortune to prop up a social online network that is essentially a giant salve to his fragile ego, it would be entirely in keeping with what I&apos;ve observed of the man in person. (Yes, I&apos;ve met him in person, at an OReilly FOO camp way back in the day. I was not impressed then, and I&apos;m even less impressed now.)&lt;/p&gt;
&lt;p&gt;Meanwhile, I&apos;m thinking my engagement will now take place on LinkedIn, Reddit, and Bluesky. If you&apos;re reading this, you probably already know how to find me on those places.&lt;/p&gt;
&lt;p&gt;As for social media in general.... I think that social media is going through its &amp;quot;yellow journalism&amp;quot; period, hearkening back to the days when printed newspapers and journals wrote any headline that might sell more copies. William Randolph Hearst was the Musk of his day, and in time, journalism standards stiffened to the point where it was unthinkable to write the kind of headlines like that which started the Spanish-American War. (Seriously, look it up.) In time, administrations (probably not the US) will realize that social media is every bit as influential and important as newspapers and other periodicals, and begin to enforce standards of conduct and honest reporting that will build trust again. (Honestly, we could use those for newspapers and other periodicals again, too.)&lt;/p&gt;
&lt;p&gt;But in the meantime, I strongly suggest to people that you go back to some of the original news outlets--AP and Reuters--and subscribe to their feeds. If you want analysis, I suggest places like The Economist, and if you want summations, consider The Week. But don&apos;t assume that any news outlet that disagrees with your interpretation of the world as &amp;quot;fake news&amp;quot;, because if we can&apos;t agree on the basics of reality, we are collectively doomed as a species.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>On Avoiding Foolish Opinions</title>
      <link>http://blogs.newardassociates.com/blog/2024/foolish-opinions.html</link>
      <pubDate>Fri, 18 Oct 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/foolish-opinions.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(I came across this quote from Russell, and liked it so much I thought I&apos;d just copy it verbatim over to my blog. Obviously I&apos;m not the author--I&apos;m not nearly this eloquent.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Via &lt;a href=&quot;https://www.amazon.com/gp/product/0415472385/ref=as_li_qf_asin_il_tl&quot;&gt;The Basic Writings of Bertrand Russell&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If the matter is one that can be settled by observation, make the observation yourself. Aristotle could have avoided the mistake of thinking that women have fewer teeth than men, by the simple device of asking Mrs. Aristotle to keep her mouth open while he counted. He did not do so because he thought he knew. Thinking that you know when in fact you don’t is a fatal mistake, to which we are all prone. I believe myself that hedgehogs eat black beetles, because I have been told that they do; but if I were writing a book on the habits of hedgehogs, I should not commit myself until I had seen one enjoying this unappetizing diet. Aristotle, however, was less cautious. Ancient and medieval authors knew all about unicorns and salamanders; not one of them thought it necessary to avoid dogmatic statements about them because he had never seen one of them.&lt;/p&gt;
&lt;p&gt;Many matters, however, are less easily brought to the test of experience. If, like most of mankind, you have passionate convictions on many such matters, there are ways in which you can make yourself aware of your own bias.&lt;/p&gt;
&lt;p&gt;If an opinion contrary to your own makes you angry, that is a sign that you are subconsciously aware of having no good reason for thinking as you do. If some one maintains that two and two are five, or that Iceland is on the equator, you feel pity rather than anger, unless you know so little of arithmetic or geography that his opinion shakes your own contrary conviction. The most savage controversies are those about matters as to which there is no good evidence either way. Persecution is used in theology, not in arithmetic, because in arithmetic there is knowledge, but in theology there is only opinion. So whenever you find yourself getting angry about a difference of opinion, be on your guard; you will probably find, on examination, that your belief is going beyond what the evidence warrants.&lt;/p&gt;
&lt;p&gt;A good way of ridding yourself of certain kinds of dogmatism is to become aware of opinions held in social circles different from your own. When I was young, I lived much outside my own country in France, Germany, Italy, and the United States. I found this very profitable in diminishing the intensity of insular prejudice. If you cannot travel, seek out people with whom you disagree, and read a newspaper belonging to a party that is not yours. If the people and the newspaper seem mad, perverse, and wicked, remind yourself that you seem so to them. In this opinion both parties may be right, but they cannot both be wrong. This reflection should generate a certain caution.&lt;/p&gt;
&lt;p&gt;Becoming aware of foreign customs, however, does not always have a beneficial effect. In the seventeenth century, when the Manchus conquered China, it was the custom among the Chinese for the women to have small feet, and among the Manchus for the men to wear-pigtails. Instead of each dropping their own foolish custom, they each adopted the foolish custom of the other, and the Chinese continued to wear pigtails until they shook off the dominion of the Manchus in the revolution of 1911.&lt;/p&gt;
&lt;p&gt;For those who have enough psychological imagination, it is a good plan to imagine an argument with a person having a different bias. This has one advantage, and only one, as compared with actual conversation with opponents; this one advantage is that the method is not subject to the same limitations of time or space. Mahatma Gandhi deplores railways and steamboats and machinery; he would like to undo the whole of the industrial revolution. You may never have an opportunity of actually meeting any one who holds this opinion, because in Western countries most people take the advantage of modern technique for granted. But if you want to make sure that you are right in agreeing with the prevailing opinion, you will find it a good plan to test the arguments that occur to you by considering what Gandhi might say in refutation of them. I have sometimes been led actually to change my mind as a result of this kind of imaginary dialogue, and, short of this, I have frequently found myself growing less dogmatic and cocksure through realizing the possible reasonableness of a hypothetical opponent.&lt;/p&gt;
&lt;p&gt;Be very wary of opinions that flatter your self-esteem. Both men and women, nine times out of ten, are firmly convinced of the superior excellence of their own sex. There is abundant evidence on both sides. If you are a man, you can point out that most poets and men of science are male; if you are a woman, you can retort that so are most criminals. The question is inherently insoluble, but self esteem conceals this from most people. We are all, whatever part of the world we come from, persuaded that our own nation is superior to all others. Seeing that each nation has its characteristic merits and demerits, we adjust our standard of values so as to make out that the merits possessed by our nation are the really important ones, while its demerits are comparatively trivial. Here, again, the rational man will admit that the question is one to which there is no demonstrably right answer. It is more difficult to deal with the self esteem of man as man, because we cannot argue out the matter with some non-human mind. The only way I know of dealing with this general human conceit is to remind ourselves that man is a brief episode in the life of a small planet in a little corner of the universe, and that, for aught we know, other parts of the cosmos may contain beings as superior to ourselves as we are to jellyfish.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Book Review: Data Structures and Algorithms in JavaScript</title>
      <link>http://blogs.newardassociates.com/blog/2024/book-review-dsaa-javascript.html</link>
      <pubDate>Mon, 7 Oct 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/book-review-dsaa-javascript.html</guid>
      	<description>
	&lt;p&gt;No Starch Press sent me an early access/review copy of the book &amp;quot;Data Structures and Algorithms in Javascript&amp;quot;, by Federico Kereki. If there&apos;s two sentences that summarize the book, it&apos;s these two from the Introduction: &amp;quot;The book deals with two basic concepts in computer science: data structures and algorithms. It follows a structure similar to university curricula and adds examples taken from coding challenges and interview questions, using them to discuss the relative advantages and disadvantages of specific algorithms and data structures.&amp;quot; In other words, it&apos;s exactly what it purports to be, and that&apos;s a good thing.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;tl;dr, this is a great book to read if you&apos;ve never had a formal introduction to ECMAScript (which, by the way, is the formal name for the language--Javascript is the name of the Netscape implementation of the language, just as JScript is the name of the implementation that Microsoft did a while back) or to some core computer science topics. The first chapter is a great succinct summary of Javascript, and the second is an intro to functional programming, though one that is entirely tailored to Javascript, and is missing a great number of functional features (like partial application of functions or currying) which are missing from Javascript. I kinda wish the book covered a bit more of FP than just what&apos;s there, but at the same time, the book is focusing on data structures and algorithms in Javascript, and not FP in general.&lt;/p&gt;
&lt;p&gt;Given that this was an early access/review copy, I didn&apos;t have a physical copy of the book to work with, but from the PDF, it looks like a pretty traditional No Starch Press book, 500+ pages long, and the rest of the book is pretty much a common-sense written version of a more-than-decent computer science textbook. What&apos;s also reminiscent of a textbook is the list questions at the end of each chapter, with answers at the back of the book, designed specifically to give the reader a chance to test their understanding at the end of each chapter. It&apos;s a nice touch, and although in general I&apos;m not a huge fan of them, Kereki does a pretty good job with these, keeping them high-level enough to get the point of the TfU across while being low-level enough to have a clear goal and area of study.&lt;/p&gt;
&lt;p&gt;The TOC is below:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;PART I: THE BASICS&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Chapter 1: Using JavaScript&lt;/li&gt;
&lt;li&gt;Chapter 2: Functional Programming in JavaScript&lt;/li&gt;
&lt;li&gt;Chapter 3: Abstract Data Types&lt;/li&gt;
&lt;li&gt;Chapter 4: Analyzing Algorithms&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;PART II: ALGORITHMS&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Chapter 5: Designing Algorithms&lt;/li&gt;
&lt;li&gt;Chapter 6: Sorting&lt;/li&gt;
&lt;li&gt;Chapter 7: Selecting&lt;/li&gt;
&lt;li&gt;Chapter 8: Shuffling and Sampling&lt;/li&gt;
&lt;li&gt;Chapter 9: Searching&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;PART III: DATA STRUCTURES&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Chapter 10: Lists&lt;/li&gt;
&lt;li&gt;Chapter 11: Bags, Sets, and Maps&lt;/li&gt;
&lt;li&gt;Chapter 12: Binary Trees&lt;/li&gt;
&lt;li&gt;Chapter 13: Trees and Forests&lt;/li&gt;
&lt;li&gt;Chapter 14: Heaps&lt;/li&gt;
&lt;li&gt;Chapter 15: Extended Heaps&lt;/li&gt;
&lt;li&gt;Chapter 16: Digital Search Trees&lt;/li&gt;
&lt;li&gt;Chapter 17: Graphs&lt;/li&gt;
&lt;li&gt;Chapter 18: Immutability and Functional Data Structures&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If anything about this book is true, it&apos;s that Kereki does an amazing job of staying 100% on task throughout the book. The first part is entirely what it says: it&apos;s all about the basics--Javascript, FP, ADTs (intro to data structures) and big-O notation (algorithms). The second part dives deeper into algorithms, and third part into data structures.&lt;/p&gt;
&lt;p&gt;One area that I&apos;ve personally always had a bit of a problem with is understanding &lt;em&gt;persistent data structures&lt;/em&gt;--that is, data structures that have the interesting property that can be updated while keeping previous versions intact, without changes. This property automatically implies that these structures are ideal for purely functional programming languages, which do not allow for side effects. &lt;a href=&quot;https://www.amazon.com/Purely-Functional-Data-Structures-Okasaki/dp/0521663504&quot;&gt;Okasaki&apos;s book&lt;/a&gt; is the gold standard on that, but I never really grasped what was going on there. While I can&apos;t say that I completely understand functional data structures yet, I can say that, like the great physicist, &amp;quot;I find that I am still clueless, but at a much higher level.&amp;quot;&lt;/p&gt;
&lt;h2&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;I like this book! It&apos;s not going to be for everybody--it&apos;s dry in places, but it&apos;s also not trying to be anything other than what it&apos;s declaring itself to be. It&apos;s a solid discussion of some core Comp Sci principles, but done in a language that isn&apos;t normally what&apos;s used by CompSci grads. And that, in many ways, is the key strength of this book--this is not a book for Computer Science graduates, it&apos;s a book for those thousands and thousands of bootcamp graduates who were all turned away because they lacked the knowledge of Big-O notation and data structures. This book, in a nutshell, is the book that every bootcamp grad needs to read, to catch up on all the theory they missed by not taking a CS degree, but it&apos;s in a readable format and approachable style that any novice Javascripter will be able to comprehend. (Note, I don&apos;t mean &amp;quot;right away&amp;quot;--some of these are dense topics that will take time and practice to master, but at least there&apos;s no Greek symbols or confusing functional programming terminology to act as gatekeeper.)&lt;/p&gt;
&lt;p&gt;If you&apos;re a well-practiced Javascripter who never learned the formalities, some of this will be redundant, and if you&apos;re a CS graduate who did well, you&apos;ll probably pick up a few things about Javascript. But overall, this book is a gold mine for the aforementioned bootcamp grad, and if I had had this book available to me a decade ago when I built a web app team out of fresh-from-bootcamp graduates, I&apos;d have bought each and every single person a copy.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Book Review: Art of ARM Assembly (Vol 1)</title>
      <link>http://blogs.newardassociates.com/blog/2024/book-review-art-of-arm-assembly.html</link>
      <pubDate>Mon, 23 Sep 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/book-review-art-of-arm-assembly.html</guid>
      	<description>
	&lt;p&gt;No Starch Press sent me an early-access e-copy drop of the book &amp;quot;The Art of ARM Assembly (Volume 1)&amp;quot;, by Randell Hyde, an author whose previous books on x86 assembly are on my shelf, and I&apos;m enthusiastically suggesting you go buy a copy when it comes out.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;For close to two decades now, I&apos;ve been telling developers (experts to neophytes) that you need to know &amp;quot;one level below the level at which you work&amp;quot;. Knowing how your Java class turns into JVM bytecode, or how that .NET assembly looks like on disk, is often the difference between knowledge and ignorance. How does the &lt;em&gt;yield return&lt;/em&gt; keyword work in C#? How did Java do inner classes before adopting nested-access classes in JDK 11 (or 12 or 15 or whenever the hell nested-access was introduced)? Being able to crack open the compiled binary, look at the disassembled output, and have at least a rough idea of what&apos;s going on, is a huge skill that every developer must have.&lt;/p&gt;
&lt;p&gt;And since the move to ARM-based processors in iOS (and later Android and later my MacBookPro machine and now even some Windows machines), I&apos;ve been unable to do that.&lt;/p&gt;
&lt;p&gt;Kotlin/Android? Compiles down to bytecode before turning into native instructions; Java or C# on my M3 MacBookPro? Yeah, I kinda just trust the JITter, but... The truth is, I&apos;d been holding off on learning ARM mostly because I didn&apos;t have a guide I trusted to lead me past the thorny parts. I&apos;ve looked at a few ARM assembly books, but always put them back on the shelf because I just... I dunno... didn&apos;t feel like the author was going to find the right mix of &amp;quot;teaching&amp;quot; to go along with the tech.&lt;/p&gt;
&lt;p&gt;(In fairness, I haven&apos;t mastered x64 yet, either, mostly because it often seems like it&apos;s &amp;quot;close enough&amp;quot; to x86 that I can muddle my way through. That said, I have Hyde&apos;s x64 book, or at least Volume 1 of it, and it&apos;s on my list to read once I get through ARM.)&lt;/p&gt;
&lt;p&gt;Now, though, I feel like I flew to Nepal, walked out of the airport intending to find a random Sherpa to guide me up the mountain, and ran into an old friend who also happens to be incredibly experienced at guiding people up Everest.&lt;/p&gt;
&lt;p&gt;As with any early-access drop, it&apos;s important to &lt;em&gt;caveat&lt;/em&gt; that it&apos;s possible that the final product you end up with in your hands will differ from what I&apos;m seeing as I read/write this... but considering we are talking about a thousand-plus page book here, I really, really, &lt;em&gt;really&lt;/em&gt; doubt Hyde&apos;s going to rewrite much except to correct mistakes/typos.&lt;/p&gt;
&lt;h2&gt;Physical&lt;/h2&gt;
&lt;p&gt;Well, I only have an e-reader (PDF) copy to work from, but did I mention the thing is a &lt;em&gt;thousand&lt;/em&gt; pages? Throwing the printed copy of this at somebody is going to qualify as &amp;quot;Assault with a Deadly Weapon&amp;quot; in thirty-three states! (In Texas, of course, everyone will expect you to have a copy mounted on a rifle rack in your pickup truck.)&lt;/p&gt;
&lt;p&gt;But it&apos;s not like this is a lightweight subject, either--assembly language is notorious for its requirements around attention to detail to function correctly. So it seems entirely reasonable to assume that if you&apos;re new to ARM, then you probably need to understand some of the hardware that drives the assembly language, since the two are going to be pretty tightly joined at the hip. On top of that, Hyde doesn&apos;t really seem to want to assume much about his target audience&apos;s skill level other than &amp;quot;At minimum, this book assumes that you have some experience in a language such as Pascal (or Delphi), Java, Swift, Rust, BASIC, Python, or any other imperative or object-oriented programming language.&amp;quot; It&apos;s a pretty broad range, but more importantly, notice that none of the aforementioned languages have much experience (or reason for it) with the lower-level details. (Back in &lt;em&gt;my&lt;/em&gt; day, we learned C! And pointers! And we &lt;strong&gt;&lt;em&gt;liked&lt;/em&gt;&lt;/strong&gt; it!)&lt;/p&gt;
&lt;p&gt;By the way, it&apos;s important to note that Hyde is no stranger to the subject. As he states in the Introduction, &amp;quot;This book is a sister volume to The Art of 64-Bit Assembly Language, which was, itself, a rewrite of The Art of Assembly Language Programming (AoA). AoA was a project I began way back in 1989 as a tool for teaching 80x86 (x86) assembly-language programming to students at California State Polytechnic University, Pomona, and the University of California, Riverside.&amp;quot; 35 years, and dude&apos;s just been cranking one assembly language book out after another. (If I remember correctly, he also did a MASM Bible thirty or so years ago, which was one of the go-to books back in the day, too.) This is what I mean about &amp;quot;seasoned guide&amp;quot;--not only is Hyde an expert on the subject, he knows how he wants to get the material across to his audience/students, and he has a ton of experience doing so.&lt;/p&gt;
&lt;p&gt;Lastly, this is officially Volume 1 of a planned two-volume set; on his website, Hyde notes, &amp;quot;The Art of ARM Assembly Language is actually going to be part of a two volume set. [Volume 2] will cover 32-bit ARM assembly language programming on 32-bit versions of Pi OS and on embedded ARM Cortex-M CPUs (such as Arduino/Teensy and Raspberry Pi Pico). Look forward to it sometime in late 2026.&amp;quot; --&lt;a href=&quot;https://artofarm.randallhyde.com/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Contents&lt;/h2&gt;
&lt;p&gt;Hyde doesn&apos;t waste much time getting started right from the start, and the start here begins with the Introduction, where he recounts a brief history of ARM and then rationales for learning ARM and 64-bit ARM, respectively. In many other books, you can breeze past the Introduction/Chapter 0 without losing much, but honestly, I&apos;d recommend you take the time to go through it--there&apos;s a lot of new products, terminology, and ideas in here that it really should be thought of as the first chapter of content. (Although, to be fair, arrays in assembly start at 0, just like in C, so maybe this is the first chapter!)&lt;/p&gt;
&lt;p&gt;Hyde is also extremely straightforward and up-front about some of the decisions he makes in the book and why; for example, he doesn&apos;t cover Microsoft&apos;s toolchain, even though ARM is now running in Surface books. The reason? &amp;quot;In theory, it should be possible to apply the information in this book to ARM-based Windows machines (such as the Surface Laptop Copilot+). Unfortunately, Microsoft’s software development tools, particularly its assembler, is based on the original ARM assembly syntax defined by Arm (the company), not Gas &lt;em&gt;[The GNU Assembler, which he explained a few paragraphs earlier --TKN]&lt;/em&gt;. While Microsoft’s &lt;em&gt;armasm64&lt;/em&gt; is a better tool in many respects (as it uses standard ARM assembly language syntax), everyone else uses Gas syntax. The machine instructions are more or less the same between the two sets of assemblers, but the other statements (known as assembler directives or pseudo-opcodes) are completely different. Therefore, example programs written in Gas will not assemble under armasm64, and vice versa. Since trying to present both syntax forms in example programs would be just as confusing as trying to teach 32- and 64-bit programming simultaneously, I stick to Gas syntax in my examples.&amp;quot; I don&apos;t like that we&apos;re using the (Hyde&apos;s opinion) suboptimal tool, since he thinks &lt;em&gt;armasm64&lt;/em&gt; is the better tool, but I can respect the decision. More importantly, thanks, Hyde, for sharing the insight and the rationale--I can accept a decision like this much more easily when I know the reason for it.&lt;/p&gt;
&lt;p&gt;Here&apos;s the TOC, and I am in no way going to go through each chapter; in fact, I&apos;ll just go over Chapter 1 (which is about as far as I&apos;ve gotten, in any depth, because I want to go through and code along with the book) in any detail.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;PART I: MACHINE ORGANIZATION&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 1: Hello, World of Assembly Language&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Remember when I said that Hyde starts running from the jump? He opens this chapter with some example assembly code that--literally--does nothing, as a way to explain some initial details. Linux and macOS, for example, treat names slightly differently, so he takes a moment to walk us through that. He shows the commands for assembling, linking, and running the example do-nothing program, then promptly demonstrates that the C/C++ toolchain will actually serve as a nice umbrella to do all that in a much simpler command-line. In a nice touch to show he&apos;s not in denial about what people want to learn assembly for, though, he immediately turns around and shows how to build a simple C++ program that calls that do-nothing assembly code. Fear not--he assumes readers have little to no experience with C/C++, and shows &amp;quot;just enough&amp;quot; to get the point across.&lt;/p&gt;
&lt;p&gt;Once that&apos;s done, though, he covers some of the hardware basics about the ARM processor(s), and goes through some of the basics of how CPU and memory work at a low level. In some ways, this feels a little overkill--after all, he&apos;s clearly not assuming we are novice programmers, just new to assembly language--but at the same time, it&apos;s not so much overkill that the reader familiar with the idea can&apos;t just turn the page early.&lt;/p&gt;
&lt;p&gt;He then goes over four or so ARM instructions (&lt;code&gt;ldr&lt;/code&gt;, &lt;code&gt;str&lt;/code&gt;, &lt;code&gt;adr&lt;/code&gt;, and &lt;code&gt;adrp&lt;/code&gt;), and their syntax and semantics. Almost immediately, we run into a problem--macOS and Linux don&apos;t like using absolute memory addresses, and require relative ones. (I can sort of understand this, since it offers the OS a bit more flexibility where to map a given module inside of a process space--but that&apos;s about the extent of what I think I know there.) So Hyde has some macros that effectively hide the difference; I kinda wish he didn&apos;t, so that I as the reader could be forced to understand the problem a bit more, but for a book that&apos;s looking to teach ARM, and not Linux/ARM or macOS/ARM, this seems reasonable.&lt;/p&gt;
&lt;p&gt;More instructions are covered in some detail, though most behave as one would expect similar instructions from other assembly languages to behave.&lt;/p&gt;
&lt;p&gt;Then, in Sections 1.9 and 1.10, Hyde discusses the ARM ABI (Application Binary Interface) and how to write ARM assembly to call C functions (most notably for I/O, a la &lt;em&gt;printf&lt;/em&gt;). He ends Chapter 1 with a &amp;quot;Hello World&amp;quot; that mixes compilation with C and the ARM assembler, giving us a nice springboard from which to explore more ARM instructions in further chapters. Then, at the end of this (and I think every) chapter, he has a few &amp;quot;Test Yourself&amp;quot; questions to test your comprehension of the reading--these sorts of things are not my favorite, since I think they don&apos;t really serve the purpose they&apos;re intended to.&lt;/p&gt;
&lt;p&gt;(With a book, so much of the experience is self-directed, I&apos;d much rather see some suggestions on how to take the code we covered in the chapter and modify it in various ways--like, for example, &amp;quot;The &lt;em&gt;printf&lt;/em&gt; function takes a variadic number of parameters to go along with the format string, so write a mixed-mode program that prints &amp;quot;Hello, %s, you are %d years old today!&amp;quot; where name and age are passed as parameters along with the format string.&amp;quot; That forces(?) me to go and write that program, which builds on what I&apos;m typing in, rather than testing my ability to go back and re-read a page in the book.)&lt;/p&gt;
&lt;p&gt;Keep in mind, Chapter 1 spans 40-something pages (p3 to 44), and it&apos;s dense the entire way. Quite honestly, having read the chapter, I&apos;m still going to go back and re-read/explore the chapter, this time typing (or, more likely, cutting-and-pasting from the PDF at least some of) the code he lays out in here, because I&apos;m not going to learn ARM just by reading the book. Like most languages, it really needs to be experienced, not just observed.&lt;/p&gt;
&lt;p&gt;Chapter 2: Data Representation and Operations&lt;br /&gt;
Chapter 3: Memory Access and Organization&lt;br /&gt;
Chapter 4: Constants, Variables, and Data Types&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;PART II: BASIC ASSEMBLY LANGUAGE&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Chapter 5: Procedures&lt;br /&gt;
Chapter 6: Arithmetic&lt;br /&gt;
Chapter 7: Low-Level Control Structures&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;PART III: ADVANCED ASSEMBLY LANGUAGE&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Chapter 8: Advanced Arithmetic&lt;br /&gt;
Chapter 9: Numeric Conversion&lt;br /&gt;
Chapter 10: Table Lookups&lt;br /&gt;
Chapter 11: Neon and SIMD Programming&lt;br /&gt;
Chapter 12: Bit Manipulation&lt;br /&gt;
Chapter 13: Macros and the Gas Compile-Time Language&lt;br /&gt;
Chapter 14: String Operations&lt;br /&gt;
Chapter 15: Managing Complex Projects&lt;br /&gt;
Chapter 16: Stand-Alone Assembly Language Programs&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;PART IV: REFERENCE MANUAL&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Appendix A: The ASCII Character Set&lt;br /&gt;
Appendix B: Glossary&lt;br /&gt;
Appendix C: Installing and Using Gas&lt;br /&gt;
Appendix D: The Bash Shell Interpreter&lt;br /&gt;
Appendix E: Some Useful C Language Functions&lt;br /&gt;
Appendix F: Answers to Questions&lt;/p&gt;
&lt;p&gt;I suppose if the book were going to lose some weight somewhere, the appendices could be trimmed down--does anyone really need (or want) a reference to the ASCII character set in a book, when Google is just six (or ten) keystrokes (or a single &amp;quot;New Tab&amp;quot; in an existing browser window) away? The Glossary is needed, for sure, and the &amp;quot;Answers to Questions&amp;quot; (did I mention he sprinkles little exam-like tests-for-understanding throughout the text?) are necessary, but &amp;quot;Installing and Using Gas&amp;quot; I would&apos;ve expected in Chapter 1 or the Introduction, and I dunno if a primer on using Bash is all that relevant here, particularly since it covers the truly basic commands (pwd, ls, cd, mkdir, date, and so on). Frankly, a quick primer on Makefiles would probably have been a better use of the pages, if you ask me.&lt;/p&gt;
&lt;p&gt;(Such a primer is discussed in Chapter 15, apparently, and Hyde has a note why shell scripts vs Makefiles: &amp;quot;If you have experience developing software by using the command line, you may wonder why I haven’t built the examples with a makefile. I discuss makefiles further in Chapter 15, but I’ve chosen not to use them here for a couple of reasons: (1) If you don’t already know the Make language, I’d prefer to put off teaching that until you’ve mastered a little more assembly language. (2) Using Make would mean writing a separate makefile for each example program. However, the build shell script this section describes works for nearly all the example programs in this book.&amp;quot; I&apos;m not sure I agree, but again, he has his reasons, and his explanation satisfies me that it&apos;s not a decision made lightly.)&lt;/p&gt;
&lt;p&gt;Aside from the Glossary and Answers, though, some hidden gold lies in the &amp;quot;Some Useful C Language Functions&amp;quot;; these are quick definition and description of some of the most common functions in the world, the C standard library. And before you accuse me of being wishy-washy (&amp;quot;you don&apos;t want a Bash primer, but a C stdlib primer is OK?&amp;quot;), remember that Hyde is expecting the reader to be familiar with other languages, many of which have a string intrinsic or built-in type, and therefore those developers may not realize that C required us to work with strings &amp;quot;the hard way&amp;quot;,as pointers to byte arrays that signaled termination with a NULL. (Back in &lt;em&gt;my&lt;/em&gt; day, we just used pointers! And we liked it!)&lt;/p&gt;
&lt;h2&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;As you probably could guess, I love this book. That said, this book is probably going to be on my list of &amp;quot;Books you should read when you have a bunch of free time (which for most people is &apos;never&apos;)&amp;quot;. It&apos;s not that the writing is poor; Hyde has been here before, and knows what to include and how to present it. It&apos;s much more due to the fact that this is not top of my day job&apos;s requirements, and it&apos;s a lot to wade through.&lt;/p&gt;
&lt;p&gt;In many respects, going down this path is the same as going down the path of building your own database, or your own RPC stack, or your own Javascript SPA framework. The knowledge gained here is foundational, and will help programmers with all sorts of different kinds of applications, but will also run the risk of feeling too abstract and removed from the problems of the day. (I say this because I&apos;ve taught workshops at conferences on how to build your own bytecode virtual machine, and those were some of the evaluation comments I got as feedback.)&lt;/p&gt;
&lt;p&gt;To wrap up: I love the book, and I think every programmer should read it. Candor compels me, however, to point out that what readers learn from this book is subtle, philosophical in nature, and hard to articulate to others until you&apos;ve turned it over in your head a few times. I personally think it makes you a better developer, but you&apos;ll need to have at least a little interest in the subject of programming languages to start.&lt;/p&gt;
&lt;p&gt;Meanwhile, I&apos;m eagerly awaiting the physical copy of the book when it comes out, although I do feel kinda bad for the delivery driver who has to bring it to my front porch--it will not be easy getting down the path to my front door with a forklift....&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Disclaimer: No Starch Press sent me a review copy of the book; no other compensation was provided.&lt;/em&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Book Review: Effective C (2nd Ed)</title>
      <link>http://blogs.newardassociates.com/blog/2024/book-review-effective-c.html</link>
      <pubDate>Fri, 20 Sep 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/book-review-effective-c.html</guid>
      	<description>
	&lt;p&gt;No Starch Press sent me a copy of the book &amp;quot;Effective C (2nd Ed)&amp;quot;, by Robert C Seacord, and overall, it&apos;s not bad, though I don&apos;t think it lives up to the &amp;quot;Effective&amp;quot; moniker established by Scott Meyers three decades ago.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Let me get one thing out of the way first: Despite the title, this is not an &amp;quot;Effective&amp;quot; book as originally coined by the master of the Effective-style books (Scott Meyers). Meyers&apos; &amp;quot;Effective C++&amp;quot;, published roughly three decades ago, set not only a high bar to hit in terms of quality and depth of technical insight, but equally so the format. When one picks up an &amp;quot;Effective&amp;quot; book, one expects to see &amp;quot;items&amp;quot; that each tackle a particular problem or concern with the language, typically written in an action-minded format. When you wrote a book in the &amp;quot;Effective&amp;quot; series, you were writing to that standard and that format.&lt;/p&gt;
&lt;p&gt;This book does none of that.&lt;/p&gt;
&lt;p&gt;In fact, it doesn&apos;t even seem to acknowledge the shoes it is either deliberately or accidentally stepping around in. While Meyers has been retired for a few years now, the author, the contributor and both the technical reviewers have been involved in C/C++ standardization efforts, and so most assuredly were not only aware of Scott (and his work), but were probably friends with him at some point--it&apos;s really quite surprising to me that they wouldn&apos;t have some kind of nod or acknowledgement of Scott&apos;s work(s) and some kind of explanation around the title. Maybe it&apos;s me, maybe it&apos;s the fact that Scott and I had some long conversations about defending the quality and approach of the &amp;quot;Effective&amp;quot; moniker back when I was writing &amp;quot;Effective Enterprise Java&amp;quot; in his series two decades ago, but it really strikes me as odd (and disquieting) to see this particular word choice here.&lt;/p&gt;
&lt;p&gt;That doesn&apos;t make it a bad book, &lt;em&gt;per se&lt;/em&gt;, but if you were looking for the next in the generation of mind-opening books in that series, you are not going to be happy with your purchase.&lt;/p&gt;
&lt;h2&gt;Physical&lt;/h2&gt;
&lt;p&gt;Any book that has a winged Cthulhu/mind flayer on the cover trying to look benevolent holding out a helping hand while a glass-helmeted robot sits on its shoulder reading a book is a sign that this is a book that isn&apos;t quite sure where it wants to rest in the world, if you ask me. What&apos;s more, the endorsement quotes also generate a slightly weird feeling, as two of the four are from security professionals--which is the first indication that maybe this book isn&apos;t quite aimed at the same category as one might think.&lt;/p&gt;
&lt;p&gt;Opening into the front matter, it&apos;s clear that Seacord and his supporting staff (contributor and reviewers) are all very smart people--they work on popular C/C++ compiler toolchains, they sit on the standards committees, and so on. There is zero doubt that these folks know what they&apos;re talking about when it comes to C. But as you read through Seacord&apos;s &lt;em&gt;bona fides&lt;/em&gt; you notice that he&apos;s done a lot of things around the intersection of C and security; for example, he wrote &amp;quot;Secure Coding in C and C++&amp;quot; back in 2013. His reviewer for the second edition comes from a similar background, and you begin to get a sense that maybe this book isn&apos;t quite for the application developer.&lt;/p&gt;
&lt;p&gt;The other thing to note is that on the front cover, it very clearly and prominently displays a banner that reads &amp;quot;Updated to cover C23&amp;quot;, the 2023 version of the C programming language standard. More on that later.&lt;/p&gt;
&lt;p&gt;As you get to the title page, however, the subtitle threw me for a leap: &amp;quot;Effective C / 2nd Edition / An Introduction to Professional C Programming&amp;quot;.&lt;/p&gt;
&lt;p&gt;And this is where my main criticism of the book comes: The book&apos;s title leads me to believe that this is going to help an existing C developer become a better one, particularly with respect to the new C23 standard; instead, the book&apos;s apparent aim is to teach the basics of the C programming language to people who&apos;ve never programmed with it before, and it&apos;s very apparent when you read the &amp;quot;Who This Book is For&amp;quot; section in the Introduction that Seacord is definitely starting from zero:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;This book is an introduction to the C language. It is written to be as accessible as possible to anyone who wants to learn C programming, without dumbing it down. In other words, we didn’t overly simplify C programming in the way many other introductory books and courses might. These overly simplified references will teach you how to compile and run code, but the code might still be wrong. Developers who learn how to program C from such sources will typically develop substandard, flawed, insecure code that will eventually need to be rewritten (often sooner than later). Hopefully, these developers will eventually benefit from senior developers in their organizations who will help them unlearn these harmful misconceptions about programming in C and help them start developing professional-quality C code. On the other hand, this book will quickly teach you how to develop correct, portable, professional-quality code; build a foundation for developing security-critical and safety-critical systems; and perhaps teach you some things that even the senior developers at your organization don’t know.&lt;/p&gt;
&lt;p&gt;&amp;quot;Effective C: An Introduction to Professional C Programming, 2nd edition, is a concise introduction to essential C language programming that will soon have you writing programs, solving problems, and building working systems. The code examples are idiomatic and straightforward. You’ll also learn about good software engineering practices for developing correct, secure C code.&lt;/p&gt;
&lt;p&gt;&amp;quot;In this book, you’ll learn about essential programming concepts in C and practice writing high-quality code with exercises for each topic.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I can&apos;t quite tell who Seacord thinks is his audience for this book. Programmers from other languages who want to learn C? System administrators who want to make the leap to programming? Hobbyists who want to learn how to program their Raspberry Pi devices to automate their doggie door? He ends the Introduction with this: &amp;quot;You’re about to embark on a journey from which you will emerge a newly minted but professional C developer.&amp;quot; But honestly, I&apos;m not sure that&apos;s a true statement, since (as we&apos;ll see in a second) the ToC is really about teaching the reader the C language, but not much of the supporting cast and ecosystem that most C developers would need to know in order to be able to operate in a professional setting.&lt;/p&gt;
&lt;p&gt;Let&apos;s dig in a little deeper.&lt;/p&gt;
&lt;h2&gt;Contents&lt;/h2&gt;
&lt;p&gt;At 300+ pages (including front and back matter), Effective C (&amp;quot;EC&amp;quot; for short) is no pamphlet, but it&apos;s not going to be a paperweight on your shelf, either. That isn&apos;t bad--books should be judged by their content and not their count. And, in fact, the aforementioned &amp;quot;Effective&amp;quot; books by Meyers were always on the skinny side, yet packed to the brim with good stuff.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 1: Getting Started with C&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Almost from the first paragraph, the inconsistency of the target audience comes to bear. Seacord opens by showing the traditional &amp;quot;Hello World&amp;quot; C program, which (for convenience) I repeat here:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

int main() {
    puts(&amp;quot;Hello, world!&amp;quot;);
    return EXIT_SUCCESS;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;He then follows this with a quick description of the program, starting with, &amp;quot;The first two lines use the #include preprocessor directive, which behaves as if you replaced it with the contents of the specified file at the exact same location.&amp;quot;&lt;/p&gt;
&lt;p&gt;OK, what?&lt;/p&gt;
&lt;p&gt;If this is a neophyte&apos;s introduction to the C language, they&apos;ve almost never heard of the preprocessor before, and certainly have no idea why one would want to &amp;quot;replace (the text) with the contents of the specified file&amp;quot;. He does go on to describe those two files as header files, but ends that paragraph with the lines &amp;quot;You need to include the declarations for any library functions that you use in your program. (You’ll learn more about the appropriate use of headers in Chapter 9.)&amp;quot;&lt;/p&gt;
&lt;p&gt;Let&apos;s be clear about something: If the intended reader is brand new to C, they didn&apos;t need to know what those lines do, only that you need to &amp;quot;#include&amp;quot; them in order to make use of them. If the intended reader has some familiarity with C, then the deeper explanation perhaps is merited, but then do they really need to be told what &amp;quot;Hello World&amp;quot; is doing?&lt;/p&gt;
&lt;p&gt;This example then continues into the next section, wherein Seacord shows using &amp;quot;cc&amp;quot; to compile the code into an executable and running it. Again, if this is for neophytes, that&apos;s appropriate, but he never discusses where &amp;quot;cc&amp;quot; comes from or what might need to be installed if the command fails on the neophyte&apos;s machine. (In fact, his only suggestion if it doesn&apos;t compile is to &amp;quot;compare the program text from Listing 1-1 to your program and make sure they are the same.&amp;quot; Not particularly helpful.)&lt;/p&gt;
&lt;p&gt;This whole chapter is all over the map like this; for example, he spends two-and-a-half pages on the differences between &amp;quot;Implementation-defined behavior&amp;quot;, &amp;quot;Unspecified behavior&amp;quot;, &amp;quot;Undefined behavior&amp;quot;, &amp;quot;Locale-specific behavior&amp;quot;, and &amp;quot;Common extensions&amp;quot;, which considering just four pages earlier he was introducing Hello World and the main() function, just seems weird.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 2: Objects, Functions, and Types&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Next, we discuss &lt;em&gt;objects&lt;/em&gt;, which is an odd term for a language that is very not object-oriented. I suspect the term is used in the C standard because as a generic word to describe the things that variable names point to, but in a world where &amp;quot;objects&amp;quot; are commonly associated with object-oriented languages like Java and C# (and of course C++), it seems an odd choice to fixate on that term--again without much nod to any of the ways somebody might have heard it defined differently--in an introductory text.&lt;/p&gt;
&lt;p&gt;He then introduces the notion of functions by creating a swap function, but at first does it incorrectly (passing the integers by value) before showing how to pass the integers by reference and thus, introduce pointers. This seems an obtuse way to introduce the subject, particularly in what is intended to be an introductory text, particularly when he&apos;s spent no time really talking about what an integer is or what it represents. In fact, the introduction of variables is as follows: &amp;quot;When you declare a variable, you assign it a type and provide it a name, or identifier, by which the variable is referenced. Optionally, you can also initialize the variable.&amp;quot; That&apos;s it.&lt;/p&gt;
&lt;p&gt;To be fair, he gets into the different primitive types of the language, (booleans, characters, integers, floats, and so on) later, but even here, he&apos;s clearly writing for an audience that isn&apos;t a beginner: &amp;quot;The signed and unsigned integer types are used to represent integers of various widths. Each platform determines the width for each of these types, given some constraints. Each type has a minimum representable range. The types are ordered by width, guaranteeing that wider types are at least as large as narrower types. ...&amp;quot; (He later states that he will go into &amp;quot;excrutiating detail&amp;quot; about integer types in the next chapter, which begs the question, why not cover that material here rather than later?)&lt;/p&gt;
&lt;p&gt;I&apos;ll cease diving into examples at this point, because I think I&apos;m making my point clear.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 3: Arithmetic Types&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 4: Expressions and Operators&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 5: Control Flow&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 6: Dynamically Allocated Memory&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 7: Characters and Strings&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 8: Input/Output&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 9: Preprocessor&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 10: Program Structure&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 11: Debugging, Testing, and Analysis&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;Seacord ostensibly wants this to be a beginner&apos;s book, but he keeps not writing for beginners. When writing a book for beginners, the author needs to take careful steps to introduce new concepts one at a time, ignoring details of implementation unless they are necessary to understand the concept. It&apos;s not easy writing for beginners, particularly when you (the author) are steeped in the myriad of implementation details on a daily basis.&lt;/p&gt;
&lt;p&gt;Honestly, if I were an editor at No Starch Press and Seacord were asking my advice for a 3rd edition, it would be this: Write this same book, but assume the reader knows basic C. They know what a function is, they know the basic types, they know how to compile and link simple programs. Now, take them one level deeper in all of those things. Let another book (or YouTube tutorial, or hobbyist exploration and spelunking) teach them the core basics, and you focus on explaining the &amp;quot;why&amp;quot; and &amp;quot;how&amp;quot; of the language. For example, at one point when introducing enumeration types, you state, &amp;quot;For portability and other reasons (Meneide and Pygott 2022), it is always better to specify the enumeration type.&amp;quot; Why? What are those reasons? The reference to the other work is always nice, but summarize those reasons and lay them out. (Ironically, much of that chapter is at the level I would expect of the work I&apos;m suggesting he write, and could probably be kept as-is with a few minor edits. In fact, much of the remainder of the book could probably be pivoted to this new, differently-assumed, audience without requiring much work.)&lt;/p&gt;
&lt;p&gt;I can&apos;t say that I can recommend this book to beginners--I&apos;d have a hard time recommending this to some of my college students, in fact, and many of them have studied Java (and after taking a class with me, Kotlin and/or Swift). The prose is quite precise in places, and Seacord clearly knows the C language, the standard, the history, and the &amp;quot;whys and wherefores&amp;quot; of C. What I&apos;m not sure he realizes is how to write for beginners.&lt;/p&gt;
&lt;p&gt;If you&apos;re already familiar with the basics of C, this book can seriously help you &amp;quot;level up&amp;quot; in your C knowledge, and bring you closer into the world of how the C language is &amp;quot;put together&amp;quot; and operates. If you&apos;re familiar with another C-like language, a la Java or C#, this book could probably serve as a way to get into writing C, but there may be some terminology issues that I&apos;m not picking up on. (The &amp;quot;curse of knowledge&amp;quot; hits me just as hard as it does Seacord, which is why I generally don&apos;t write beginner-level books!)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Disclaimer: No Starch Press sent me a review copy of the book; no other compensation was provided.&lt;/em&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Book Review: Strange Code</title>
      <link>http://blogs.newardassociates.com/blog/2024/book-review-strange-code.html</link>
      <pubDate>Thu, 12 Sep 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/book-review-strange-code.html</guid>
      	<description>
	&lt;p&gt;No Starch Press sent me a copy of the book &amp;quot;Strange Code&amp;quot;, by Ronald T Kneusel, and honestly, they had me at &amp;quot;esolangs&amp;quot;. But more than that, the book opines on reasons why studying programming languages, including their esoteric kin, is a useful and productive endeavor.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;First off, let&apos;s get something out of the way right now: Being the huge fan of programming languages that I am, I am almost &lt;em&gt;always&lt;/em&gt; a fan of a book that talks about how to build a programming language. This one not only talks about some of the concepts involved in doing that, &lt;em&gt;and&lt;/em&gt; shows how to build two custom languages (Filska and Firefly), &lt;em&gt;AND&lt;/em&gt; talks about a few popular esoteric languages and how they warp your brain in a good way, it takes the unusual step (in Part II) of examining some languages that Kneusel describes as &amp;quot;atypical&amp;quot;, which makes them unknown to most developers, which have some interesting and useful properties. His coverage of CLIPS, alone, is worth the price of admission here.&lt;/p&gt;
&lt;p&gt;Secondly, I love this book because Kneusel&apos;s history so closely parallels my own:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;My first exposure to programming came in the summer of 1980. It involved an Apple II+ computer. As principal of the lo­cal high school, my father was able to bring it home for us to play with over the summer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In my case, my parents spent my father&apos;s Christmas bonus to buy an Apple II+ in 1979.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Apple II+ included a version of unstructured BASIC in ROM called Applesoft. As far as BASIC programming languages go, it was somewhat limited. However, it opened a new world to me, and I ran with it, writing small program after small program as I explored what the Apple II+ was and could do. It could ask questions, interpret answers, calculate formulas, plot pictures, and make sounds. And all of that power was at the tips of my 14-­year-­old fingers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;My fingers were a little bit younger than his, but the excitement was the same. Dad showed us a game program, &amp;quot;Little Brick Out&amp;quot; (basically one of those early &amp;quot;pong but you&apos;re knocking bricks out&amp;quot; games) and then he showed us the Applesoft BASIC code that powered the game, and frankly, I was hooked.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Of course, I wanted one of these godlike machines for my own. My fa­ther, likely thinking it would put me off, told my younger brother, Bob, and me we could have one if we learned how to program it. Challenge accepted!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In my case, Dad was learning Applesoft BASIC, and worked out a barter deal with the computer shop whereby he taught public classes on the language, in exchange for hardware and software purchases. We went from the base unit by itself (hooked up to a tape recorder and a small color TV) to a green-screen monitor (soooo much easier on the eyes) and first one, then &lt;em&gt;two&lt;/em&gt; floppy drives. I asked for--and got--a joystick for my birthday. But more importantly, Dad let me tag along and follow him to the store when he taught the classes, and although it was hard for me to pay attention during the class, the idea of programming was laid into my genetic structure early.&lt;/p&gt;
&lt;p&gt;You can already see where this is going--Kneusel&apos;s history and my own are so similar I could&apos;ve been his brother. I taught myself BASIC and (a little) 6502 assembly, as he did, but couldn&apos;t get to Pascal because we didn&apos;t have the necessary CP/M card to run it. (Which &lt;em&gt;sucked&lt;/em&gt; because I really wanted to learn how to program something like Wizardry, which was my game addiction on that machine for many years.) I wouldn&apos;t get to Pascal until high school, when a friend &amp;quot;loaned&amp;quot; me his copy of Turbo Pascal 5.5 for my PC, and then later Turbo C/C++. But I digress--my point is, this book feels like &amp;quot;coming home&amp;quot; for me.&lt;/p&gt;
&lt;h2&gt;Contents&lt;/h2&gt;
&lt;p&gt;The book is a respectable 450+ pages (including front and back matter), so this is no &amp;quot;I can read it in the bathroom in a week&amp;quot; kind of book. This is rich, meaty, hearty fare that will require any programmer reader to spend some serious cycles to ingest and absorb.&lt;/p&gt;
&lt;p&gt;More importantly, Kneusel lays out the intent of the book right in the first chapter: &amp;quot;The pur­pose of this book is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;To give you a sense of where programming languages came from and provide some context for the languages we use today and the structures they contain.&lt;/li&gt;
&lt;li&gt;&amp;quot;To explain some of the essential elements of programming lan­guages, so you become familiar with terms like Turing machine and Turing complete.&lt;/li&gt;
&lt;li&gt;&amp;quot;To expand your thinking about what a programming language can be and how it can express thought and process in creative and el­ egant ways. We’ll do this by exploring various programming lan­guages ranging from the unusual to the downright bizarre.&lt;/li&gt;
&lt;li&gt;&amp;quot;To have fun! We’ll create our own programming languages, and see how we can use them to implement some algorithms. We’ll even put one on a small computer for standalone projects (the BBC micro:bit).&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Clearly, this is not a beginning programmer&apos;s book, but fortunately, it also doesn&apos;t require the reader to have a postdoctoral degree in Computer Science, either. The book states, &amp;quot;If you are a student, you’ll hopefully see that programming can be more than what you may perceive it to be based on your introductory programming courses, as necessary as they are. If you’re a hobbyist, you’re likely already somewhat familiar with esolangs and are looking to feed your passion.&amp;quot; but as I read it, it really felt more that this was for the professional developer who is looking to understand what&apos;s going on inside and/or below the languages they use, and to grok the &amp;quot;why&amp;quot; of certain languages. I don&apos;t know if the student has the necessary perspective to get that, and while the hobbyist might get something out of this, it&apos;s hard for me to say--I left &amp;quot;hobbyist&amp;quot; status behind when I took that first programming job fifteen years after getting that Apple II+.&lt;/p&gt;
&lt;p&gt;The book uses Python as its implementation language (where it needs to provide implementation), which is a reasonable choice, given Python&apos;s popularity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Part I: On Programming Languages&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 1: A Cherry-Picked Review of Programming Languages&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It&apos;s a lovely little bit of history and archaeology (Kneusel calls it paleontology, likening different language eras to different eras of dinosaurs), but there is one nit: he references the website  &lt;a href=&quot;http://www.info.univ­angers.fr/~gh/hilapr/langlist/langlist.htm&quot;&gt;http://www.info.univ­angers.fr/~gh/hilapr/langlist/langlist.htm&lt;/a&gt;, which unfortunately in my Chrome browser doesn&apos;t render. I have to assume the website did render at one point (it appears to be an https/http issue), but it does take a bit of the wind out of the reader&apos;s sails to get excited about seeing more languages and being presented with a blank screen.&lt;/p&gt;
&lt;p&gt;His coverage of the foundational languages (FORTRAN, Lisp, COBOL) and the &amp;quot;Ur-Languages&amp;quot; (Algol, APL, BASIC, PL/I, Logo, Simula, Pascal, Prolog, Smalltalk, and Standard ML) is pretty decent, though in my opinion he clearly has the most fun showing off the last three (Prolog, Smalltalk, and SML). Those are very different ways of thinking about code, and all three are still wildly relevant today. (As a matter of fact, any of those could be used to build a modern web application, which is hard to say about Logo!)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 2: The Essentials of Programming Languages&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It&apos;s a very basic treatise of what makes up a programming language. If you&apos;ve taken a language survey course as part of a CS program, there&apos;s little to nothing new here; if you&apos;ve never explored this space, it&apos;s a pretty reasonable introduction (and a lightweight one at that) to the topic. (I do love that he uses an Apple II+ BASIC program and its representation as the example, though, instead of something more modern.) He shows off UCSD Pascal p-code, the ancient predecessor to Java/JVM bytecode and .NET CIL, which for some will be the first time seeing something like that. (Matter of fact, now I want to find a reference doc on the UCSD p-code opcode set.) He covers most of the popular categorizations of programming languages (static and dynamically typed, the core data structures like arrays, lists, etc, and so on), but it&apos;s mostly a concept-heavy chapter that readers could probably skip and come back to if they aren&apos;t as interested in the broad categories of programming. (That said, you risk not having some of the definitions in your head as you move to later chapters--&lt;em&gt;caveat emptor&lt;/em&gt;.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 3: Turing Machines and Turing Completeness&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This chapter feels a little bit like a digression from the main point; yes, it&apos;s helpful to discuss what a &amp;quot;Turing-complete language&amp;quot; means, but I&apos;m not sure that we really needed this deep a dive or to explore a Python implementation of one. It&apos;s definitely the heaviest &amp;quot;academic&amp;quot; chapter in the book, and readers who are new to the material may want to come back to this one.&lt;/p&gt;
&lt;p&gt;Then again, I&apos;ve always been a little less interested in the theory and math around languages, so this may just not be a chapter for me.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Part II: Atypical Programming Languages&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 4: Forth&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Forth is an entirely stack-centric language, which feels like something of a waste... until you learn that most virtual machines (the JVM, the .NET runtime, and others) are all stack-based virtual machines. Learning Forth gets you a leg up on understanding how those machines can do all their wonderful things entirely in terms of an execution stack.&lt;/p&gt;
&lt;p&gt;(True story, I have a professional colleague/friend from 20 years back who is a huge Forth nut, and is constantly threatening to write a book on Forth--Lionel, if you&apos;re reading this, you should totally write it, and No Starch Press might even print it!)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 5: SNOBOL&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;quot;SNOBOL is a text pattern matching lan­ guage developed in the 1960s. Modern pro­grammers might find its syntax quaint, and maybe even a tad frustrating, but I suspect the power of the language will shine through in the end as we explore its features, some of which are still with us in modern languages like Python.&amp;quot; With these words, Kneusel opens the chapter on SNOBOL (“StriNg Oriented and symBOlic Language”), and with a philosophy of &amp;quot;All the world&apos;s a string&amp;quot;, SNOBOL is off and running. Which, if you think about it, is quite true--almost all the data we hand back and forth across network lines are strings (usually shoved into JSON or XML).&lt;/p&gt;
&lt;p&gt;Lest you think this is purely an exercise in trying to shoehorn old languages into modern conversations, take a hard look at the part of this chapter entitled, &amp;quot;Machine Learning with SNOBOL&amp;quot;: &amp;quot;the goal of this section is to build a complete SNOBOL ap­plication to classify datasets using a simple machine learning technique--a &lt;em&gt;nearest neighbor&lt;/em&gt; classifier.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 6: CLIPS&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is one of my favorites; I discovered CLIPS when I was looking at logic languages, and in particular when I discovered the Java flavor of CLIPS, called JESS (Java Expert System Shell). (Sadly, JESS development seems to have stalled since 2006.) If you&apos;ve ever spent any time exploring the world of &amp;quot;expert systems&amp;quot; or &amp;quot;rules engines&amp;quot;, you owe it to yourself to read this chapter. (By the way, CLIPS has bindings for both Java and .NET, so the material in this chapter is actually directly applicable to your day job, if you&apos;re in either of those platforms.) In many respects CLIPS occupies the same space as Prolog, but the syntax is in some ways a little easier to parse, and there&apos;s less emphasis around &amp;quot;the cut&amp;quot; (a Prolog-ism). That said, the syntax is essentially Lisp, so if you&apos;re not a fan of parentheses....&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Part III: Esoteric Programming Languages&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 7: The ABCs of ABCs&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 8: FRACTRAN&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 9: Piet&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 10: Brainfuck&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 11: Befunge&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;These are all esoteric programming languages, selected because (a) esolangs are fun, (b) esolangs take some of programming&apos;s most cherished traditions and turn them upside-down or do away with them completely, leaving you to think whether you wanted to or not, and (c) no seriously esolangs are fun! Kneusel takes each esolang, explains them, discusses why it holds interest, then shows how to implement them in Python (and sometimes another language as well).&lt;/p&gt;
&lt;p&gt;(By the way, if your religious upbringing makes it hard to pronounce the language discussed in Chapter 10, it&apos;s also commonly called &amp;quot;BF&amp;quot;, which should be easier for the &amp;quot;fuck&amp;quot;-challenged.)&lt;/p&gt;
&lt;p&gt;Oh, and just because it&apos;s fun to toss this off as the last comment in this section, the following is a legal Befunge program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;v&amp;quot;How now brown cow?&amp;quot;0
 &amp;gt;:v
^,_91+,@
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;PART IV: Homegrown Esolangs&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 12: Filska&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 13: Using Filska&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 14: Firefly&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 15: Using Firefly&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Filska and Firefly are Kneusel&apos;s new contributions to the field, and they&apos;re both... interesting. Filska asks, &amp;quot;what is it like to program in a language where each subprogram can manipulate only a single memory location?&amp;quot;, while Firefly holds that &amp;quot;A Firefly program is a series of single­character instructions that either move the firefly around the grid, set the way its luminous trail acts, or make the firefly sing a note.&amp;quot; While they sound somewhat frivolous on the surface, Chapters 13 and 15 show how to build some pretty interesting non-trivial things using each language, and each one definitely qualifies as &amp;quot;makes you think&amp;quot; fodder.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 16: Going Further&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is more of a &amp;quot;Miscellaneous&amp;quot; chapter, in which Kneusel lists a few more esolangs, and then provides some resources around programming languages, including a number of solid books (many of which I&apos;ve also found useful over the years).&lt;/p&gt;
&lt;h2&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;As you probably could guess, I love this book. That said, this book is probably going to be on my list of &amp;quot;Books you should read when you have a bunch of free time (which for most people is &apos;never&apos;)&amp;quot;. It&apos;s not that the writing is poor; Kneusel is clearly no neophyte author, as his bio states: &amp;quot;He is the author of Practical Deep Learning: A Python­Based Introduction (No Starch Press, 2021), Math for Deep Learning: What You Need to Know to Understand Neural Networks (No Starch Press, 2021), Numbers and Computers (Springer, 2017), and Random Numbers and Computers (Springer, 2018).&amp;quot; It&apos;s much more due to the fact that this is just a space where too few programmers really choose to congregate.&lt;/p&gt;
&lt;p&gt;In many respects, going down this path is the same as going down the path of building your own database, or your own RPC stack, or your own Javascript SPA framework. The knowledge gained here is foundational, and will help programmers with all sorts of different kinds of applications, but will also run the risk of feeling too abstract and removed from the problems of the day. (I say this because I&apos;ve taught workshops at conferences on how to build your own bytecode virtual machine, and those were some of the evaluation comments I got as feedback.)&lt;/p&gt;
&lt;p&gt;Frankly, I love the book, and I think every programmer should read it. Candor compels me, however, to point out that what readers learn from this book is subtle, philosophical in nature, and hard to articulate to others until you&apos;ve turned it over in your head a few times. I personally think it makes you a better developer, but you&apos;ll need to have at least a little interest in the subject of programming languages to start.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Disclaimer: No Starch Press sent me a review copy of the book; no other compensation was provided.&lt;/em&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Book Review: Dead Simple Python</title>
      <link>http://blogs.newardassociates.com/blog/2024/book-review-dead-simple-python.html</link>
      <pubDate>Wed, 11 Sep 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/book-review-dead-simple-python.html</guid>
      	<description>
	&lt;p&gt;I bought a copy of the book &amp;quot;Dead Simple Python&amp;quot;, by Jason C McDonald, and I have to say, this is my new go-to book for book recommendations on learning Python.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;For starters, this is &lt;em&gt;not&lt;/em&gt; a pocket-sized book; weighing in at just under 700 pages (including both front and back matter), this sucker is quite possibly a deadly weapon in the right hands. That, to me, is a reflection of the Python ecosystem: rich, deep, and easily the equivalent of any of the other mainstream ecosystems out there (Java, .NET, Javascript, and so on). To try and cover Python by only covering the syntax would be doing the reader a disservice every bit as much as it would be do teach Java or C# without going over the standard libraries (&lt;code&gt;java.util&lt;/code&gt;, &lt;code&gt;System.IO&lt;/code&gt;, etc). Considering that much of the Python experience is heavily influenced by Guido&apos;s &amp;quot;Batteries Included&amp;quot; approach to the language, covering more than just the language seems an excellent choice.&lt;/p&gt;
&lt;p&gt;It also reflects the goal of the book, which McDonald highlights very early on in the Introduction in the section &amp;quot;Who Is This Book For?&amp;quot;: &amp;quot;If you are already familiar with another programming language and now wish to learn Python for the first time without slogging through beginner-oriented courses, this book is for you.&amp;quot; McDonald has done the thing I frequently find authors fail to do with their books: Establish the target persona, and ruthlessly avoid anything that doesn&apos;t meet that target persona&apos;s needs. The professional programmer, who already knows about inheritance, classes, and flow control, doesn&apos;t need examples showing the concept of an &lt;code&gt;if&lt;/code&gt; statement, they just need to see the syntax and any semantics that might be different from what they&apos;re used to. (And Python does have a few of those--I&apos;ve never seen a language that has allows an &amp;quot;else&amp;quot; clause attached to a &amp;quot;while&amp;quot; loop before. Or &amp;quot;for&amp;quot; loops. Wild.)&lt;/p&gt;
&lt;p&gt;McDonald&apos;s goal is also not just to teach the cold hard facts of syntax, but also the &amp;quot;Python way&amp;quot;, which the community has captured in the Zen of Python, an official document that captures the essence of how good citizens of the Python community should think about things. McDonald frequently references the Zen, and liberally quotes from other books (which is a practice that I think is highly admirable--too many books seem to pretend that there is no other book out there but their own), which I find helps the new-to-Python reader know where to go in the larger community to see and feel more about how Python approaches things.&lt;/p&gt;
&lt;p&gt;But if you&apos;re from No Starch Press reading this review, one quibble: The back of the book proudly proclaims &amp;quot;I Lie Flat!&amp;quot; and that the book won&apos;t &amp;quot;snap shut&amp;quot;; frankly, that&apos;s not true. As I write this, I have the book open to the &amp;quot;Brief Contents&amp;quot; page, requiring me to carefully balance the book&apos;s back half against the laptop screen so that I can use two hands to type while being able to read the contents to replicate the list in the post below. It&apos;s probably not the fault of the binding--after all, 700 pages is pretty heavy to hold open by itself anywhere before page 250 or after page 450--but it does like to smile innocently back at me while I glare at the back of the book because it just &lt;em&gt;whoomped&lt;/em&gt; closed while I was trying to read the code while typing it in. Maybe just drop the logo.&lt;/p&gt;
&lt;h2&gt;Contents&lt;/h2&gt;
&lt;p&gt;As I said before, DSP is a hefty tome, and covers a wide variety of topics:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Part I: The Python Environment&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 1: The Python Philosophy&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Nice little read of how Python thinks about things.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 2: Your Workbench&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is your classic &amp;quot;Getting Started&amp;quot; section, describing all the different ways Python and its associated tools can be installed and used.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 3: Syntax Crash Course&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It doesn&apos;t cover all the permutations--each of the various subjects get deeper coverage later--but it does get you the basics of Python&apos;s scripting syntax, such as variables, looping and conditionals, how to use objects, that sort of thing. In theory, if you had to suddenly support a Python script and had never looked at the language, you could probably use this as your &amp;quot;I only have time to read one chapter&amp;quot; candidate.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 4: Project Structure and Imports&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Chapter 4&apos;s location struck me as odd at first; I wasn&apos;t really expecting a lecture on how to arrange the files in my project this early in the book. After reading it, though, I can see why it&apos;s here--so much of Python is reliant on conventions, and Python in particular really stresses things &amp;quot;be done a certain way&amp;quot; to work best. Getting that into a reader&apos;s head as early as possible is probably a good idea here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Part II: Essential Structures&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 5: Variables and Types&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 6: Functions and Lambdas&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 7: Objects and Classes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 8: Errors and Exceptions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;These four chapters are your &amp;quot;deep dive&amp;quot; into the semantics of each subject.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Part III: Data and Flow&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 9: Collections and Iteration&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 10: Generators and Comprehensions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 11: Text IO and Context Managers&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 12: Binary and Serialization&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Chapter 10 I kinda wanted to be inside Part II, since I think of these in the same vein as lambdas, but it&apos;s not unreasonable that they appear here, after collections and iterators have been covered. Still, it feels a little out of place compared to the rest in here. (I also suspect that there&apos;s a balancing act at work here--each Part has four chapters, with exception of Part IV, which has five.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Part IV: Advanced Concepts&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 13: Inheritance and Mixins&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 14: Metaclasses and ARCs&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 15: Introspection and Generics&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 16: Asynchrony and Concurrency&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 17: Threading and Parallelism&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If Chapter 10 felt like a sore thumb, then Chapter 13&apos;s place here in &amp;quot;Advanced Concepts&amp;quot; is the clown suit worn to a funeral--I have never thought of inheritance as an &amp;quot;advanced&amp;quot; concept, and I don&apos;t know that any &amp;quot;formally-trained&amp;quot; (Java, C#, C++, Smalltalk, ...) object-oriented developer would either. Personally I&apos;d have preferred this to be in Part II, but the rest... they&apos;re definitely &amp;quot;advanced&amp;quot;.&lt;/p&gt;
&lt;p&gt;Matter of fact, unless you&apos;re seriously prepared to drop some serious mental acid and open your brain, I&apos;d recommend passing on Part IV until you&apos;ve had some time playing with the language under your belt. Don&apos;t get me wrong, this is the good stuff (and highlights just how &amp;quot;well put together&amp;quot; the Python environment is), but understanding some of this is definitely only for those who can explain the difference between contravariance and covariance in generic parameters in Java (or C# or C++ or....).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Part V: Beyond the Code&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 18: Packaging and Distribution&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 19: Debugging and Logging&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 20: Testing and Profiling&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapter 21: The Parting of the Ways&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;These four bring us back to practical &lt;em&gt;terra firma&lt;/em&gt; again, with clear and direct discussion of each of these programming-adjacent topics that are really quite crucial to success in programming. It&apos;s also important to me that I point out that this is the first book that describes how to use &lt;code&gt;pdb&lt;/code&gt;, the Python debugger.&lt;/p&gt;
&lt;p&gt;Let me be more transparent: this is the first book that I&apos;ve ever seen even &lt;em&gt;talk&lt;/em&gt; about the Python debugger--in fact, I didn&apos;t know Python &lt;em&gt;had&lt;/em&gt; a debugger (at least not a console-mode debugger) until this book. Made me take a second and look at my Python installation (Homebrew, on macOS) to see if there was a launcher script, and, sure enough... nope! Nothing. So then I flip to the back of the book to that chapter, and discover that &lt;code&gt;pdb&lt;/code&gt; is, like so much else in Python, a Python module that ships with the base installation. Ah! That would explain why I&apos;ve not seen it before. Cost of the book justified, right there.&lt;/p&gt;
&lt;h2&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;As is probably obvious, I&apos;m a fan of the book, and I plan on keeping it on the shelf nearby when I reach for Python as a solution to whatever problem I&apos;m facing. There&apos;s enough reference material in here that I can see myself going to the book to look something up to refresh my memory rather than Googling it, particularly for things that are more conceptual than syntactic. The coverage is extensive but skips the trivia, and its emphasis on quoting the community and the Zen of Python helps the would-be Pythonista come up to speed on the &amp;quot;why of how&amp;quot; quickly. If you&apos;re a programmer wanting to learn Python (and you like books over videos!), this is where I&apos;m going to send you.&lt;/p&gt;
&lt;p&gt;If you&apos;re a data scientist or AI/ML researcher, I think there&apos;s still a lot here for you, but you may find about 50% of the book&apos;s content unnecessary--it&apos;s definitely written for those of us who would use Python to build applications. Unfortunately, it&apos;s not a matter of telling you which chapters to ignore, as they&apos;re all useful (except maybe you don&apos;t need most or all of Part IV). It&apos;s more the depth and assumptions made about how you&apos;re going to use Python that comes through in the text--as an application developer, it&apos;s in tune with what I care about, but if you&apos;re a data scientist, you may want to pivot to a different book.&lt;/p&gt;
&lt;p&gt;If there was one criticism, I kinda wish there was a chapter or two that had a bit more of how to do the various things we want to do in Python: access a database (relational or otherwise), stand up an HTTP endpoint, that sort of thing. Wouldn&apos;t have to be much, just even a list of popular packages with one or two code snippets for a few of them, highlighting and showcasing just how mammoth and diverse the Python ecosystem is. That said, it&apos;s a nit, and definitely not something that should keep this book out of any programmer&apos;s hands.&lt;/p&gt;
&lt;p&gt;Well done.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;While No Starch Press has sent me review copies of books before, this was not one of them; this one I bought in a bookstore after flipping through the pages.&lt;/em&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Manager Antipatterns</title>
      <link>http://blogs.newardassociates.com/blog/2024/management-antipatterns.html</link>
      <pubDate>Thu, 29 Aug 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/management-antipatterns.html</guid>
      	<description>
	&lt;p&gt;Ever had a manager who was clearly smart, but had no idea how to manage? Or one of those managers who was &amp;quot;laterally promoted&amp;quot; over from a team that was radically different from what your team did? There&apos;s a whole host of mistakes that companies often fall prey to with respect to those they have leading teams, and I thought it a good idea to collect them into one place, under the umbrella heading of &amp;quot;manager antipatterns&amp;quot;. (Because &amp;quot;antipatterns&amp;quot; sounds better than &amp;quot;often-repeated mistakes that we really should have learned from so that we don&apos;t make them again, and yet...&amp;quot;.)&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Within each of these, I try to provide a barebones pattern form, but most importantly, advice on how to rectify the situation, split into three different forks: when you work for that manager, when you have that manager reporting to you, and when you are that manager.&lt;/p&gt;
&lt;p&gt;A sample:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;../../manager-tips/absentee-manager.html&quot;&gt;&amp;quot;The Absentee Manager&amp;quot;&lt;/a&gt;: &amp;quot;What manager?&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../manager-tips/bomb-manager.html&quot;&gt;&amp;quot;The Bomb Manager&amp;quot;&lt;/a&gt;: &amp;quot;We need to toss it all and start over.&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../manager-tips/c-buddy-manager.html&quot;&gt;&amp;quot;The C-Buddy Manager&amp;quot;&lt;/a&gt;: &amp;quot;Why yes, the CxO is my friend, and they asked me to take over this team.&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../manager-tips/funnel-manager.html&quot;&gt;&amp;quot;The Funnel Manager&amp;quot;&lt;/a&gt;: &amp;quot;Wait until you hear what my boss told me today!&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../manager-tips/hammer-manager.html&quot;&gt;&amp;quot;The Hammer Manager&amp;quot;&lt;/a&gt;: &amp;quot;I only know how to use a hammer, so I&apos;m going to hammer away with it&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../manager-tips/hlc-manager.html&quot;&gt;&amp;quot;The Headless Chicken Manager&amp;quot;&lt;/a&gt;: &amp;quot;OMG OMG OMG I don&apos;t know what to do OMG OMG OMG&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../manager-tips/laissez-faire-manager.html&quot;&gt;&amp;quot;The Laissez-Faire Manager&amp;quot;&lt;/a&gt;: &amp;quot;I&apos;m going to be the opposite of a micromanager, and leave them totally alone&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../manager-tips/lateral-move-manager.html&quot;&gt;&amp;quot;The Lateral-Move Manager&amp;quot;&lt;/a&gt;: &amp;quot;Let&apos;s take a manager from one group and move them to run a team in a totally different area of the company&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../manager-tips/perfectionist-manager.html&quot;&gt;&amp;quot;The Perfectionist Manager&amp;quot;&lt;/a&gt;: &amp;quot;Hey, it&apos;s MY team, so the work isn&apos;t done until I think it&apos;s perfect.&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../manager-tips/smartest-engineer-manager.html&quot;&gt;&amp;quot;The Smartest-Engineer Manager&amp;quot;&lt;/a&gt;: &amp;quot;Let&apos;s promote the smartest engineer on the team to manager&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../manager-tips/sphinx-manager.html&quot;&gt;&amp;quot;The Sphinx Manager&amp;quot;&lt;/a&gt;: &amp;quot;Riddle me this....&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../manager-tips/tech-lead-manager.html&quot;&gt;&amp;quot;The Tech-Lead Manager&amp;quot;&lt;/a&gt;: &amp;quot;Let&apos;s just have a developer be a manager and a developer at the same time&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The full list is &lt;a href=&quot;../../manager-tips/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>A Java Language Cumulative Feature Rollup</title>
      <link>http://blogs.newardassociates.com/blog/2024/java-cumulative-feature-rollup.html</link>
      <pubDate>Wed, 28 Aug 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/java-cumulative-feature-rollup.html</guid>
      	<description>
	&lt;p&gt;I found myself asking myself the question, &amp;quot;What&apos;s every new feature Java has introduced since the last time I really cared about new Java language features?&amp;quot;, and didn&apos;t find an easy answer via Google. So, I decided to create that list.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Note that most JDK releases are a combination of new language features, new library features (and by libraries I mean the modules that ship with the JDK), and sometimes new virtual machine features to support either of those two. In the list below, I do my best to categorize which features apply where. I&apos;m also going to elide out anything that seems relatively trivial or is a Preview feature in the release.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;213: &lt;a href=&quot;https://openjdk.org/jeps/213&quot;&gt;Milling Project Coin&lt;/a&gt; (9)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allow effectively-final vaiables to be used as resources in try-with-resources&lt;/li&gt;
&lt;li&gt;Allow diamond with anonymous classes if inferrable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;222: &lt;a href=&quot;https://openjdk.org/jeps/222&quot;&gt;jshell&lt;/a&gt; (9) (VM): &amp;quot;Provide an interactive tool to evaluate declarations, statements, and expressions of the Java programming language, together with an API so that other applications can leverage this functionality.&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;238: &lt;a href=&quot;https://openjdk.org/jeps/238&quot;&gt;Multi-Release JAR files&lt;/a&gt; (9) (VM): &amp;quot;Extend the JAR file format to allow multiple, Java-release-specific versions of class files to coexist in a single archive.&amp;quot; In other words, an MRJAR can sport different versions of a class for different releases of Java.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;259: &lt;a href=&quot;https://openjdk.org/jeps/259&quot;&gt;Stack-Walking API&lt;/a&gt; (9) (Library/VM): &amp;quot;Define an efficient standard API for stack walking that allows easy filtering of, and lazy access to, the information in stack traces.&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;261: &lt;a href=&quot;https://openjdk.org/jeps/261&quot;&gt;Module system&lt;/a&gt; (9): Hello darkness my old friend....&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;266: &lt;a href=&quot;https://openjdk.org/jeps/266&quot;&gt;More Concurrency Updates&lt;/a&gt; (9) (Library): Some enhancements around publish-subscribe (&lt;code&gt;Flow&lt;/code&gt; and friends), the &lt;code&gt;CompletableFuture&lt;/code&gt; type and some other enhancements. Looks to be entirely library-centric.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;286: &lt;a href=&quot;https://openjdk.org/jeps/286&quot;&gt;Local-Variable Type Inference&lt;/a&gt; (10): Use &lt;code&gt;var&lt;/code&gt; as a type placeholder in local variable declarations. (What they should&apos;ve done back in Java7 when they went the other direction.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;181: &lt;a href=&quot;https://openjdk.org/jeps/181&quot;&gt;Nest-Based Access Control&lt;/a&gt; (11): &amp;quot;Introduce nests, an access-control context that aligns with the existing notion of nested types in the Java programming language. Nests allow classes that are logically part of the same code entity, but which are compiled to distinct class files, to access each other&apos;s private members without the need for compilers to insert accessibility-broadening bridge methods.&amp;quot; I&apos;m guessing this now invalidates/supercedes the need for the synthesized methods I always used to use as an example for why it was useful to look at Java bytecode. &lt;em&gt;sigh&lt;/em&gt;.... I mean, it&apos;s best to close the hole, but now I have to find a new demo.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;361: &lt;a href=&quot;https://openjdk.java.net/jeps/361&quot;&gt;Switch Expressions&lt;/a&gt; (14): &amp;quot;Extend switch so it can be used as either a statement or an expression, and so that both forms can use either traditional &lt;code&gt;case ... :&lt;/code&gt; labels (with fall through) or new &lt;code&gt;case ... -&amp;gt;&lt;/code&gt; labels (with no fall through), with a further new statement for yielding a value from a switch expression.&amp;quot; Functional programming infiltrates the language once again.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;371: &lt;a href=&quot;https://openjdk.org/jeps/371&quot;&gt;Hidden Classes&lt;/a&gt; (15): &amp;quot;Introduce hidden classes, which are classes that cannot be used directly by the bytecode of other classes. Hidden classes are intended for use by frameworks that generate classes at run time and use them indirectly, via reflection. A hidden class may be defined as a member of an access control nest, and may be unloaded independently of other classes.&amp;quot; Now that&apos;s interesting, never heard of that before....&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;378: &lt;a href=&quot;https://openjdk.java.net/jeps/378&quot;&gt;Text Blocks&lt;/a&gt; (15): &amp;quot;A text block is a multi-line string literal that avoids the need for most escape sequences, automatically formats the string in a predictable way, and gives the developer control over the format when desired.&amp;quot; Looks like it uses the triple-quote &amp;quot;heredoc&amp;quot; syntax popular in other languages.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;394: &lt;a href=&quot;https://openjdk.java.net/jeps/394&quot;&gt;Pattern Matching for instanceof&lt;/a&gt; (16):&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;395: &lt;a href=&quot;https://openjdk.java.net/jeps/395&quot;&gt;Records&lt;/a&gt; (16):&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;306: &lt;a href=&quot;https://openjdk.java.net/jeps/306&quot;&gt;Restore Always-Strict Floating-Point Semantics&lt;/a&gt; (17):&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;409: &lt;a href=&quot;https://openjdk.java.net/jeps/409&quot;&gt;Sealed Classes&lt;/a&gt; (17):&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;431: &lt;a href=&quot;https://openjdk.java.net/jeps/431&quot;&gt;Sequenced Collections&lt;/a&gt; (21) (Library):&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;440: &lt;a href=&quot;https://openjdk.java.net/jeps/440&quot;&gt;Record Patterns&lt;/a&gt; (21):&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;441: &lt;a href=&quot;https://openjdk.java.net/jeps/441&quot;&gt;Pattern Matching for switch&lt;/a&gt; (21):&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;444: &lt;a href=&quot;https://openjdk.java.net/jeps/444&quot;&gt;Virtual Threads&lt;/a&gt; (21) (Library): Fibers come to Java. Finally.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;The full list, as given by the OpenJDK pages, are below.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;LTS&lt;/em&gt;-marked releases are the Oracle Long-Term Support releases.&lt;/p&gt;
&lt;h3&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk9/&quot;&gt;JDK 9&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;102: Process API Updates&lt;/li&gt;
&lt;li&gt;110: HTTP 2 Client&lt;/li&gt;
&lt;li&gt;143: Improve Contended Locking&lt;/li&gt;
&lt;li&gt;158: Unified JVM Logging&lt;/li&gt;
&lt;li&gt;165: Compiler Control&lt;/li&gt;
&lt;li&gt;193: Variable Handles&lt;/li&gt;
&lt;li&gt;197: Segmented Code Cache&lt;/li&gt;
&lt;li&gt;199: Smart Java Compilation, Phase Two&lt;/li&gt;
&lt;li&gt;200: The Modular JDK&lt;/li&gt;
&lt;li&gt;201: Modular Source Code&lt;/li&gt;
&lt;li&gt;211: Elide Deprecation Warnings on Import Statements&lt;/li&gt;
&lt;li&gt;212: Resolve Lint and Doclint Warnings&lt;/li&gt;
&lt;li&gt;213: Milling Project Coin&lt;/li&gt;
&lt;li&gt;214: Remove GC Combinations Deprecated in JDK 8&lt;/li&gt;
&lt;li&gt;215: Tiered Attribution for javac&lt;/li&gt;
&lt;li&gt;216: Process Import Statements Correctly&lt;/li&gt;
&lt;li&gt;217: Annotations Pipeline 2.0&lt;/li&gt;
&lt;li&gt;219: Datagram Transport Layer Security (DTLS)&lt;/li&gt;
&lt;li&gt;220: Modular Run-Time Images&lt;/li&gt;
&lt;li&gt;221: Simplified Doclet API&lt;/li&gt;
&lt;li&gt;222: jshell: The Java Shell (Read-Eval-Print Loop)&lt;/li&gt;
&lt;li&gt;223: New Version-String Scheme&lt;/li&gt;
&lt;li&gt;224: HTML5 Javadoc&lt;/li&gt;
&lt;li&gt;225: Javadoc Search&lt;/li&gt;
&lt;li&gt;226: UTF-8 Property Files&lt;/li&gt;
&lt;li&gt;227: Unicode 7.0&lt;/li&gt;
&lt;li&gt;228: Add More Diagnostic Commands&lt;/li&gt;
&lt;li&gt;229: Create PKCS12 Keystores by Default&lt;/li&gt;
&lt;li&gt;231: Remove Launch-Time JRE Version Selection&lt;/li&gt;
&lt;li&gt;232: Improve Secure Application Performance&lt;/li&gt;
&lt;li&gt;233: Generate Run-Time Compiler Tests Automatically&lt;/li&gt;
&lt;li&gt;235: Test Class-File Attributes Generated by javac&lt;/li&gt;
&lt;li&gt;236: Parser API for Nashorn&lt;/li&gt;
&lt;li&gt;237: Linux/AArch64 Port&lt;/li&gt;
&lt;li&gt;238: Multi-Release JAR Files&lt;/li&gt;
&lt;li&gt;240: Remove the JVM TI hprof Agent&lt;/li&gt;
&lt;li&gt;241: Remove the jhat Tool&lt;/li&gt;
&lt;li&gt;243: Java-Level JVM Compiler Interface&lt;/li&gt;
&lt;li&gt;244: TLS Application-Layer Protocol Negotiation Extension&lt;/li&gt;
&lt;li&gt;245: Validate JVM Command-Line Flag Arguments&lt;/li&gt;
&lt;li&gt;246: Leverage CPU Instructions for GHASH and RSA&lt;/li&gt;
&lt;li&gt;247: Compile for Older Platform Versions&lt;/li&gt;
&lt;li&gt;248: Make G1 the Default Garbage Collector&lt;/li&gt;
&lt;li&gt;249: OCSP Stapling for TLS&lt;/li&gt;
&lt;li&gt;250: Store Interned Strings in CDS Archives&lt;/li&gt;
&lt;li&gt;251: Multi-Resolution Images&lt;/li&gt;
&lt;li&gt;252: Use CLDR Locale Data by Default&lt;/li&gt;
&lt;li&gt;253: Prepare JavaFX UI Controls &amp;amp; CSS APIs for Modularization&lt;/li&gt;
&lt;li&gt;254: Compact Strings&lt;/li&gt;
&lt;li&gt;255: Merge Selected Xerces 2.11.0 Updates into JAXP&lt;/li&gt;
&lt;li&gt;256: BeanInfo Annotations&lt;/li&gt;
&lt;li&gt;257: Update JavaFX/Media to Newer Version of GStreamer&lt;/li&gt;
&lt;li&gt;258: HarfBuzz Font-Layout Engine&lt;/li&gt;
&lt;li&gt;259: Stack-Walking API&lt;/li&gt;
&lt;li&gt;260: Encapsulate Most Internal APIs&lt;/li&gt;
&lt;li&gt;261: Module System&lt;/li&gt;
&lt;li&gt;262: TIFF Image I/O&lt;/li&gt;
&lt;li&gt;263: HiDPI Graphics on Windows and Linux&lt;/li&gt;
&lt;li&gt;264: Platform Logging API and Service&lt;/li&gt;
&lt;li&gt;265: Marlin Graphics Renderer&lt;/li&gt;
&lt;li&gt;266: More Concurrency Updates&lt;/li&gt;
&lt;li&gt;267: Unicode 8.0&lt;/li&gt;
&lt;li&gt;268: XML Catalogs&lt;/li&gt;
&lt;li&gt;269: Convenience Factory Methods for Collections&lt;/li&gt;
&lt;li&gt;270: Reserved Stack Areas for Critical Sections&lt;/li&gt;
&lt;li&gt;271: Unified GC Logging&lt;/li&gt;
&lt;li&gt;272: Platform-Specific Desktop Features&lt;/li&gt;
&lt;li&gt;273: DRBG-Based SecureRandom Implementations&lt;/li&gt;
&lt;li&gt;274: Enhanced Method Handles&lt;/li&gt;
&lt;li&gt;275: Modular Java Application Packaging&lt;/li&gt;
&lt;li&gt;276: Dynamic Linking of Language-Defined Object Models&lt;/li&gt;
&lt;li&gt;277: Enhanced Deprecation&lt;/li&gt;
&lt;li&gt;278: Additional Tests for Humongous Objects in G1&lt;/li&gt;
&lt;li&gt;279: Improve Test-Failure Troubleshooting&lt;/li&gt;
&lt;li&gt;280: Indify String Concatenation&lt;/li&gt;
&lt;li&gt;281: HotSpot C++ Unit-Test Framework&lt;/li&gt;
&lt;li&gt;282: jlink: The Java Linker&lt;/li&gt;
&lt;li&gt;283: Enable GTK 3 on Linux&lt;/li&gt;
&lt;li&gt;284: New HotSpot Build System&lt;/li&gt;
&lt;li&gt;285: Spin-Wait Hints&lt;/li&gt;
&lt;li&gt;287: SHA-3 Hash Algorithms&lt;/li&gt;
&lt;li&gt;288: Disable SHA-1 Certificates&lt;/li&gt;
&lt;li&gt;289: Deprecate the Applet API&lt;/li&gt;
&lt;li&gt;290: Filter Incoming Serialization Data&lt;/li&gt;
&lt;li&gt;291: Deprecate the Concurrent Mark Sweep (CMS) Garbage Collector&lt;/li&gt;
&lt;li&gt;292: Implement Selected ECMAScript 6 Features in Nashorn&lt;/li&gt;
&lt;li&gt;294: Linux/s390x Port&lt;/li&gt;
&lt;li&gt;295: Ahead-of-Time Compilation&lt;/li&gt;
&lt;li&gt;297: Unified arm32/arm64 Port&lt;/li&gt;
&lt;li&gt;298: Remove Demos and Samples&lt;/li&gt;
&lt;li&gt;299: Reorganize Documentation&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk/10/&quot;&gt;JDK 10&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;286: Local-Variable Type Inference&lt;/li&gt;
&lt;li&gt;296: Consolidate the JDK Forest into a Single Repository&lt;/li&gt;
&lt;li&gt;304: Garbage-Collector Interface&lt;/li&gt;
&lt;li&gt;307: Parallel Full GC for G1&lt;/li&gt;
&lt;li&gt;310: Application Class-Data Sharing&lt;/li&gt;
&lt;li&gt;312: Thread-Local Handshakes&lt;/li&gt;
&lt;li&gt;313: Remove the Native-Header Generation Tool (javah)&lt;/li&gt;
&lt;li&gt;314: Additional Unicode Language-Tag Extensions&lt;/li&gt;
&lt;li&gt;316: Heap Allocation on Alternative Memory Devices&lt;/li&gt;
&lt;li&gt;317: Experimental Java-Based JIT Compiler&lt;/li&gt;
&lt;li&gt;319: Root Certificates&lt;/li&gt;
&lt;li&gt;322: Time-Based Release Versioning&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk/11/&quot;&gt;JDK 11&lt;/a&gt; &lt;em&gt;LTS&lt;/em&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;181: Nest-Based Access Control&lt;/li&gt;
&lt;li&gt;309: Dynamic Class-File Constants&lt;/li&gt;
&lt;li&gt;315: Improve Aarch64 Intrinsics&lt;/li&gt;
&lt;li&gt;318: Epsilon: A No-Op Garbage Collector&lt;/li&gt;
&lt;li&gt;320: Remove the Java EE and CORBA Modules&lt;/li&gt;
&lt;li&gt;321: HTTP Client (Standard)&lt;/li&gt;
&lt;li&gt;323: Local-Variable Syntax for Lambda Parameters&lt;/li&gt;
&lt;li&gt;324: Key Agreement with Curve25519 and Curve448&lt;/li&gt;
&lt;li&gt;327: Unicode 10&lt;/li&gt;
&lt;li&gt;328: Flight Recorder&lt;/li&gt;
&lt;li&gt;329: ChaCha20 and Poly1305 Cryptographic Algorithms&lt;/li&gt;
&lt;li&gt;330: Launch Single-File Source-Code Programs&lt;/li&gt;
&lt;li&gt;331: Low-Overhead Heap Profiling&lt;/li&gt;
&lt;li&gt;332: Transport Layer Security (TLS) 1.3&lt;/li&gt;
&lt;li&gt;333: ZGC: A Scalable Low-Latency Garbage Collector (Experimental)&lt;/li&gt;
&lt;li&gt;335: Deprecate the Nashorn JavaScript Engine&lt;/li&gt;
&lt;li&gt;336: Deprecate the Pack200 Tools and API&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk/12/&quot;&gt;JDK 12&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;189: Shenandoah: A Low-Pause-Time Garbage Collector (Experimental)&lt;/li&gt;
&lt;li&gt;230: Microbenchmark Suite&lt;/li&gt;
&lt;li&gt;325: Switch Expressions (Preview)&lt;/li&gt;
&lt;li&gt;334: JVM Constants API&lt;/li&gt;
&lt;li&gt;340: One AArch64 Port, Not Two&lt;/li&gt;
&lt;li&gt;341: Default CDS Archives&lt;/li&gt;
&lt;li&gt;344: Abortable Mixed Collections for G1&lt;/li&gt;
&lt;li&gt;346: Promptly Return Unused Committed Memory from G1&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk/13/&quot;&gt;JDK 13&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;350: Dynamic CDS Archives&lt;/li&gt;
&lt;li&gt;351: ZGC: Uncommit Unused Memory&lt;/li&gt;
&lt;li&gt;353: Reimplement the Legacy Socket API&lt;/li&gt;
&lt;li&gt;354: Switch Expressions (Preview)&lt;/li&gt;
&lt;li&gt;355: Text Blocks (Preview)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk/14/&quot;&gt;JDK 14&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;305: Pattern Matching for instanceof (Preview)&lt;/li&gt;
&lt;li&gt;343: Packaging Tool (Incubator)&lt;/li&gt;
&lt;li&gt;345: NUMA-Aware Memory Allocation for G1&lt;/li&gt;
&lt;li&gt;349: JFR Event Streaming&lt;/li&gt;
&lt;li&gt;352: Non-Volatile Mapped Byte Buffers&lt;/li&gt;
&lt;li&gt;358: Helpful NullPointerExceptions&lt;/li&gt;
&lt;li&gt;359: Records (Preview)&lt;/li&gt;
&lt;li&gt;361: Switch Expressions (Standard)&lt;/li&gt;
&lt;li&gt;362: Deprecate the Solaris and SPARC Ports&lt;/li&gt;
&lt;li&gt;363: Remove the Concurrent Mark Sweep (CMS) Garbage Collector&lt;/li&gt;
&lt;li&gt;364: ZGC on macOS&lt;/li&gt;
&lt;li&gt;365: ZGC on Windows&lt;/li&gt;
&lt;li&gt;366: Deprecate the ParallelScavenge + SerialOld GC Combination&lt;/li&gt;
&lt;li&gt;367: Remove the Pack200 Tools and API&lt;/li&gt;
&lt;li&gt;368: Text Blocks (Second Preview)&lt;/li&gt;
&lt;li&gt;370: Foreign-Memory Access API (Incubator)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk/15/&quot;&gt;JDK 15&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;339: Edwards-Curve Digital Signature Algorithm (EdDSA)&lt;/li&gt;
&lt;li&gt;360: Sealed Classes (Preview)&lt;/li&gt;
&lt;li&gt;371: Hidden Classes&lt;/li&gt;
&lt;li&gt;372: Remove the Nashorn JavaScript Engine&lt;/li&gt;
&lt;li&gt;373: Reimplement the Legacy DatagramSocket API&lt;/li&gt;
&lt;li&gt;374: Disable and Deprecate Biased Locking&lt;/li&gt;
&lt;li&gt;375: Pattern Matching for instanceof (Second Preview)&lt;/li&gt;
&lt;li&gt;377: ZGC: A Scalable Low-Latency Garbage Collector&lt;/li&gt;
&lt;li&gt;378: Text Blocks&lt;/li&gt;
&lt;li&gt;379: Shenandoah: A Low-Pause-Time Garbage Collector&lt;/li&gt;
&lt;li&gt;381: Remove the Solaris and SPARC Ports&lt;/li&gt;
&lt;li&gt;383: Foreign-Memory Access API (Second Incubator)&lt;/li&gt;
&lt;li&gt;384: Records (Second Preview)&lt;/li&gt;
&lt;li&gt;385: Deprecate RMI Activation for Removal&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk/16/&quot;&gt;JDK 16&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;338: Vector API (Incubator)&lt;/li&gt;
&lt;li&gt;347: Enable C++14 Language Features&lt;/li&gt;
&lt;li&gt;357: Migrate from Mercurial to Git&lt;/li&gt;
&lt;li&gt;369: Migrate to GitHub&lt;/li&gt;
&lt;li&gt;376: ZGC: Concurrent Thread-Stack Processing&lt;/li&gt;
&lt;li&gt;380: Unix-Domain Socket Channels&lt;/li&gt;
&lt;li&gt;386: Alpine Linux Port&lt;/li&gt;
&lt;li&gt;387: Elastic Metaspace&lt;/li&gt;
&lt;li&gt;388: Windows/AArch64 Port&lt;/li&gt;
&lt;li&gt;389: Foreign Linker API (Incubator)&lt;/li&gt;
&lt;li&gt;390: Warnings for Value-Based Classes&lt;/li&gt;
&lt;li&gt;392: Packaging Tool&lt;/li&gt;
&lt;li&gt;393: Foreign-Memory Access API (Third Incubator)&lt;/li&gt;
&lt;li&gt;394: Pattern Matching for instanceof&lt;/li&gt;
&lt;li&gt;395: Records&lt;/li&gt;
&lt;li&gt;396: Strongly Encapsulate JDK Internals by Default&lt;/li&gt;
&lt;li&gt;397: Sealed Classes (Second Preview)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk/17/&quot;&gt;JDK 17&lt;/a&gt; &lt;em&gt;LTS&lt;/em&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;306: Restore Always-Strict Floating-Point Semantics&lt;/li&gt;
&lt;li&gt;356: Enhanced Pseudo-Random Number Generators&lt;/li&gt;
&lt;li&gt;382: New macOS Rendering Pipeline&lt;/li&gt;
&lt;li&gt;391: macOS/AArch64 Port&lt;/li&gt;
&lt;li&gt;398: Deprecate the Applet API for Removal&lt;/li&gt;
&lt;li&gt;403: Strongly Encapsulate JDK Internals&lt;/li&gt;
&lt;li&gt;406: Pattern Matching for switch (Preview)&lt;/li&gt;
&lt;li&gt;407: Remove RMI Activation&lt;/li&gt;
&lt;li&gt;409: Sealed Classes&lt;/li&gt;
&lt;li&gt;410: Remove the Experimental AOT and JIT Compiler&lt;/li&gt;
&lt;li&gt;411: Deprecate the Security Manager for Removal&lt;/li&gt;
&lt;li&gt;412: Foreign Function &amp;amp; Memory API (Incubator)&lt;/li&gt;
&lt;li&gt;414: Vector API (Second Incubator)&lt;/li&gt;
&lt;li&gt;415: Context-Specific Deserialization Filters&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk/18/&quot;&gt;JDK 18&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;400: UTF-8 by Default&lt;/li&gt;
&lt;li&gt;408: Simple Web Server&lt;/li&gt;
&lt;li&gt;413: Code Snippets in Java API Documentation&lt;/li&gt;
&lt;li&gt;416: Reimplement Core Reflection with Method Handles&lt;/li&gt;
&lt;li&gt;417: Vector API (Third Incubator)&lt;/li&gt;
&lt;li&gt;418: Internet-Address Resolution SPI&lt;/li&gt;
&lt;li&gt;419: Foreign Function &amp;amp; Memory API (Second Incubator)&lt;/li&gt;
&lt;li&gt;420: Pattern Matching for switch (Second Preview)&lt;/li&gt;
&lt;li&gt;421: Deprecate Finalization for Removal&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk/19/&quot;&gt;JDK 19&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;405: Record Patterns (Preview)&lt;/li&gt;
&lt;li&gt;422: Linux/RISC-V Port&lt;/li&gt;
&lt;li&gt;424: Foreign Function &amp;amp; Memory API (Preview)&lt;/li&gt;
&lt;li&gt;425: Virtual Threads (Preview)&lt;/li&gt;
&lt;li&gt;426: Vector API (Fourth Incubator)&lt;/li&gt;
&lt;li&gt;427: Pattern Matching for switch (Third Preview)&lt;/li&gt;
&lt;li&gt;428: Structured Concurrency (Incubator)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk/20/&quot;&gt;JDK 20&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;429: Scoped Values (Incubator)&lt;/li&gt;
&lt;li&gt;432: Record Patterns (Second Preview)&lt;/li&gt;
&lt;li&gt;433: Pattern Matching for switch (Fourth Preview)&lt;/li&gt;
&lt;li&gt;434: Foreign Function &amp;amp; Memory API (Second Preview)&lt;/li&gt;
&lt;li&gt;436: Virtual Threads (Second Preview)&lt;/li&gt;
&lt;li&gt;437: Structured Concurrency (Second Incubator)&lt;/li&gt;
&lt;li&gt;438: Vector API (Fifth Incubator)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk/21/&quot;&gt;JDK 21&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;430: String Templates (Preview)&lt;/li&gt;
&lt;li&gt;431: Sequenced Collections&lt;/li&gt;
&lt;li&gt;439: Generational ZGC&lt;/li&gt;
&lt;li&gt;440: Record Patterns&lt;/li&gt;
&lt;li&gt;441: Pattern Matching for switch&lt;/li&gt;
&lt;li&gt;442: Foreign Function &amp;amp; Memory API (Third Preview)&lt;/li&gt;
&lt;li&gt;443: Unnamed Patterns and Variables (Preview)&lt;/li&gt;
&lt;li&gt;444: Virtual Threads&lt;/li&gt;
&lt;li&gt;445: Unnamed Classes and Instance Main Methods (Preview)&lt;/li&gt;
&lt;li&gt;446: Scoped Values (Preview)&lt;/li&gt;
&lt;li&gt;448: Vector API (Sixth Incubator)&lt;/li&gt;
&lt;li&gt;449: Deprecate the Windows 32-bit x86 Port for Removal&lt;/li&gt;
&lt;li&gt;451: Prepare to Disallow the Dynamic Loading of Agents&lt;/li&gt;
&lt;li&gt;452: Key Encapsulation Mechanism API&lt;/li&gt;
&lt;li&gt;453: Structured Concurrency (Preview)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk/22/&quot;&gt;JDK 22&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;423: Region Pinning for G1&lt;/li&gt;
&lt;li&gt;447: Statements before super(...) (Preview)&lt;/li&gt;
&lt;li&gt;454: Foreign Function &amp;amp; Memory API&lt;/li&gt;
&lt;li&gt;456: Unnamed Variables &amp;amp; Patterns&lt;/li&gt;
&lt;li&gt;457: Class-File API (Preview)&lt;/li&gt;
&lt;li&gt;458: Launch Multi-File Source-Code Programs&lt;/li&gt;
&lt;li&gt;459: String Templates (Second Preview)&lt;/li&gt;
&lt;li&gt;460: Vector API (Seventh Incubator)&lt;/li&gt;
&lt;li&gt;461: Stream Gatherers (Preview)&lt;/li&gt;
&lt;li&gt;462: Structured Concurrency (Second Preview)&lt;/li&gt;
&lt;li&gt;463: Implicitly Declared Classes and Instance Main Methods (Second Preview)&lt;/li&gt;
&lt;li&gt;464: Scoped Values (Second Preview)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk/23/&quot;&gt;JDK 23&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;455: Primitive Types in Patterns, instanceof, and switch (Preview)&lt;/li&gt;
&lt;li&gt;466: Class-File API (Second Preview)&lt;/li&gt;
&lt;li&gt;467: Markdown Documentation Comments&lt;/li&gt;
&lt;li&gt;469: Vector API (Eighth Incubator)&lt;/li&gt;
&lt;li&gt;473: Stream Gatherers (Second Preview)&lt;/li&gt;
&lt;li&gt;471: Deprecate the Memory-Access Methods in sun.misc.Unsafe for Removal&lt;/li&gt;
&lt;li&gt;474: ZGC: Generational Mode by Default&lt;/li&gt;
&lt;li&gt;476: Module Import Declarations (Preview)&lt;/li&gt;
&lt;li&gt;477: Implicitly Declared Classes and Instance Main Methods (Third Preview)&lt;/li&gt;
&lt;li&gt;480: Structured Concurrency (Third Preview)&lt;/li&gt;
&lt;li&gt;481: Scoped Values (Third Preview)&lt;/li&gt;
&lt;li&gt;482: Flexible Constructor Bodies (Second Preview)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk/24/&quot;&gt;JDK 24&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;404: Generational Shenandoah (Experimental)&lt;/li&gt;
&lt;li&gt;450: Compact Object Headers (Experimental)&lt;/li&gt;
&lt;li&gt;472: Prepare to Restrict the Use of JNI&lt;/li&gt;
&lt;li&gt;475: Late Barrier Expansion for G1&lt;/li&gt;
&lt;li&gt;478: Key Derivation Function API (Preview)&lt;/li&gt;
&lt;li&gt;479: Remove the Windows 32-bit x86 Port&lt;/li&gt;
&lt;li&gt;483: Ahead-of-Time Class Loading &amp;amp; Linking&lt;/li&gt;
&lt;li&gt;484: Class-File API&lt;/li&gt;
&lt;li&gt;485: Stream Gatherers&lt;/li&gt;
&lt;li&gt;486: Permanently Disable the Security Manager&lt;/li&gt;
&lt;li&gt;487: Scoped Values (Fourth Preview)&lt;/li&gt;
&lt;li&gt;488: Primitive Types in Patterns, instanceof, and switch (Second Preview)&lt;/li&gt;
&lt;li&gt;489: Vector API (Ninth Incubator)&lt;/li&gt;
&lt;li&gt;490: ZGC: Remove the Non-Generational Mode&lt;/li&gt;
&lt;li&gt;491: Synchronize Virtual Threads without Pinning&lt;/li&gt;
&lt;li&gt;492: Flexible Constructor Bodies (Third Preview)&lt;/li&gt;
&lt;li&gt;493: Linking Run-Time Images without JMODs&lt;/li&gt;
&lt;li&gt;494: Module Import Declarations (Second Preview)&lt;/li&gt;
&lt;li&gt;495: Simple Source Files and Instance Main Methods (Fourth Preview)&lt;/li&gt;
&lt;li&gt;496: Quantum-Resistant Module-Lattice-Based Key Encapsulation Mechanism&lt;/li&gt;
&lt;li&gt;497: Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm&lt;/li&gt;
&lt;li&gt;498: Warn upon Use of Memory-Access Methods in sun.misc.Unsafe&lt;/li&gt;
&lt;li&gt;499: Structured Concurrency (Fourth Preview)&lt;/li&gt;
&lt;li&gt;501: Deprecate the 32-bit x86 Port for Removal&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href=&quot;https://openjdk.org/projects/jdk/25/&quot;&gt;JDK 25&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;470: PEM Encodings of Cryptographic Objects (Preview)&lt;/li&gt;
&lt;li&gt;502: Stable Values (Preview)&lt;/li&gt;
&lt;li&gt;503: Remove the 32-bit x86 Port&lt;/li&gt;
&lt;li&gt;505: Structured Concurrency (Fifth Preview)&lt;/li&gt;
&lt;li&gt;506: Scoped Values&lt;/li&gt;
&lt;li&gt;507: Primitive Types in Patterns, instanceof, and switch (Third Preview)&lt;/li&gt;
&lt;li&gt;508: Vector API (Tenth Incubator)&lt;/li&gt;
&lt;li&gt;509: JFR CPU-Time Profiling (Experimental)&lt;/li&gt;
&lt;li&gt;510: Key Derivation Function API&lt;/li&gt;
&lt;li&gt;511: Module Import Declarations&lt;/li&gt;
&lt;li&gt;512: Compact Source Files and Instance Main Methods&lt;/li&gt;
&lt;li&gt;513: Flexible Constructor Bodies&lt;/li&gt;
&lt;li&gt;514: Ahead-of-Time Command-Line Ergonomics&lt;/li&gt;
&lt;li&gt;515: Ahead-of-Time Method Profiling&lt;/li&gt;
&lt;li&gt;518: JFR Cooperative Sampling&lt;/li&gt;
&lt;li&gt;519: Compact Object Headers&lt;/li&gt;
&lt;li&gt;520: JFR Method Timing &amp;amp; Tracing&lt;/li&gt;
&lt;li&gt;521: Generational Shenandoah&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;These are the &amp;quot;diffs&amp;quot; list given by the OpenJDK pages on each of the LTS release pages. In essence, these are rollups from one LTS release to the next.&lt;/p&gt;
&lt;h1&gt;JDK 11 -&amp;gt; 17&lt;/h1&gt;
&lt;h2&gt;Additions&lt;/h2&gt;
&lt;p&gt;403:  Strongly Encapsulate JDK Internals (17)&lt;br /&gt;
390:  Warnings for Value-Based Classes (16)&lt;/p&gt;
&lt;h3&gt;HotSpot JVM&lt;/h3&gt;
&lt;p&gt;386:  Alpine Linux Port (16)&lt;br /&gt;
391:  macOS/AArch64 Port (17)&lt;br /&gt;
340:  One AArch64 Port, Not Two (12)&lt;br /&gt;
388:  Windows/AArch64 Port (16)&lt;/p&gt;
&lt;h3&gt;Flight Recorder&lt;/h3&gt;
&lt;p&gt;349:  JFR Event Streaming (14)&lt;/p&gt;
&lt;h3&gt;Garbage Collectors&lt;/h3&gt;
&lt;p&gt;344:  Abortable Mixed Collections for G1 (12)&lt;br /&gt;
345:  NUMA-Aware Memory Allocation for G1 (14)&lt;br /&gt;
346:  Promptly Return Unused Committed Memory from G1 (12)&lt;br /&gt;
379:  Shenandoah: A Low-Pause-Time Garbage Collector (15)&lt;br /&gt;
377:  ZGC: A Scalable Low-Latency Garbage Collector (15)&lt;br /&gt;
376:  ZGC: Concurrent Thread-Stack Processing (16)&lt;/p&gt;
&lt;h3&gt;Run-Time System&lt;/h3&gt;
&lt;p&gt;341:  Default CDS Archives (12)&lt;br /&gt;
350:  Dynamic CDS Archives (13)&lt;br /&gt;
387:  Elastic Metaspace (16)&lt;br /&gt;
358:  Helpful NullPointerExceptions (14)&lt;/p&gt;
&lt;h3&gt;Language&lt;/h3&gt;
&lt;p&gt;394:  Pattern Matching for instanceof (16)&lt;br /&gt;
395:  Records (16)&lt;br /&gt;
306:  Restore Always-Strict Floating-Point Semantics (17)&lt;br /&gt;
409:  Sealed Classes (17)&lt;br /&gt;
361:  Switch Expressions (14)&lt;br /&gt;
378:  Text Blocks (15)&lt;/p&gt;
&lt;h3&gt;Libraries&lt;/h3&gt;
&lt;h4&gt;2D Graphics&lt;/h4&gt;
&lt;p&gt;382:  New macOS Rendering Pipeline (17)&lt;/p&gt;
&lt;h4&gt;Cryptography&lt;/h4&gt;
&lt;p&gt;339:  Edwards-Curve Digital Signature Algorithm (EdDSA) (15)&lt;/p&gt;
&lt;h4&gt;I/O&lt;/h4&gt;
&lt;p&gt;352:  Non-Volatile Mapped Byte Buffers (14)&lt;br /&gt;
380:  Unix-Domain Socket Channels (16)&lt;/p&gt;
&lt;h4&gt;Networking&lt;/h4&gt;
&lt;p&gt;373:  Reimplement the Legacy DatagramSocket API (15)&lt;br /&gt;
353:  Reimplement the Legacy Socket API (13)&lt;/p&gt;
&lt;h4&gt;Reflection &amp;amp; Method Handles&lt;/h4&gt;
&lt;p&gt;371:  Hidden Classes (15)&lt;br /&gt;
334:  JVM Constants API (12)&lt;/p&gt;
&lt;h4&gt;Serialization&lt;/h4&gt;
&lt;p&gt;415:  Context-Specific Deserialization Filters (17)&lt;/p&gt;
&lt;h4&gt;Utilities&lt;/h4&gt;
&lt;p&gt;356:  Enhanced Pseudo-Random Number Generators (17)&lt;/p&gt;
&lt;h3&gt;Tools&lt;/h3&gt;
&lt;p&gt;392:  Packaging Tool (16)&lt;/p&gt;
&lt;h2&gt;Preview &amp;amp; incubating&lt;/h2&gt;
&lt;h3&gt;Language&lt;/h3&gt;
&lt;p&gt;406:  Pattern Matching for switch (Preview) (17)&lt;/p&gt;
&lt;h3&gt;Libraries&lt;/h3&gt;
&lt;p&gt;412:  Foreign Function &amp;amp; Memory API (Incubator) (17)&lt;br /&gt;
414:  Vector API (Second Incubator) (17)&lt;/p&gt;
&lt;h2&gt;Deprecations&lt;/h2&gt;
&lt;h3&gt;HotSpot JVM&lt;/h3&gt;
&lt;p&gt;374:  Deprecate and Disable Biased Locking (15)&lt;br /&gt;
366:  Deprecate the ParallelScavenge + SerialOld GC Combination (14)&lt;/p&gt;
&lt;h3&gt;Libraries&lt;/h3&gt;
&lt;p&gt;398:  Deprecate the Applet API for Removal (17)&lt;br /&gt;
411:  Deprecate the Security Manager for Removal (17)&lt;/p&gt;
&lt;h2&gt;Removals&lt;/h2&gt;
&lt;h3&gt;HotSpot JVM&lt;/h3&gt;
&lt;p&gt;363:  Remove the Concurrent Mark Sweep (CMS) Garbage Collector (14)&lt;br /&gt;
410:  Remove the Experimental AOT and JIT Compiler (17)&lt;br /&gt;
381:  Remove the Solaris and SPARC Ports (15)&lt;/p&gt;
&lt;h3&gt;Libraries&lt;/h3&gt;
&lt;p&gt;407:  Remove RMI Activation (17)&lt;br /&gt;
372:  Remove the Nashorn JavaScript Engine (15)&lt;/p&gt;
&lt;h3&gt;Tools&lt;/h3&gt;
&lt;p&gt;367:  Remove the Pack200 Tools and API (14)&lt;/p&gt;
&lt;h1&gt;JDK 17 -&amp;gt; 21&lt;/h1&gt;
&lt;h2&gt;Additions&lt;/h2&gt;
&lt;h3&gt;HotSpot JVM&lt;/h3&gt;
&lt;p&gt;422:  Linux/RISC-V Port (19)&lt;/p&gt;
&lt;h4&gt;Garbage Collectors&lt;/h4&gt;
&lt;p&gt;439:  Generational ZGC (21)&lt;/p&gt;
&lt;h4&gt;Serviceability&lt;/h4&gt;
&lt;p&gt;451:  Prepare to Disallow the Dynamic Loading of Agents (21)&lt;/p&gt;
&lt;h3&gt;Language&lt;/h3&gt;
&lt;p&gt;441:  Pattern Matching for switch (21)&lt;br /&gt;
440:  Record Patterns (21)&lt;/p&gt;
&lt;h3&gt;Libraries&lt;/h3&gt;
&lt;p&gt;444:  Virtual Threads (21)&lt;/p&gt;
&lt;h4&gt;Collections&lt;/h4&gt;
&lt;p&gt;431:  Sequenced Collections (21)&lt;/p&gt;
&lt;h4&gt;Cryptography&lt;/h4&gt;
&lt;p&gt;452:  Key Encapsulation Mechanism API (21)&lt;/p&gt;
&lt;h4&gt;I/O&lt;/h4&gt;
&lt;p&gt;400:  UTF-8 by Default (18)&lt;/p&gt;
&lt;h4&gt;Networking&lt;/h4&gt;
&lt;p&gt;418:  Internet-Address Resolution SPI (18)&lt;br /&gt;
408:  Simple Web Server (18)&lt;/p&gt;
&lt;h4&gt;Reflection &amp;amp; Method Handles&lt;/h4&gt;
&lt;p&gt;416:  Reimplement Core Reflection with Method Handles (18)&lt;/p&gt;
&lt;h3&gt;Tools&lt;/h3&gt;
&lt;h4&gt;JavaDoc&lt;/h4&gt;
&lt;p&gt;413:  Code Snippets in Java API Documentation (18)&lt;/p&gt;
&lt;h2&gt;Preview &amp;amp; Incubating&lt;/h2&gt;
&lt;h3&gt;Language&lt;/h3&gt;
&lt;p&gt;430:  String Templates (Preview) (21)&lt;br /&gt;
445:  Unnamed Classes and Instance Main Methods (Preview) (21)&lt;br /&gt;
443:  Unnamed Patterns and Variables (Preview) (21)&lt;/p&gt;
&lt;h3&gt;Libraries&lt;/h3&gt;
&lt;p&gt;442:  Foreign Function &amp;amp; Memory API (Third Preview) (21)&lt;br /&gt;
446:  Scoped Values (Preview) (21)&lt;br /&gt;
453:  Structured Concurrency (Preview) (21)&lt;br /&gt;
448:  Vector API (Sixth Incubator) (21)&lt;/p&gt;
&lt;h2&gt;Deprecations&lt;/h2&gt;
&lt;h3&gt;HotSpot JVM&lt;/h3&gt;
&lt;p&gt;449:  Deprecate the Windows 32-bit x86 Port for Removal (21)&lt;/p&gt;
&lt;h3&gt;Libraries&lt;/h3&gt;
&lt;p&gt;421:  Deprecate Finalization for Removal (18)&lt;/p&gt;
&lt;h1&gt;JDK 21 -&amp;gt; 25&lt;/h1&gt;

	</description>
    </item>
    <item>
      <title>Book Review: The Nature of Code</title>
      <link>http://blogs.newardassociates.com/blog/2024/book-the-nature-of-code.html</link>
      <pubDate>Tue, 20 Aug 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/book-the-nature-of-code.html</guid>
      	<description>
	&lt;p&gt;No Starch Press sent me a copy of the book &amp;quot;The Nature of Code&amp;quot;, by Daniel Shiffman, and I have to say, it&apos;s a lovely piece of work, both figuratively and literally.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2&gt;Physical&lt;/h2&gt;
&lt;p&gt;Let&apos;s start with the physical (which is rare for a book review, I think): This book is gorgeous. It&apos;s clear that No Starch is trying to make this book more than just something that appears on your shelf, but instead takes center stage on your coffee table. A number of &amp;quot;design&amp;quot; books went after this motif, and The Nature of Code (TNoC) definitely feels at home with them. Paper is heavy, covers are solid, and the binding is strong. Definitely a book that can take some abuse as you cart it from desk to restaurant to bed to... well, wherever else you might read stuff while your body is preoccupied with other things.&lt;/p&gt;
&lt;p&gt;Secondly, Daniel Shiffman (whom I&apos;ve never met) clearly knows how to &lt;em&gt;teach&lt;/em&gt;. His bio reflects that (creator of The Coding Train channel on YouTube, and associate arts professor at NYU Tech School of the Arts being two of the big credentials there), but there&apos;s a fair number of people I know who have a teaching credit in their bio that still don&apos;t know how to teach. My mom put it best once: &amp;quot;Some people know how to teach, and some only know how to lecture.&amp;quot; Shiffman clearly falls in the latter category: he starts with some core functionality, then builds on that to the next section, then builds on top of that, and so on. The aim is to carefully bring the reader along on a journey, never too far away from where you started (at the start of the chapter) but far enough to realize that yes, you did learn something here.&lt;/p&gt;
&lt;p&gt;Next, let&apos;s address the elephant in the room: Shiffman makes the material available over a variety of media, including the &lt;a href=&quot;https://natureofcode.com&quot;&gt;Web&lt;/a&gt;. (In the front matter, he even addresses how his goal has always been to have one set of source materials get transformed--dare I say transpiled?--into a variety of different consumable media, like PDFs, HTML, or printed book. Sentiments quite close to my own heart!) Should you buy the book even though you could read it for free? My answer here is biased and twofold: One, it&apos;s always good to support authors in situations like this, so buy the book so Shiffman gets his tiny, tiny royalty. (Seriously, book royalties are &lt;em&gt;not&lt;/em&gt; why you write a book.) Two, while I like having books on my Kindle app on my iPad(s), because they travel soooo much easier than carting around physical books, there is still something visceral about turning the page that no e-reader has been able to duplicate yet. I suspect mine may be the last generation (Gen-Xer over ehre) that feels this way, but if you like books over online resources to learn something, then you already knew the answer.&lt;/p&gt;
&lt;h2&gt;Contents&lt;/h2&gt;
&lt;p&gt;In terms of the actual contents, TNoC is a hefty tome, weighing in at around 600 pages, and that&apos;s not an inflated number due to multi-page code listings (like you might find in certain self-published books). Twelve chapters (starting at chapter 0, as God intended!), covering:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Part I: Inanimate Objects&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Randomness: Using different flavors to drive an object&apos;s motion (like a soccer ball through the grass)&lt;/li&gt;
&lt;li&gt;Vectors: A foundational tool for pretty much everything else&lt;/li&gt;
&lt;li&gt;Forces: Vectors are forces that can act on objects&lt;/li&gt;
&lt;li&gt;Oscillation: Angles, trigonometry, and angular acceleration&lt;/li&gt;
&lt;li&gt;Particle Systems: Now make thousands and thousands of those objects (particles) and turn &apos;em loose&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Part II: It&apos;s Alive!&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Autonomous Agents&lt;/li&gt;
&lt;li&gt;Physics Libraries&lt;/li&gt;
&lt;li&gt;Cellular Automata&lt;/li&gt;
&lt;li&gt;Fractals&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Part III: Intelligence&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Evolutionary Computing&lt;/li&gt;
&lt;li&gt;Neural Networks&lt;/li&gt;
&lt;li&gt;Neuroevolution&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&apos;s pretty clear this isn&apos;t a tutorial on how to learn programming, but makes for an excellent follow-up to your traditional programming class, in that Shiffman&apos;s goal is to show how to model natural/physical systems in code.&lt;/p&gt;
&lt;p&gt;Speaking of programming, the examples make use of &lt;a href=&quot;https://p5js.org/&quot;&gt;p5.js&lt;/a&gt; a spirital cousin (if not successor) to &lt;a href=&quot;https://processing.org/&quot;&gt;Processing&lt;/a&gt;, the Java-based environment that allows &amp;quot;creatives&amp;quot; to express their ideas and designs without having to learn Java3D, JavaFX, or any other 3D graphics library + programming language.&lt;/p&gt;
&lt;h2&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;Overall, as you&apos;ve probably guessed, I like the book. This area--graphics and physical motion simulation and so on--is not one of those areas that I consider myself &amp;quot;skilled&amp;quot; in, so in many ways I think I&apos;m in a target audience for the book, and one thing that strikes me as a deep positive is that it never tries to &amp;quot;talk over&amp;quot; me. In too many 3D graphics books, there&apos;s a tendency to start spewing Greek symbols all over the page and teach the math behind the code, but doing so before ever showing code. Shiffman doesn&apos;t do this--he shows code, then if he wants to go into the math, he does so in simple prose. Granted, I&apos;m not much smarter about the math after reading the chapter, but if I wanted to learn the math, I&apos;d go pick up a math text. Half the time, I don&apos;t care how a thing works, I just want to know (and see!) that it does.&lt;/p&gt;
&lt;p&gt;If graphics and simulating natural systems appeals to you (and frankly I think anybody who&apos;s ever thought about diving into building a video game has thought about this at least once!), then I encourage you to &lt;a href=&quot;https://store.natureofcode.com/products/the-nature-of-code&quot;&gt;&amp;quot;grab a copy of a bound collection of processed cellulose fibers, imprinted with symbolic glyphs via pigment-based transfer particles direct from me!&amp;quot;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Disclaimer: No Starch Press sent me a review copy of the book; no other compensation was provided.&lt;/em&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The R-and-D Library Team</title>
      <link>http://blogs.newardassociates.com/blog/2024/library-team.html</link>
      <pubDate>Wed, 12 Jun 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/library-team.html</guid>
      	<description>
	&lt;p&gt;There are four different kinds of R&amp;amp;D teams, each with very different actions and goals, and each with very different outcomes. The success of the team often depends on aligning the activities of the team with the intended goals, and it&apos;s actually quite reasonable for a company to have two or more teams, each operating independently and towards different ends. In this post, I explore the Library Team.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;As a reminder, there are four kinds of R&amp;amp;D Teams:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;a href=&quot;./scout-team.html&quot;&gt;Scout team&lt;/a&gt;, exploring what tech others in the industry have built (e.g., Flutter, SwiftUI, etc)&lt;/li&gt;
&lt;li&gt;the &lt;a href=&quot;./spy-team.html&quot;&gt;Spy team&lt;/a&gt;, exploring what competitors have built&lt;/li&gt;
&lt;li&gt;the &lt;a href=&quot;./library-team.html&quot;&gt;Library team&lt;/a&gt;, building lowest-common-denominator libraries used (sometimes) within the company&lt;/li&gt;
&lt;li&gt;the &lt;a href=&quot;./research-team.html&quot;&gt;Practical Research team&lt;/a&gt;, building novel solutions to the company&apos;s (and others&apos;) problems&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;The Library Team&lt;/h3&gt;
&lt;p&gt;The Library team is the team given responsibility for managing reusable artifacts within the company--libraries, tools, frameworks, services (cloud or on-prem), whatever--because achieving actual reusability, it turns out, requires a degree of commitment of time and resources to maintaining and homogenizing those artifacts. Doing this work, at the same time a team is trying to manage a product release, ends up becoming a distraction to the product release cycle, particularly as the shared &amp;quot;thing&amp;quot; becomes more widely shared.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; In any given company consisting of more than one development team operating in parallel, there comes a point when each team creates their own independent solution to a particular sliver of the domain or infrastructure. Once the duplication becomes known, concerns about the duplication became a topic of discussion, and the teams spend some (sometimes tiny, sometimes significant) time talking over the issue, in what sometimes turns into outright negotiations.&lt;/p&gt;
&lt;p&gt;But as the company grows, more and more teams come into play, and before long, it&apos;s something of a free-for-all as teams try to figure out what&apos;s shared and what&apos;s sharable. In some organizations, being the team that&apos;s sharing the library becomes a point of pride--or worse, metrics--and thus creates incentive to convince everybody else to use our stuff, as well as disincentive to use anybody else&apos;s stuff.&lt;/p&gt;
&lt;p&gt;THe problem multiplies, however, when the teams that use another team&apos;s library start to discover bugs or a lack of particular features necessary to the adopting team&apos;s requirements. Pressure begins on the owning team to incorporate these new features--which the owning team really has no need for--and the inevitable conflict escalates to higher management to hash out. Quickly one or all parties realize that there is no real winner here: If the owning team is required to add the features, their own schedules and delivery are affected; if the adopting team(s) are told to add the feature themselves, the codebase now reaches a point where no one team has a real sense of how the code operates anymore; if the adopting team(s) are told that the library is &amp;quot;as-is&amp;quot; and no support from the owning team is available, the adopting team often uses that as a pretext to &amp;quot;go their own way&amp;quot; and &amp;quot;build it the right way&amp;quot;. In essence, everybody loses.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Successful Execution:&lt;/strong&gt; For successful reuse to occur, a library team must be formed with the explicit goal of being an &amp;quot;internal vendor&amp;quot; of software to other teams within the company. They own, operate, maintain, and innovate around the software library or libraries that are intended for use across the organization, and the relationship is formalized much as a formal relationship is built between a vendor and their customer: explicit expectations are written and signed, a contract (of sorts) around support requests and/or updates is created, and the library team begins to interact with the adopting teams around prioritization of fixes, tweaks, and updates.&lt;/p&gt;
&lt;p&gt;The Library Team is a flavor of R&amp;amp;D, although it may not seem like it at first, since they are more focused on providing goods and services (in the form of tools, frameworks/libraries, and support) than most people associate with an R&amp;amp;D team. However, if R&amp;amp;D is defined as an effort intended to create competitive advantages for the company&apos;s developers through technology, then this team certainly fits.&lt;/p&gt;
&lt;p&gt;In contrast to the perception that an R&amp;amp;D team is always about creating something bright and shiny and new, the emphasis for the Library team has to be on the ongoing support of the things created. Just as no language, framework, or tool would ever be adopted by a company without understanding (and leaning on) some kind of support structure and/or community around it, efforts to create internal reusable products have to have a surrounding suport structure. Later, as time passes and the usage of the internal product grows, the library team will take on some of the internal community support as well, engaging with internal developers the same way an external vendor&apos;s Developer Relations team would engage with developers.&lt;/p&gt;
&lt;p&gt;Thus, the Library team&apos;s execution falls into a variety of phases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Discovery.&lt;/strong&gt; The library team is searching for new opportunities for reuse, by meeting and interacting with all of the development teams around them. Each time a team goes through a security review, architectural review, or any other sort of review, the library team (or a representative of) should be present to understand the architecture, discuss what options for security the library team can provide, and/or what features or infrastructure the product or service team is using or adopting. Each time a team releases something, the library team (or a representative of) should be present to understand what went into the release. In general, the library team should be on a constant hunt for things that could or should be reused across the organization.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Research.&lt;/strong&gt; Part of this discovery process can come from looking at what sorts of things external vendors are offering, as well. If a mobile or UI control component pack offers some visual components that currently are missing (and requested), the library team can do the &amp;quot;buy vs build&amp;quot; feasibility analysis. If a new cloud service is available, the library team can examine it with the same eye.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Innovation.&lt;/strong&gt; The library team is not entirely dependent on &amp;quot;outsiders&amp;quot; to come up with things to do, however, as there&apos;s likely plenty of ideas or feature requests for the existing shared components, so work can continue on developing those components.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Maintenance.&lt;/strong&gt; Naturally, as bug reports come in, the library team will be responsible for triage and prioritization. The library team will also need to determine its release schedule, and coordinate with its downstream dependents to make sure they&apos;re not breaking anyone with their changes. (For this reason, any module under the ownership of the library team should follow a strict semantic versioning scheme, and use existing infrastructure like NuGet, npm, Maven repos, and/or the Swift Packaging system to make their modules available internally).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reporting.&lt;/strong&gt; Lastly, the library team should be gathering up statistics on the usage of each of the modules/components they manage, and actively look for &amp;quot;dead modules&amp;quot; that can be removed from their watch and deleted.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

	</description>
    </item>
    <item>
      <title>The R-and-D Scout Team</title>
      <link>http://blogs.newardassociates.com/blog/2024/scout-team.html</link>
      <pubDate>Wed, 12 Jun 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/scout-team.html</guid>
      	<description>
	&lt;p&gt;There are four different kinds of R&amp;amp;D teams, each with very different actions and goals, and each with very different outcomes. The success of the team often depends on aligning the activities of the team with the intended goals, and it&apos;s actually quite reasonable for a company to have two or more teams, each operating independently and towards different ends. In this post, I explore the Scout Team.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;As a reminder, there are four kinds of R&amp;amp;D Teams:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;a href=&quot;./scout-team.html&quot;&gt;Scout team&lt;/a&gt;, exploring what tech others in the industry have built (e.g., Flutter, SwiftUI, etc)&lt;/li&gt;
&lt;li&gt;the &lt;a href=&quot;./spy-team.html&quot;&gt;Spy team&lt;/a&gt;, exploring what competitors have built&lt;/li&gt;
&lt;li&gt;the &lt;a href=&quot;./library-team.html&quot;&gt;Library team&lt;/a&gt;, building lowest-common-denominator libraries used (sometimes) within the company&lt;/li&gt;
&lt;li&gt;the &lt;a href=&quot;./research-team.html&quot;&gt;Practical Research team&lt;/a&gt;, building novel solutions to the company&apos;s (and others&apos;) problems&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;The Scout Team&lt;/h3&gt;
&lt;p&gt;The Scout Team is what most corporate R&amp;amp;D teams go after: The hunt for new technology that will somehow provide the company with a competitive advantage over its competitors, despite the fact that the competitors are all themselves out there scouting the industry just like this team is. New programming languages, new databases, new architecture styles, new whatever-fill-in-the-blank, just so long as it is (a) new and (b) not yet mainstream, it&apos;s a candidate for the Scout Team&apos;s infinite desire to create prototypes that bear a remarkable resemblance to the demos that the new thing has on its website or in its documentation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; The Scout Team suffers from several intrinsic flaws:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;The Scout Team isn&apos;t always a great evaluator of technology.&lt;/em&gt; Honestly, it often comes down to the team lead&apos;s personal preferences and/or opinions. Do we scout Dart/Flutter, or React Native? Do we scout MongoDB, or CouchDB? Do we scout Pulumi, or Terraform? Some teams will try to do an apples-to-apples comparison of two relatively-similar technologies, but usually this effort just leads to the realization that &amp;quot;the differences are marginal&amp;quot; and, unfortunately, not particularly compelling. Which then begs the never-asked question, What would happen if we just threw a dart against the dartboard and picked one at random and tried building our prototype in that?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Any gained advantage is temporary.&lt;/em&gt; Great, you&apos;ve identified that you can build your mobile apps 5% faster using React Native. You must now engage in a deep coverup of epic counterespionage, because if your competitor gets wind of the fact that you&apos;re using this technology (and they will, if they watch your website&apos;s Careers page, which some competitors will do), they have every opportunity to follow in your footsteps and begin using it as well, which effectively negates your advantage and renders all the work the Scout Team effectively moot. Given the cost of the Scout Team against the time where you actually had the advantage, the ROI on the Scout Team&apos;s efforts generally isn&apos;t there, particularly when you could play &amp;quot;second mover&amp;quot; and watch your competitors&apos; Careers page, instead.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Successful Execution:&lt;/strong&gt; If the Scout Team is to be successful, it must first begin with either a business problem to solve or a hypothesis it seeks to prove and disprove (yes, both). &amp;quot;We believe that we can produce customer-acceptable mobile applications in half the time if we use a cross-platform toolkit to build hte mobile app&amp;quot; is a reasonable hypothesis, because it leads to the natural question, &amp;quot;What does &apos;customer-acceptable&apos; mean?&amp;quot; as well as &amp;quot;Well, how long does it take us to build a mobile app in both iOS and Android today?&amp;quot;. Technology-centric folks (myself included) will feel more comfortable with formulating a hypothesis than a business problem, so either the team has to run its hypotheses past product owners or business analysts or even customers themselves before adopting one for scouting.&lt;/p&gt;
&lt;p&gt;Then, once the problem or the hypothesis has been adopted, the team should move into a series of phases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Discovery (1 to 5 days):&lt;/em&gt; What&apos;s out there? This shouldn&apos;t take longer than a week, maximum. For some topics, it might even be just a day. Google to your hearts&apos; content, and capture the results in some kind of table to be able to do the best (highly-ignorant, because you really are just getting started here) comparison. Keep in mind, you&apos;re not at a decision point yet, you&apos;re literally just comparing the options. No code is written yet.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Discussion (2 hours):&lt;/em&gt; Once the discovery is finished, do a quick conversation (in person or online) about the options. All the attendees are given the table, encouraged to bring their own opinions, and as soon as the meeting starts, take a vote on the top 3 to explore. (I prefer &amp;quot;$100-voting&amp;quot; schemes, where you get to &amp;quot;spend&amp;quot; a fictitious amount of money/votes on up to three options, and the results are tallied. It&apos;s flexible voting, and allows those with really strong opinions to make the strength of that opinion known.) What stand out as the top three choices, given the problem or hypothesis? Limit yourself to three.&lt;br /&gt;
One will probably emerge as a majority favorite, another will be a lukewarm choice, and two others will be argued about extensively. Put a hard limit on this meeting, and if the team can&apos;t decide which one to explore as the third option, make the call to only use two--that&apos;ll usually coalesce agreement around a third (surprisingly quickly). If it doesn&apos;t, then clearly neither one has much momentum behind it within your team, so just do two.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Exploration (1 week):&lt;/em&gt; Now, depending on the size of the team, comes exploration, during which the thing is downloaded, installed, a few demos are built/explored, and initial conclusions are drawn. In order to avoid strong opinions coloring the analysis, however, make sure that whichever team member voted the strongest in favor of the technology is &lt;em&gt;not&lt;/em&gt; given the technology to explore. That is to say, if Ted spent $50 on Flutter, Woody spent $25, and Scott spent $10, then Scott should be the one to explore Flutter. The reasoning here is simple--if Ted voted so strongly for Flutter, he runs a strong risk of being biased in favor of it, and will be less likely to spot the negative traits. Scott, however, feels less strong, and so will likely be more open-minded. (Yes, this system can be gamed if somebody really wants to try and game it, but honestly, if you can&apos;t trust your R&amp;amp;D team to be able to approximate some degree of unbiased investigation, then you probably have bigger problems.)&lt;br /&gt;
Keep in mind here, you&apos;re &lt;em&gt;not&lt;/em&gt; building your prototype yet. You&apos;re literally just trying to get a sense for the &amp;quot;unboxing experience&amp;quot;--can we run demos right away? Are other dependencies involved? Do we have the right tools or infrastructure already, or would we need to pull down more in order to get even the simplest example up and running? This goes a long way to hint at what the overall developer experience will be.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Prototype Decision (2 hours):&lt;/em&gt; Once the team has had a little experience with each of the three options, it&apos;s time to decide which one to build the prototype in. The previous exploration step is essentially a preview for what comes next, but the team can&apos;t realistically build anything of substance if they&apos;re trying to do it across a large number of options, so reducing it down to one helps keep things focused. Meet with the team, with each of the three options presented, examples discussed, and make a decision out of the three.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Prototype (1-3 months):&lt;/em&gt; Now the time is right to build out the prototype, always with an eye towards the hypothesis or the problem. Don&apos;t just build a CRUD app--any tool can do that. Build something that has the difficulty characteristics that your business deals with. Got a mainframe you need to talk to? Figure out how that would work as part of the prototype. Complex workflow? Really convoluted price-calculation logic? All that has to be a part of the prototype, or it&apos;s not a successful prototype.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Presentation (1 week):&lt;/em&gt; Having spent the time building out the prototype, now the team needs to build out the presentation: Specifically, the questions answered, the issues addressed, the results, and so on. But keep in mind that at least &lt;em&gt;half&lt;/em&gt; of this presentation would need to be forward-facing--that is to say, it needs to talk about what adoption would look like and how it would play out within the company. Which teams would adopt first? How would they go about adopting? What&apos;s the timeframe? What do the steps look like, going from zero to &amp;quot;adopted&amp;quot;? Without practical execution steps, your prototype is just a target, not a plan.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Execution (variable):&lt;/em&gt; At this point, having established a plan, the time has come to start integrating the new thing into the overall fabric of the team/organization/company. The time and effort required to do this will be variable, depending on the work required and how deeply it will cut through the rest of the organization, but this is the point to which the entire effort has been building. Integration, training, all of these things form the core of the execution of the adoption of the new technology, and now having established the start of the momentum to adopt it, it&apos;s time to carry it through. The full effect of this effort will likely require much more than the efforts of the Scout team, though--this is now a &amp;quot;digital transformation&amp;quot; effort, which means it&apos;s likely something that will need to be coordinated at an executive level.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

	</description>
    </item>
    <item>
      <title>The R-and-D Spy Team</title>
      <link>http://blogs.newardassociates.com/blog/2024/spy-team.html</link>
      <pubDate>Wed, 12 Jun 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/spy-team.html</guid>
      	<description>
	&lt;p&gt;There are four different kinds of R&amp;amp;D teams, each with very different actions and goals, and each with very different outcomes. The success of the team often depends on aligning the activities of the team with the intended goals, and it&apos;s actually quite reasonable for a company to have two or more teams, each operating independently and towards different ends. In this post, I explore the Spy Team.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;As a reminder, there are four kinds of R&amp;amp;D Teams:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;a href=&quot;./scout-team.html&quot;&gt;Scout team&lt;/a&gt;, exploring what tech others in the industry have built (e.g., Flutter, SwiftUI, etc)&lt;/li&gt;
&lt;li&gt;the &lt;a href=&quot;./spy-team.html&quot;&gt;Spy team&lt;/a&gt;, exploring what competitors have built&lt;/li&gt;
&lt;li&gt;the &lt;a href=&quot;./library-team.html&quot;&gt;Library team&lt;/a&gt;, building lowest-common-denominator libraries used (sometimes) within the company&lt;/li&gt;
&lt;li&gt;the &lt;a href=&quot;./research-team.html&quot;&gt;Practical Research team&lt;/a&gt;, building novel solutions to the company&apos;s (and others&apos;) problems&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;The Spy Team&lt;/h3&gt;
&lt;p&gt;The spy team&apos;s purpose is pretty much as its name implies: Take a strong look at what competitors and adjacents are doing in your industry, and how they do (or might) affect your company&apos;s activities. The spy team doesn&apos;t get industry press articles written about the things they are doing, but they do often adopt a technology quickly enough to make a difference without paying the cost of finding all the mistakes and wrong assumptions about it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; Technology is often seen as a competitive advantage by a number of companies, but an equally larger number of companies don&apos;t want to be the &amp;quot;first mover&amp;quot; in a technology space because of the costs involved in discovering how to apply something to their day-to-day operations. When the Web first became a &amp;quot;thing&amp;quot;, for example, many companies ran to the Web with an idea of bringing a corporate &amp;quot;home page&amp;quot; (which was the principal use case for the Web browser at first) to the rest of the world. MySpace was the first in that regard, and built quite the comprehensive set of individuals&apos; home pages as a result. But companies pretty quickly discovered that the real power of the Internet-connected web browser wasn&apos;t in showing off one&apos;s questionable design skills, but in the brand-new world of being able to sell things to people. MySpace was the first-mover, but very quickly discovered they had no real business model to lean on, while Amazon went on to become one of the biggest tech companies on the planet. Lesson learned: Don&apos;t be the first-mover. Wait for the first-movers to figure out everything wrong with a technology, then leverage that knowledge and experience (which is free to you now) and be the &lt;em&gt;second&lt;/em&gt;-mover, but the vastly more efficient adopter, of a technology.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Successful Execution:&lt;/strong&gt; The spy team&apos;s execution model is often cyclical, in which the team chooses a &amp;quot;target&amp;quot; for their activities, and engages in some &amp;quot;creative reconnaissance&amp;quot; to determine what that company is doing. This doesn&apos;t mean decking out tuxedo-clad actors in all the latest spy gadgets or engaging in questionably-legal corporate espionage. In many cases, it&apos;s as simple as looking at the company&apos;s careers page (to determine what they&apos;re hiring by looking at the &amp;quot;skills desired&amp;quot; section of each job listing), or &amp;quot;view source&amp;quot; on the company&apos;s various web properties, or even looking on LinkedIN at current employees and discovering what their posts tell you about what they&apos;re doing or using at work.&lt;/p&gt;
&lt;p&gt;Then, once something new has been discovered, the spy team kicks into high gear, looking at the technology and the company&apos;s public statements and conversations around that technology. Competitor just adopted React? Cool--see if you can identify which team inside the company is using React, what they&apos;re using it for, and how the adoption seems to be going. Are any of the company&apos;s engineers or technical executives speaking at conferences? See if you can catch the video recording of the talk, and use that as a guide for what they might be using it for, and what &amp;quot;minefields&amp;quot; they ran into when they were using it. Simultaneously, of course, begin your own investigation into React itself, but always with an eye back to what the competitor is doing and saying, so that you can avoid the mistakes they&apos;ve made.&lt;/p&gt;
&lt;p&gt;Once you have a good sense of the technology and how it might (or might not) apply to your own company&apos;s problems, you shift into &lt;a href=&quot;./scout-team.md&quot;&gt;Scout Team&lt;/a&gt; mode: prepare a presentation, define a prototype, and work out an execution plan for transitioning to using the new technology within your own company&apos;s fabric.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The R-and-D Research Team</title>
      <link>http://blogs.newardassociates.com/blog/2024/research-team.html</link>
      <pubDate>Wed, 12 Jun 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/research-team.html</guid>
      	<description>
	&lt;p&gt;There are four different kinds of R&amp;amp;D teams, each with very different actions and goals, and each with very different outcomes. The success of the team often depends on aligning the activities of the team with the intended goals, and it&apos;s actually quite reasonable for a company to have two or more teams, each operating independently and towards different ends. In this post, I explore the Research Team.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;As a reminder, there are four kinds of R&amp;amp;D Teams:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;a href=&quot;./scout-team.html&quot;&gt;Scout team&lt;/a&gt;, exploring what tech others in the industry have built (e.g., Flutter, SwiftUI, etc)&lt;/li&gt;
&lt;li&gt;the &lt;a href=&quot;./spy-team.html&quot;&gt;Spy team&lt;/a&gt;, exploring what competitors have built&lt;/li&gt;
&lt;li&gt;the &lt;a href=&quot;./library-team.html&quot;&gt;Library team&lt;/a&gt;, building lowest-common-denominator libraries used (sometimes) within the company&lt;/li&gt;
&lt;li&gt;the &lt;a href=&quot;./research-team.html&quot;&gt;Practical Research team&lt;/a&gt;, building novel solutions to the company&apos;s (and others&apos;) problems&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;The (Practical) Research Team&lt;/h3&gt;
&lt;p&gt;The Research team (also more recently called &amp;quot;the innovation team&amp;quot; or the &amp;quot;disruption team&amp;quot; in more &amp;quot;hip&amp;quot; companies) is the one most people think about with respect to an R&amp;amp;D team. It&apos;s important to note, however, that the team cannot be just focused on research--like the Scout team, the Research team has to have a constant eye on what they build having a practical impact on the company that sponsors them. For that reason, I often make the conscious decision to put the word &amp;quot;practical&amp;quot; in front of the name, so that the emphasis is on practical research that will have a direct effect on the company&apos;s ability to execute.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; It has been proven, over and over again, that companies that don&apos;t spend time thinking about how to leverage technology to make their business run more effectively or more interconnectedly or more... well, pick your favorite adverb here, it probably applies... will find that they are being surpassed by competitors who have. This statement, however, is exceedingly vague, and is often vague on purpose--nobody exactly knows what the &amp;quot;next big thing&amp;quot; will be, so they don&apos;t know ahead of time what the right adverb is to use!&lt;/p&gt;
&lt;p&gt;For example, there was a time when simply shipping something on the company&apos;s website was sufficient. Then it needed to be up there more quickly than the competitors. Then it needed to be faster and more interactive. Then the push was to get more users on the platform. And so on and so on. With each &amp;quot;internet generation&amp;quot; a new adverb became the watchword of the industry, and massive amounts of time and energy were spent chasing that adverb. (Case in point: For a while, the chief goal was &amp;quot;scale&amp;quot;/&amp;quot;scalability&amp;quot;, and many companies went bankrupt trying to build a platform that could handle the &amp;quot;inevitable&amp;quot; challenges of having a million simultaneous users on the platform--even before they had their first user.)&lt;/p&gt;
&lt;p&gt;If a Research team is trying to build things that will help the company go to &amp;quot;where the puck will be, instead of where it is now&amp;quot;, as the famous hockey player is famous for saying, then the Research team is one that is firmly in the position of having to make fantastic guesses on a regular basis, and--worse--be right all the time or risk being accused of wasting time and money. (Picture this exchange, if you will: &amp;quot;What do you mean you went out and built tools for integrating with a blockchain?&amp;quot; &amp;quot;But boss, back in 2020, you said...&amp;quot; &amp;quot;Blockchain is dead! (I read it in Forbes!) You should be chasing after AI!&amp;quot; Now imagine what the exchange was like in 2016, 2012, 2008, ....)&lt;/p&gt;
&lt;p&gt;The humbling truth for most businesses is that whatever the current industry hype is, it&apos;s probably not the thing that will most &amp;quot;move the needle&amp;quot; for the company. And, worse, you can almost be certain that your competitor&apos;s CEO is currently yelling at their staff about the exact same thing--in 2024, everybody is chasing AI, such that the memes (&amp;quot;Hey, we have a pitch meeting in five minutes; do me a favor, take our pitch deck and replace all the uses of &apos;blockchain&apos; with &apos;AI&apos;, would you?&amp;quot;) are omnipresent on the social media feeds. And yet, even as we know that everybody is chasing it, the biological imperative inside of our lizard brains keeps whispering, &amp;quot;Yeah, but what if they&apos;re RIGHT this time? We could be hopelessly behind!&amp;quot; (all the while trying desperately to make you forget that it whispered the same thing about blockchain five years ago).&lt;/p&gt;
&lt;p&gt;In many respects, the problem with a Practical Research R&amp;amp;D team isn&apos;t the &amp;quot;research&amp;quot; part of it--it&apos;s the &amp;quot;practical&amp;quot; part of it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Successful Execution:&lt;/strong&gt; Executing a Practical Research team takes a lot more work than the other three kinds, because the practical research team has to do more in the way of research. (There&apos;s a certain logic to that statement, no?)&lt;/p&gt;
&lt;p&gt;For starters, part of the research has to be about what will &amp;quot;move the needle&amp;quot; for the &lt;em&gt;business as a whole&lt;/em&gt;. This is where some degree of familiarity with the domain (or having a subject matter expert on the team, even part-time) will help immensely with identifying what those areas might be. But keep in mind, part of the discussion can be &amp;quot;shifted left&amp;quot; in the pipeline--if there&apos;s no immediately obvious way to move the needle for one group in the company, what about doing so for a group that appears earlier in the pipeline?&lt;/p&gt;
&lt;p&gt;Consider Facebook, a social media company. Most of the company&apos;s work is in building the web platform on which Facebook provides its &amp;quot;feed&amp;quot; to each of its users. But &amp;quot;shifting left&amp;quot; takes us to some of the infrastructure behind that platform: building the web components, integration with incoming data sources, and (for a while there, anyway) making it easy for people to build apps (like games) on top of the platform or connected deeply with the platform. What does &amp;quot;shifting left&amp;quot; here look like? Well, if someone makes it easier to build a webapp, with particular semantics for how data is managed by the UI code, you get... React.&lt;/p&gt;
&lt;p&gt;Did React completely solve all of Facebook&apos;s problems? Probably not. (We can debate the issue for days or weeks if we want, but that would actually be missing the point.) More importantly, a team inside of Facebook asked themselves, &amp;quot;What is it something that we and/or our partners or customers do that we can improve?&amp;quot; And then they iterated. Over and over again, and eventually it made its way outside the company to be something that others found useful, and next thing you know, it&apos;s pervasive in the front-end industry.&lt;/p&gt;
&lt;p&gt;Which brings up an important point about all of this: Progress isn&apos;t made in big-bang &amp;quot;Eureka&amp;quot; moments. (Neither is scientific progress, for that matter, but that&apos;s a different discussion.) Progress is made in incremental steps with lots of iteration. The shorter those steps, the more iterations you get, the faster you learn about the thing you&apos;re iterating on. (This has actually been discussed in certain circles as the &amp;quot;OODA Loop&amp;quot;, as coined by John Boyd fifty years ago.)&lt;/p&gt;
&lt;p&gt;Consider this story from the book &lt;a href=&quot;http://www.amazon.com/dp/0961454733/?tag=codihorr-20&quot;&gt;Art &amp;amp; Fear&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The ceramics teacher announced on opening day that he was dividing the class into two groups. All those on the left side of the studio, he said, would be graded solely on the quantity of work they produced, all those on the right solely on its quality.&lt;/p&gt;
&lt;p&gt;His procedure was simple: on the final day of class he would bring in his bathroom scales and weigh the work of the &amp;quot;quantity&amp;quot; group: fifty pound of pots rated an &amp;quot;A&amp;quot;, forty pounds a &amp;quot;B&amp;quot;, and so on. Those being graded on &amp;quot;quality&amp;quot;, however, needed to produce only one pot – albeit a perfect one – to get an &amp;quot;A&amp;quot;.&lt;/p&gt;
&lt;p&gt;Well, came grading time and a curious fact emerged: the works of highest quality were all produced by the group being graded for quantity. It seems that while the &amp;quot;quantity&amp;quot; group was busily churning out piles of work – and learning from their mistakes – the &amp;quot;quality&amp;quot; group had sat theorizing about perfection, and in the end had little more to show for their efforts than grandiose theories and a pile of dead clay.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As a practial research team, you need to put out &lt;em&gt;lots&lt;/em&gt; of work, not just one &amp;quot;eureka&amp;quot; work.&lt;/p&gt;
&lt;p&gt;Are you looking for examples of practical R&amp;amp;D? Consider some of the ideas being put forth by &lt;a href=&quot;https://www.microsoft.com/en-us/research/&quot;&gt;Microsoft Research&lt;/a&gt;, or &lt;a href=&quot;https://labs.oracle.com/pls/apex/r/labs/labs/projects&quot;&gt;Oracle Labs&lt;/a&gt;. (For the record, MSR produced F#, and Oracle Labs is the group behind GraalVM.) IBM used to have a similar section, alphaWorks, which unfortunately got shut down a number of years ago due to IBM&apos;s inability to actually be successful. &lt;a href=&quot;https://research.facebook.com/&quot;&gt;Meta/Facebook&lt;/a&gt; has one, too. Does your company need to fund a multi-million (possibly -billion) dollar research group? Of course not. That&apos;s what companies with billions of dollars in their budget can afford to do. But a company of several hundreds in size can put together a single team of 5 +/- 2 developers to iterate on ideas to make the company&apos;s technology a better return on investment.&lt;/p&gt;
&lt;p&gt;Which brings up the last point: A practical research team needs to be extremely visible to the rest of the company in terms of the work they are doing and the research they are carrying out. Because a team of this nature is usually a &amp;quot;net negative&amp;quot; in terms of the company&apos;s financials (they draw a lot of money in and rarely generate any money back), socialiing the work and demonstrating the current iteration is crucial to demonstrating the value of the team. In addition, it&apos;s important for people to get their hands on what the research team is doing--putting alphas and betas out into the world (or at least into the world inside the company, if there&apos;s no interest in open-sourcing the efforts) is important both to the visibility of the team as well as a means of obtaining feedback around the ideas.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Four Kinds of Research-and-Development Teams</title>
      <link>http://blogs.newardassociates.com/blog/2024/four-kinds-of-rd-teams.html</link>
      <pubDate>Sat, 1 Jun 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/four-kinds-of-rd-teams.html</guid>
      	<description>
	&lt;p&gt;Many developers get really excited when they join an R&amp;amp;D team, because it signals in their minds that they&apos;re among an elite group looking to move the needle for a company. We imagine the business suddenly soaring in revenue and profit because of the whatever-thing we just built. We can hear--in the mind&apos;s ear--the kudos and praise raining down from the C-Suite as the whatever-thing we just built is rolled out company-wide and maybe, just maybe, industry-wide. We&apos;re excited!&lt;/p&gt;
&lt;p&gt;Wait, what was it we were trying to do again?&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;In my &lt;a href=&quot;../2024/the-problem-with-rd-teams.md&quot;&gt;last post&lt;/a&gt;, I talked about some of the problems with R&amp;amp;D teams and how they&apos;re run. What I didn&apos;t really get into in that post, however, was the idea that (I believe) there are four different kinds of R&amp;amp;D teams, each with very different actions and goals, and each with very different outcomes. The success of the team often depends on aligning the activities of the team with the intended goals, and it&apos;s actually quite reasonable for a company to have two or more teams, each operating independently and towards different ends.&lt;/p&gt;
&lt;p&gt;In brief, there are four kinds of R&amp;amp;D Teams:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;a href=&quot;./scout-team.html&quot;&gt;Scout team&lt;/a&gt;, exploring what tech others in the industry have built (e.g., Flutter, SwiftUI, etc)&lt;/li&gt;
&lt;li&gt;the &lt;a href=&quot;./spy-team.html&quot;&gt;Spy team&lt;/a&gt;, exploring what competitors have built&lt;/li&gt;
&lt;li&gt;the &lt;a href=&quot;./library-team.html&quot;&gt;Library team&lt;/a&gt;, building lowest-common-denominator libraries used (sometimes) within the company&lt;/li&gt;
&lt;li&gt;the &lt;a href=&quot;./research-team.html&quot;&gt;Practical Research team&lt;/a&gt;, building novel solutions to the company&apos;s (and others&apos;) problems&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In each of those subsequent posts, I address each of these in some level of detail, but here&apos;s summaries for each:&lt;/p&gt;
&lt;h3&gt;The Scout Team&lt;/h3&gt;
&lt;p&gt;The Scout Team is what most corporate R&amp;amp;D teams go after: The hunt for new technology that will somehow provide the company with a competitive advantage over its competitors, despite the fact that the competitors are all themselves out there scouting the industry just like this team is. New programming languages, new databases, new architecture styles, new whatever-fill-in-the-blank, just so long as it is (a) new and (b) not yet mainstream, it&apos;s a candidate for the Scout Team&apos;s infinite desire to create prototypes that bear a remarkable resemblance to the demos that the new thing has on its website or in its documentation.&lt;/p&gt;
&lt;h3&gt;The Library Team&lt;/h3&gt;
&lt;p&gt;The Library team is the team given responsibility for managing reusable artifacts within the company--libraries, tools, frameworks, services (cloud or on-prem), whatever--because achieving actual reusability, it turns out, requires a degree of commitment of time and resources to maintaining and homogenizing those artifacts. Doing this work, at the same time a team is trying to manage a product release, ends up becoming a distraction to the product release cycle, particularly as the shared &amp;quot;thing&amp;quot; becomes more widely shared.&lt;/p&gt;
&lt;h3&gt;The Spy Team&lt;/h3&gt;
&lt;p&gt;The spy team&apos;s purpose is pretty much as its name implies: Take a strong look at what competitors and adjacents are doing in your industry, and how they do (or might) affect your company&apos;s activities. The spy team doesn&apos;t get industry press articles written about the things they are doing, but they do often adopt a technology quickly enough to make a difference without paying the cost of finding all the mistakes and wrong assumptions about it.&lt;/p&gt;
&lt;h3&gt;The Practical Research Team&lt;/h3&gt;
&lt;p&gt;The Research team (also more recently called &amp;quot;the innovation team&amp;quot; or the &amp;quot;disruption team&amp;quot; in more &amp;quot;hip&amp;quot; companies) is the one most people think about with respect to an R&amp;amp;D team. It&apos;s important to note, however, that the team cannot be just focused on research--like the Scout team, the Research team has to have a constant eye on what they build having a practical impact on the company that sponsors them. For that reason, I often make the conscious decision to put the word &amp;quot;practical&amp;quot; in front of the name, so that the emphasis is on practical research that will have a direct effect on the company&apos;s ability to execute.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Problem With Most R-and-D Teams</title>
      <link>http://blogs.newardassociates.com/blog/2024/the-problem-with-rd-teams.html</link>
      <pubDate>Tue, 28 May 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/the-problem-with-rd-teams.html</guid>
      	<description>
	&lt;p&gt;For many software developers, career success comes when they are placed on the &amp;quot;R&amp;amp;D&amp;quot; (research and development) team. It seems like a golden ticket kind of role: Spend time exploring new technology (which lots of developers enjoy doing), weighing in, offering insights, and just... it&apos;s like, all play, and no deadlines! And yet, strangely (or perhaps not), those teams never seem to last long--they go through one, maybe two iterations on something, and then the team is broken up and nothing replaces it for a few years until a new VP comes along and says, &amp;quot;Wait, who&apos;s tracking our future direction?&amp;quot; and forms one again.... Only to have it dismember again in a year or two. What gives?&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Typically, the &amp;quot;failures&amp;quot; of these teams have nothing to do with the team&apos;s lead or its members; in fact, it&apos;s often counterintuitive that they would fail, since they&apos;re often made up of some of the most senior people in the company. In fact, in many cases, participation on this team is itself a reward for success elsewhere in the firm!&lt;/p&gt;
&lt;h3&gt;Why Build One of These?&lt;/h3&gt;
&lt;p&gt;We begin our analysis with the classic philosopher&apos;s question: &amp;quot;Why?&amp;quot; Or in this case, &amp;quot;Why does this team exist? What&apos;s the purpose of the team, and what are they asked to do?&amp;quot;&lt;/p&gt;
&lt;p&gt;And, as with many of these philosophical questions, almost right away we run into an interesting problem: &lt;em&gt;Nobody knows.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Most companies know, intuitively, that technology can be a competitive advantage, and almost every company that is over twenty years old has found themselves in a situation where they slept on a technology and suddenly found themselves on the wrong side of history when a competitor suddenly roars past them. Never mind the fact that the technology is only the surface symptom of why the competitor surpassed them, clearly the fault is that &amp;quot;We aren&apos;t studying the future enough! We aren&apos;t protecting our future! We need a team to do research and development!&amp;quot;&lt;/p&gt;
&lt;p&gt;Armed with this &amp;quot;realization&amp;quot;, a VP or CTO acts as the sponsor/champion for the founding of an R&amp;amp;D team, a team leader is selected for the role, and the team is told... pretty much nothing solid. &amp;quot;Go evaluate the industry! Find us that competitive advantage that we need! Go &apos;future-proof&apos; our tech investment!&amp;quot; and other such empty statements are offered up as the vision or goal of the team, and they are turned loose.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;NOTE: Keep in mind that &amp;quot;R&amp;amp;D&amp;quot; here could easily be replaced with &amp;quot;innovation&amp;quot;--as in, the &amp;quot;R&amp;amp;D Team&amp;quot; could easily be called the &amp;quot;Innovation Team&amp;quot; and staffed with not just engineers but also product and UX folks, but the goals are still equally vague. It simply highlights that most companies don&apos;t know how to Innovate any more than they know how to Research &amp;amp; Development.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The CTO might check in once or twice a quarter, particularly around review time, but for the most part the team is left alone, to their own devices, to char their own way. &amp;quot;These are the best and the brightest in the company,&amp;quot; any doubters are told, &amp;quot;And they need time and space in which to work.&amp;quot; If the doubters persist, they&apos;re told stories about teams at big companies that turned out the most amazing things by being left alone--Smalltalk and the DynaBook at Xerox PARC, or the iPhone at Apple, or any of a dozen other stories (only some of which actually have any bearing in fact, but that never stops the stories from being told). The R&amp;amp;D team itself will often get into the mix, too. &amp;quot;We need to behave like a startup,&amp;quot; the R&amp;amp;D team tells anyone who comes knocking. &amp;quot;That means we have to go out there and Innovate. R&amp;amp;D. Discover. Disrupt, even!&amp;quot;&lt;/p&gt;
&lt;p&gt;After a while, though, enough questions are asked that the CTO or VP is finally ready/willing/able/persuaded to take a deeper look at what the team is doing. &amp;quot;Can you present some of your findings to the Board/Company/Department sometime next month? We&apos;re all eager to hear what you&apos;ve come up with.&amp;quot; And the R&amp;amp;D team, just as eager to show off the fruit of their labor, agree to put together a presentation.&lt;/p&gt;
&lt;h3&gt;The Presentation&lt;/h3&gt;
&lt;p&gt;THe appointed hour comes around, and the R&amp;amp;D team proudly stands up to present what they&apos;ve spent the last six, nine, twelve, sometimes even eighteen months working on. And it&apos;s....&lt;/p&gt;
&lt;p&gt;&amp;quot;We&apos;re really excited to show you how Flutter can be used to completely change the way we build software. We&apos;ve combined it with Firebase to produce this amazing prototype demonstrating....&amp;quot;&lt;/p&gt;
&lt;p&gt;It&apos;s one presentation after another about existing technologies out in the world, just outside the mainstream. Elixir. Flutter. Kotlin. Two years ago it would&apos;ve been &amp;quot;Cloud Native&amp;quot;. Five years ago it would&apos;ve been &amp;quot;Serverless&amp;quot;. Today it&apos;s probably something in the AI space, such as demonstrating how to build a chatbot or use a vector database.&lt;/p&gt;
&lt;p&gt;The CTO is excited. &lt;em&gt;Wants&lt;/em&gt; to be excited. Tells everyone else they &lt;em&gt;need&lt;/em&gt; to be excited by this. But the rest of the Board or the rest of the company are demonstrably less so. This doesn&apos;t really showcase how the company will catch up on their competitor, particularly because the competitor doesn&apos;t seem to be using that....? If the CTO or VP are in a strong position, they might double down on the R&amp;amp;D team, but in time, before long, somebody points out that this team is &amp;quot;the most expensive team in the company&amp;quot; and pressure builds to break the team up and put all that brainpower and skill to use on other teams that are sorely lacking in such. Before long, the R&amp;amp;D team is gone, the former team&apos;s members are either bitter or sad, and sometimes they start sending out resumes shortly thereafter. The CTO or VP move on at some point, which--if the team isn&apos;t broken up by then--almost guarantees the replacement is going to take a look at this huge &amp;quot;investment&amp;quot; and its return, which is pretty close to nil, and break them up at that point.&lt;/p&gt;
&lt;p&gt;And all of the findings are essentially lost to the company, but helpfully captured on each members&apos; resume.&lt;/p&gt;
&lt;h3&gt;Analysis&lt;/h3&gt;
&lt;p&gt;Many readers are already jumping out of their seats, screaming, &amp;quot;Of course the team failed, they weren&apos;t researching the right thing!&amp;quot; But as other readers will point out, that&apos;s not the real problem. The &lt;em&gt;real&lt;/em&gt; problems are that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;The team was never given any goals.&lt;/em&gt; What problem are they trying to solve? &amp;quot;Innovate&amp;quot; isn&apos;t a goal, it&apos;s a vague word that could mean anything to anybody at any time. Worse, the term&apos;s shared definition and context can easily change over time. Sure, it&apos;s entirely possible the team is versed enough in the company&apos;s business domain to know intrinsically what the problems are--just as it&apos;s entirely possible that the CEO, who doesn&apos;t actually program for a living, knows programming enough to know what language and stack the company should use. (Without the regular feedback that comes from doing the job, any &amp;quot;knowledge&amp;quot; about a job should be treated as suspect and untrusted until proven otherwise.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;The team had no business problem guiding it.&lt;/em&gt; Technology, as any halfway-trained product owner will be quick to point out, has to solve an actual business problem in order to have any value to the business. What&apos;s the business problem that needs to be solved? What does solving that problem look like? The best R&amp;amp;D teams are, in fact, run like a startup, complete with pitch: &amp;quot;This team is going to (blank). Our customer (people inside the company) faces pain in the form of (blank), and we aim to solve for this pain by creating a solution that (blank).&amp;quot; &lt;strong&gt;&lt;em&gt;The R&amp;amp;D team has to have a driving goal, a purpose, or it risks wandering around in the technology jungle for a while before finally being declared &amp;quot;missing in action&amp;quot; and rescued (disbanded).&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;The team has no checkpoints or accountability points.&lt;/em&gt; Even in those rare cases where the team has goal, it frequently lacks any sort of checkpoint or accountability. &amp;quot;We&apos;re &lt;em&gt;innovating&lt;/em&gt;! You can&apos;t put a schedule on that!&amp;quot; True, but you &lt;em&gt;can&lt;/em&gt; put a periodic checkpoint to see how the team is faring against the goal, and/or force the team to present their findings on a much more regular basis. It&apos;s a simple agile problem--without feedback the team cannot know how well they are actually attacking the problem. In a startup, you get those checkpoints via &amp;quot;seed rounds&amp;quot; and &amp;quot;Board meetings&amp;quot; and &amp;quot;revenue targets&amp;quot;; in a larger firm, you&apos;ll have to create them. &lt;strong&gt;&lt;em&gt;The R&amp;amp;D team needs to show progress on a regular basis towards the goal that was set, or it will be assumed to be lost, regardless of its actual progress or status.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;The team had no plans beyond the research.&lt;/em&gt; For most of these presentations, the R&amp;amp;D team creates a prototype, a wonderful example of using the thing(s) they&apos;ve researched, and they show it off during the presentation. &amp;quot;It&apos;s amazing, it&apos;s wonderful, it cuts our development time by (some wild-eyed number)!&amp;quot; Which is all great, but did anybody on the team stop to think about how this would/could get rolled out within the company? Like, if the research is on Elixir, what&apos;s the plan if the CTO says, &amp;quot;Great! We&apos;re in!&amp;quot;? As the natural experts within the company, the R&amp;amp;D team is now going to be tasked with figuring out the rollout, starting with which projects will get updated, which teams get training, and which projects will see the perceived benefits of the new thing right away. What are reasonable timeframes? What are the likely obstacles groups will hit? Is the intent to freeze all development across the company and do a rewrite of everything in Elixir? How reasonable is that? How &lt;em&gt;possible&lt;/em&gt; is that? &lt;strong&gt;&lt;em&gt;It&apos;s not enough to just say, &amp;quot;Look there!&amp;quot;; the R&amp;amp;D team also needs to have some kind of plan around how this would actually &lt;em&gt;work&lt;/em&gt;.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;The team&apos;s prototype doesn&apos;t actually address the hard problems.&lt;/em&gt; The prototype usually bears a slight resemblance to what the company does, but usually it&apos;s an idealized version of the problem, with none of the ugly parts. &amp;quot;It&apos;s just a prototype,&amp;quot; they&apos;ll say when challenged on that point. Unfortunately, these prototypes, which often are built to be basic CRUD apps over a data store of one form or another, show off how well the new thing does the &lt;em&gt;easy&lt;/em&gt; parts. Folks, any technology can make the easy parts look easy--any prototype that&apos;s actually gong to be useufl needs to show how well it handles the Hard Parts. This was one of the major pain points among the Ruby-on-Rails and NodeJS crowds back in the early stages of each of those technologies--yes, they made it absurdly easy to build a CRUD app, but then again, so did everything else. Show me the RoR app that streamlined how I talk to a mainframe, or how the NodeJS app can talk to our legacy COM/DCOM or CORBA objects. And they didn&apos;t--or couldn&apos;t--and as a result, it took a very long time for either of those two to break into &amp;quot;the enterprise&amp;quot;, but were overwhelmingly adopted by startups, who lacked those brownfield obstacles. (Then, of course, when the startups were bought, they had to learn how to do those integrations, but by that point the die was already cast.) &lt;strong&gt;&lt;em&gt;If you build a prototype, it has to demonstrate how to handle the hard problems, not the easy ones.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Even then, however, the R&amp;amp;D team can still get lost if they aren&apos;t run properly or in the right direction. But starting by addressing some of these points will help at least get the team to a 50/50 shot of succeeding at something.&lt;/p&gt;
&lt;p&gt;I have much deeper thoughts about the different kinds of R&amp;amp;D teams and how to think about creating a group that focuses on innovation (to the scale of something like what Facebook created with React or what Netflix did with Chaos Monkey), but that&apos;s going to have to wait for a new post.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>An Engineering Manager Challenge</title>
      <link>http://blogs.newardassociates.com/blog/2024/engineering-manager-challenge.html</link>
      <pubDate>Mon, 20 May 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/engineering-manager-challenge.html</guid>
      	<description>
	&lt;p&gt;My LinkedIn feed recently brought me a question posted about &lt;a href=&quot;https://www.linkedin.com/feed/update/urn:li:activity:7198459086902878208/&quot;&gt;an interview question the original poster faced&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;You&apos;re the tech lead and your team is getting stretched thin. You decide to add resources &lt;em&gt;(sic; not my choice of words here)&lt;/em&gt; but you can afford 1 senior full-stack developer or 2 junior full-stack devs. Which do you choose and why?&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&apos;s a decent engineering manager question. So....&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;tl;dr&lt;/em&gt;&lt;/strong&gt; I think the issue is an ROI calculation, based on short-term relief vs long-term relief. It&apos;s an immediate-cost vs long-term ROI analysis, in other words, but measured in the currency of time/effort, rather than money. (The capital expenditure here is way smaller than the operational cost, when you start adding up your teams&apos; time.) The longer the window, the more the juniors make more sense.&lt;/p&gt;
&lt;p&gt;Now, let&apos;s dive deeper into why I think this.&lt;/p&gt;
&lt;h3&gt;Context&lt;/h3&gt;
&lt;p&gt;Let&apos;s make a few assumptions here, that (1) the juniors we&apos;d hire are going to come with basic skills in our tech stack (i.e., they know how to write React, Java, and SQL, but have no clue about our codebase), and (2) the senior would not only have the basic skills in the stack, but be of sufficient skill in our stack that she could debug into the stack itself if need be. That may be an unrealistic assumption, both in terms of what we (collectively) mean by &amp;quot;junior&amp;quot; and &amp;quot;senior&amp;quot;, but clarifying what &amp;quot;senior&amp;quot; and &amp;quot;junior&amp;quot; means here is going to make a huge difference in the outcome. In particular, we&apos;ll want to spend a moment thinking very consciously about the senior--if our tech stack is React/Java/MongoDB, and we find a senior who is most comfortable in Angular/C#/MSSQLServer, would that individual still qualify as a &amp;quot;senior&amp;quot; in this discussion? For my money, the answer to that is going to be very much dependent on what our stressors are, and where we could see new hires jumping in.&lt;/p&gt;
&lt;p&gt;Along similar lines, let&apos;s also assume that our tech stack is fairly mainstream. If we&apos;re using something that&apos;s &lt;em&gt;too&lt;/em&gt; bleeding edge, the junior/senior split isn&apos;t going to matter as much, because each will still likely need to spend time coming up to speed with our stack. If we&apos;re using Elm, Jolie, and ArangoDB, both juniors and seniors are going to spend half their time looking up how to do common things in the unfamiliar parts of the stack. (And God help us all if there&apos;s Perl in here somewhere.)&lt;/p&gt;
&lt;p&gt;Lastly, I think it&apos;s important to assume that the rest of the team is going to welcome the newcomer(s). If the team is stressed, that&apos;s not always a given, particularly since the newcomer(s) will (a) disrupt the existing team dynamics, and (b) likely have lots of questions and/or suggestions that were asked or discussed a while ago. If the team has no patience, bringing anybody in is going to be a bit rough, on both the existing team and the newcomer(s). If the team sees the newcomer(s) as a welcome relief, they&apos;ll be much more likely to go whatever extra mile necessary to make them feel welcome.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;EDIT (22 May 2024):&lt;/em&gt; A few comments from &lt;a href=&quot;https://www.linkedin.com/posts/tedneward_this-was-an-interesting-question-on-one-of-activity-7198605380766109696-8umw&quot;&gt;my LinkedIn post&lt;/a&gt; to this blog entry pointed out there were a few things more that should&apos;ve been here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&amp;quot;There is no such thing as a full-stack developer.&amp;quot;&lt;/em&gt; While I agree with the statement, it&apos;s often important to take the context as-is and work within it, particularly when (as was the case for the original poster) the question comes in an interview. Moreover, as much as I disagree with the use of the term, it is a standard, and it does lead to the next important assumption....&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;quot;... I would hire a frontend and a seperate backend developer.&amp;quot;&lt;/em&gt; That&apos;s actually a really good point--it often makes more sense to have some degrees of specialization within the team, and once we examine the full-stack assumption on its own merits, we open up the idea that maybe it&apos;s actually better-and-easier to hire people into particular roles. This is a really good point, which still falls outside the framework of the question, but definitely something to consider in a real-world scenario.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;quot;As an Engineering Manager, you can negotiate the scope and schedule....&amp;quot;&lt;/em&gt; Another great point, &lt;em&gt;assuming&lt;/em&gt; you actually have that flexibility. I would amend the statement to read &amp;quot;As an EM, you &lt;em&gt;should&lt;/em&gt; have the ability to negotiate the scope and schdule...&amp;quot;, but unfortunately there are some projects where scope and/or schedule are constrained in ways that aren&apos;t easy to amend. (If an app needs to be ready before the Super Bowl, it&apos;s not like we can change the date of the Super Bowl!) All that said, if you have the flexibility, that&apos;s another lever to slide, because if you can slide the scope or the schedule, you can potentially relieve some of the pressure that leads the team to feeling stretched. That &lt;em&gt;also&lt;/em&gt; said, headcount is also a pretty precious commodity, so if you have it, there&apos;s a strong drive to exercise it and hire, because if you solve the problem without hiring, there&apos;s a near-1.0 chance that it&apos;ll be taken from you and given to another team. It&apos;s not necessarily fair, but it is a truth of even small companies.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;quot;I&apos;d also consider the makeup of the team. If you have 3 juniors.... If you have 3 seniors....&amp;quot;&lt;/em&gt; I actually can&apos;t believe I missed this in my analysis, and yet, I can; I typically look to hire &amp;quot;diamond&amp;quot; or &amp;quot;pyramid&amp;quot; teams, that are either balanced senior-midlevel-junior (sort of a 1:2:1 ratio) or junior-heavy (1:2:3 ratio), but that&apos;s no excuse in forgetting to question the assumption.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;quot;How big is the team? What is its present composition, output, turnover, etc?&amp;quot;&lt;/em&gt; This is more of the previous, and all are good points to consider.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;quot;If the team is feeling stretched thin, it&apos;s because they have too much work to do, and the planning isn&apos;t getting done correctly already.&amp;quot;&lt;/em&gt; That&apos;s a pretty good point, and also highlights another assumption that may not be legitimate to assume, in that there&apos;s actual deadlines here. It&apos;s entirely possible/reasonable that the team is simply stretched thin over a constant workload (think a support-ticket bug-fixing maintenance team, for example), and there aren&apos;t immediate deadlines that are in jeopardy.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Most of these assumptions don&apos;t, in large part, change the analysis of my answer, although the front-end/back-end distinction could very well weigh in significantly. Lesson learned, and thanks for the comments!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Assumptions set, let&apos;s analyze.&lt;/p&gt;
&lt;h3&gt;Analysis&lt;/h3&gt;
&lt;p&gt;Juniors are initially a drag on the project velocity as the others on the team help bring them up to speed. Over time (months), however, they can end up significantly increasing team delivery velocity as they begin to jell with the rest of the team and start pulling their own weight. This can be eased some by making sure their initial assignments are appropriate to developers with less experience (both in general and with the codebase). Best approach I&apos;ve seen is to have them take on bugs rather than building features while they&apos;re coming up to speed.&lt;/p&gt;
&lt;p&gt;However, keep in mind that the senior is going to need onboarding time, too! No developer, not even the mythical &amp;quot;10X Developer&amp;quot;, is going to be able to jump into a brand-new codebase and immediately add value without requiring other team members&apos; help/assistance. Usually the senior can come up to speed faster (weeks instead of months), but the onboarding cost is never zero.&lt;/p&gt;
&lt;p&gt;We also need to consider the auspices under which we&apos;re bringing them in--specifically, is this a contract basis, or are we making them full-time offers? Contract vs full-time is an important distinction here, too. If this is just a short-term contract, don&apos;t bother with the juniors for the same ROI-based reason. However, I think a contract approach here is wildly inappropriate, because all you&apos;re doing is kicking the &amp;quot;stretched thin&amp;quot; feeling down the road for a time, and eventually you&apos;ll be right back to square one, and all the time invested in the onboarding will have been a waste. So either hire them full-time, or don&apos;t bother.&lt;/p&gt;
&lt;p&gt;Also, factor in the interviewing and hiring time. Interviewing and hiring seniors takes much longer than hiring a pair of juniors--this holds true regardless of the market. Seniors are also more likely to have multiple interviews running simultaneously, and thus a higher chance of rejecting an offer or ghosting partway through. Plus, juniors are generally more intrinsically motivated to demonstrate they were a good bet, so they&apos;ll be more likely to take on the challenge more enthusiastically. (In fact, the hard part might be getting them to actually ask questions, because they want to prove they don&apos;t need the handholding, when it would be far more efficient if they just ask.) As for determining their skillsets, juniors will take a little more time to interview, since they&apos;ll more likely be unwilling to admit what they don&apos;t know, whereas most seniors are (generally) comfortable with elucidating their less-comfortable spots. Juniors also will potentially have blind spots outside the tech, and may take longer to adjust to the culture; but while seniors may be more accustomed to adjusting to new cultures, may also be more intransigent and stubborn if they decide they don&apos;t like the culture. That can play out in the team interpersonal dynamics in a big way.&lt;/p&gt;
&lt;p&gt;Remote will have a play in here, too, and generally it&apos;s not a great story: You&apos;re probably going to want people who will be willing to &amp;quot;come into the office&amp;quot; frequently, in order to get direct exposure to others on the team in the most high-signal way possible. If the whole team is remote, then you&apos;re going to need to figure out how the newcomer(s) are going to have easy access to other team members in order to ask the questions they&apos;re inevitably going to have. This means you&apos;re probably going to need them to &amp;quot;buddy up&amp;quot; with existing team members, either by virtually pairing together on code, or else by having them share a Teams/Zoom call that&apos;s muted for much of the day but still live. (Slack or Discord just may not be quite at the high-interactivity and low-barrier-to-question level that an open channel or an in-presence &amp;quot;swiveling chair&amp;quot; situation would provide.)&lt;/p&gt;
&lt;h3&gt;In short&lt;/h3&gt;
&lt;p&gt;If the timeframe is less than a month, don&apos;t hire anyone--you won&apos;t get the ROI. If the timeframe is less than 6 months, hire the senior--you won&apos;t get the ROI from the juniors in that short a timeframe. Otherwise, hire the juniors.&lt;/p&gt;
&lt;p&gt;Once you&apos;ve hired, pair the newcomer(s) with a rotation of the existing team members for the first several weeks (seniors) or months (juniors) or until the newcomer(s) are able to complete work without requiring more than one question per unit work (story, bug, etc). I think the superior approach is to have them fix bugs in the code to start (the first two or three weeks or months), then have them add functionality to existing features, and only after that do you have them create new features.&lt;/p&gt;
&lt;p&gt;But as with all answers of this type, context will influence and matter greatly on the outcome. &lt;em&gt;Caveat emptor.&lt;/em&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Software Architecture, In Practice</title>
      <link>http://blogs.newardassociates.com/blog/2024/software-architecture-in-practice.html</link>
      <pubDate>Mon, 26 Feb 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/software-architecture-in-practice.html</guid>
      	<description>
	&lt;p&gt;One of the more curious things I&apos;ve found, both in my time as a consultant and as a software management executive, is the striking differences between what the title &amp;quot;architect&amp;quot; means at different companies. Strangely (or perhaps, not so strangely), the nature of the job changes significantly depending on the size of the company and how &amp;quot;interwoven&amp;quot; the various software development teams are against one another. The larger, more interwoven the company, the more your job as an architect is &amp;quot;referee or facilitator between teams&amp;quot; than it is &amp;quot;decider of technical strategy and direction&amp;quot;.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Tell me if this story has ever happened to you: You are set up as an architect on a project. &lt;em&gt;Cool,&lt;/em&gt; you think. &lt;em&gt;I&apos;m going to make some solid decisions, make sure that they&apos;re well-reasoned, approachable, nothing too overkill, all the things that make an architecture a good one.&lt;/em&gt; You spend some time analyzing the problem domain, you build out a few proofs of concept and a prototype or two, and your team is off and running. Knowing that your project doesn&apos;t exist in isolation, of course, you make room for some interoperability capabilities--let&apos;s say through an API. You make the firm decision that any access to your system has to come through the API.&lt;/p&gt;
&lt;p&gt;One day, you get a call. Another team is working on a project that runs in parallel to yours, and they want to talk about how you&apos;ve built some of your data-access code. &lt;em&gt;Sure,&lt;/em&gt; you think, &lt;em&gt;That makes sense. They don&apos;t want to reinvent the wheel if they don&apos;t have to, and I&apos;m here for it--that&apos;s good architecting!&lt;/em&gt; You meet, and that other team comes away with some ideas of how to best connect to a database like yours--and the internal Git repo URL for your project, so they can see how to use it.&lt;/p&gt;
&lt;p&gt;Another team, meanwhile, has also heard of your project&apos;s work, and wants to discuss whatever-it-is you&apos;re using for your API layer. More importantly, they want to understand how you&apos;re doing some of the validation logic. &lt;em&gt;Sure,&lt;/em&gt; you think, &lt;em&gt;They&apos;re trying to avoid reinventing the wheel, too.&lt;/em&gt; You meet, and once again they walk away with the Git repo URL for your project, because they wanted to see how to use that whatever-it-is.&lt;/p&gt;
&lt;p&gt;But you&apos;re starting to get a weird feeling in your stomach that all these teams are too alike. You mention it to your boss, who nods thoughtfully and asks, &amp;quot;It&apos;s almost as if all these teams are building the same thing over and over again, no?&amp;quot; Somewhat uncertain, you nod, because, well, yeah, it kinda does. &amp;quot;Thanks for bringing this to my attention, I&apos;ll check with a few others and see if they get the same feeling. Good work.&amp;quot; Feeling good that you may have done the company some good, you go back to your team and hunker down.&lt;/p&gt;
&lt;p&gt;For a sprint or two.&lt;/p&gt;
&lt;p&gt;Then, one day, you get called into an Engineering All-Hands. The Senior Engineering VP opens by saying, &amp;quot;We have great news. Thanks to some proactive investigation,&amp;quot; and she gestures at you, &amp;quot;We have identified a major source of waste in our organization, that of duplicating efforts across many teams, and we are forming a group to combat it. We will be pulling all the architects together into an architect group, where we can share and spread architectural knowledge across the teams and create opportunities to aggressively share code.&amp;quot; On the one hand, cool, but on the other hand, you&apos;re a little worried because your project--&lt;em&gt;ahem&lt;/em&gt; your former project--is somewhat like those other projects, but it&apos;s kinda not. But, hey, you get a cool new title--&amp;quot;enterprise architect&amp;quot;--and it&apos;ll give you a chance to rub shoulders with other architects, so... yay?&lt;/p&gt;
&lt;p&gt;After a few weeks&apos; of reorg madness, things settle down, and you start having meetings with your former project team and the other project teams that you&apos;d met with before, around the database and the API. Under the SVP&apos;s new mandate, the teams are breaking out these into separate microservices, and you&apos;re now in the uncomfortable position of trying to help your former team modularize code that was never intended to be modularized, for the use by teams that have problems that are similar--but definitely not identical--to theirs, with all the weird corporate battles around ownership and time allocation that come along for the ride: Who is responsible for bug fixes against the shared module/microservice? Who owns the decision-making around what can and cannot go into the microservice API? Each of the various teams look to you to champion their cause over the others, because after all, you were the one that helped them back when all this got started.....&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;When a company gets to be of a particular size, the different project teams often find themselves needing to collaborate in various ways, but (it seems) often don&apos;t feel comfortable doing so at just the &amp;quot;programmer&amp;quot; level--it&apos;s almost as if we don&apos;t trust programmers, even senior ones, to make decisions for their team. That&apos;s the Team Lead&apos;s job!&lt;/p&gt;
&lt;p&gt;But the Team Lead is too busy being the Lead--meetings with the boss, with the team as a whole and also as individuals, and responding to fires that pop up every so often--to really sit down with the other teams to sort out technical issues, so...&lt;/p&gt;
&lt;p&gt;Then one day, an executive realizes, &amp;quot;Hey, we have an Architect, and they&apos;re (supposed to be) the smartest technical person in the room, so let&apos;s have them sort these integration issues out! Even better if they&apos;re actually not attached to any one team but are instead part of an &amp;quot;architect team&amp;quot; or part of the &amp;quot;Enterprise Architecture&amp;quot; org. Then, when we disagree, we&apos;re not disagreeing with our teammates, we&apos;re disagreeing with somebody outside of the team who clearly doesn&apos;t understand the team&apos;s issues as well as we do.&amp;quot; Granted, they may not think of it in precisely thsoe terms--particularly that last bit--but the thought still pops up. (Even better, some organizations make the Team Lead be the Architect, or vice versa, which means it&apos;s really a no-brainer for that executive.)&lt;/p&gt;
&lt;p&gt;At this point, however, the role has transitioned away from the &amp;quot;solver of technical problems&amp;quot; and moved squarely into the &amp;quot;referee of team dynamics&amp;quot; and &amp;quot;arbiter of integration&amp;quot;. Once in this position, most enterprise architects find themselves in a position that is more organizational design than it is software design.&lt;/p&gt;
&lt;p&gt;And then, once that realization hits, the unhappy enterprise architect has two ways out: get promoted to become full-time management (embracing the organizational design side of the story) or get out of enterprise architecture entirely, either by transitioning to an IC role writing code again, or to a smaller organization wherein they can be &amp;quot;just&amp;quot; an architect again.&lt;/p&gt;
&lt;p&gt;For a little while, anyway.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;The root of the problem? In the previous section it&apos;s actually easy to spot: &lt;em&gt;&amp;quot;trying to help your former team modularize code that was never intended to be modularized&amp;quot;&lt;/em&gt;. Remember, microservices were an organizational design solution to a particular problem at Amazon: that of removing all dependencies. According to &lt;em&gt;Working Backwards&lt;/em&gt;, Jeff Bezos spent a lot of time thinking about this.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Speed, or more accurately velocity, which measures both speed and direction, matters in business. With all other things being equal, the organization that moves faster will innovate more, simply because it will be able to conduct a higher number of experiments per unit of time. Yet many companies find themselves struggling against their own bureaucratic drag, which appears in the form of layer upon layer of permission, ownership, and accountability, all working against fast, decisive forward progress.&lt;br /&gt;
The answer lies in an Amazon innovation called &amp;quot;single-threaded leadership,&amp;quot; in which a single person, unencumbered by competing responsibilities, owns a single major initiative and heads up a separable, largely autonomous team to deliver its goals.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In essence, the whole &amp;quot;microservices&amp;quot; approach popularized by Amazon was, in fact, not an exercise in software design, but in organizational design--by creating teams that were focused on a single objective, with an explicit agenda to eliminate dependencies that they might have. The elimination of dependencies, it turns out, is precisely the thing that holds up most teams, which (as any architect knows) is also the same principles around how to get the most throughput from a scalable system. &amp;quot;The enemy of scalability is contention.&amp;quot; The more often a process has to content for a shared resource, the worse the performance curve gets.&lt;/p&gt;
&lt;p&gt;For a team to truly be the master of its own destiny, it needs to be focused on one thing (&amp;quot;single-threaded&amp;quot;), with zero dependencies on external resources (databases, message queues, etc). It admits, up front, that there will be some violation of the Don&apos;t Repeat Yourself principle, but like all of the practices listed in the Pragmatic Programmer, they were intended as heuristics, not ironclad algorithms.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;All of this, though, is really tangential to my main point: When you take an architect position, you really need to understand, up front, what role your position is really taking. Are you tied to a single-threaded organization? Then you are probably a software/system architect, focused on achieving a specific and concrete result. If you&apos;re matrixed across several teams, though, you&apos;re much more likely to become an organizational architect, focused more on helping teams navigate their cross-dependencies with one another.&lt;/p&gt;
&lt;p&gt;Of course, there&apos;s always the third option, in which you are matrixed but have the authority to dictate to those teams the technical decisions you feel best suits their combined problem set. But, in all honesty, that position, I think, is a corporate legend: Everybody&apos;s heard of it, everybody yearns for it, but nobody&apos;s ever seen one in the wild except at an extreme distance, much less been in one. I used to think we called those roles &amp;quot;CTO&amp;quot;, but having spent some time in and among CTO roles, I&apos;m less convinced than ever that it actually exists.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Why Candidates Don&apos;t Trust Recruiting</title>
      <link>http://blogs.newardassociates.com/blog/2024/recruiting-process-thoughts.html</link>
      <pubDate>Mon, 12 Feb 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/recruiting-process-thoughts.html</guid>
      	<description>
	&lt;p&gt;If you&apos;ve spent any time on LinkedIn at all the past few years, you&apos;ve seen the incessant posts about people &amp;quot;looking for their next challenge&amp;quot;. Many of these are followed, sometimes weeks or months later, by additional posts (sometimes by the same people) about being really really &lt;em&gt;really&lt;/em&gt; desperate to find something. Sandwiched right in between them are posts by LinkedIn &amp;quot;influencers&amp;quot; trying to tell us the right sequence of events, the &amp;quot;magic sauce&amp;quot;, to get that next gig. Then, every so often, there&apos;s a recruiter in the feed that bemoans the behavior of other recruiters, says, &amp;quot;Do better&amp;quot;, and disappears. Yet, nothing ever gets better.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;To all the recruiters in the world: The truth is, while some of you are certainly predatory and untrustworthy, I firmly believe the majority of you aren&apos;t trying to take advantage of anybody. That&apos;s the good news. The bad news is, we still don&apos;t trust you. And the main reason we don&apos;t trust you is because &lt;em&gt;we don&apos;t trust your process.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Don&apos;t get me wrong, there&apos;s plenty of bad--or at least thoughtless--actors out there in the world. I recently interviewed with a CEO for a CTO position in which we would be working quite closely together. Post-interview, a week later, no response. She sent out an email right after the interview with the full job description, but has since offered no insight as to whether the search is still going, whether there will be another interview... nothing.&lt;/p&gt;
&lt;p&gt;I don&apos;t think she&apos;s being deliberately cruel (far from it, she seems like a good person), but it&apos;s certainly sent something of a message. Even if she comes back next week with a &amp;quot;Great, we&apos;d love to schedule another round...&amp;quot; I don&apos;t know that I&apos;d be all that interested to continue. Sure, she&apos;s busy--but so is everybody.&lt;/p&gt;
&lt;p&gt;Relationships, professional or personal, take work. This is a position wherein two people are going to be working closely together, and if you don&apos;t have the time and energy to lay down a good foundation for a good working relationship, then how can I be sure you&apos;re going to put the time and energy into a good working relationship once we&apos;re on the job together?&lt;/p&gt;
&lt;p&gt;What&apos;s worse, I don&apos;t even know if we&apos;re done or if we&apos;ve even started--I have zero insight into what the interview process is. I don&apos;t know if we had a good conversation, a bad one, a &amp;quot;meh&amp;quot; one that didn&apos;t really take me out of the running but left me out of the top consideration.... nothing.&lt;/p&gt;
&lt;p&gt;I have ZERO insight into what&apos;s happening there. And in the absence of information, people tend to assume the worst, and then make judgments and decisions based on their assumptions. Then recruiters wonder why nobody&apos;s really warming up to them, even though half (or three-quarters) of the time, the recruiter is actually on the candidate&apos;s side!&lt;/p&gt;
&lt;h4&gt;FAANG&lt;/h4&gt;
&lt;p&gt;Big companies are much, MUCH worse. While they have a better chance of describing the overall process to you (in some few cases, they&apos;ll actually have it posted either as part of the job posting or as part of the application process), the process itself tends to lend itself to opacity--multiple rounds, each with multiple interviewers, often each asking a spate of questions that they themselves aren&apos;t 100% familiar or comfortable with.&lt;/p&gt;
&lt;p&gt;Depending on the position, the nature of the interview will be different. Some of these interview rounds will be &amp;quot;system design&amp;quot; interviews, in which the candidate is presented with an open-ended question, such as one I recently went through, wherein you are challenged to &amp;quot;Please design an Identity and Access Management (IAM) system.&amp;quot; You get maybe a paragraph&apos;s worth of specification. The interviewer (or interviewers) are often there to see... what, exactly?&lt;/p&gt;
&lt;p&gt;Or perhaps you are doing a &amp;quot;culture fit&amp;quot; round, where the interviewers are asking you about the company&apos;s cultural values/positions/statements. They ask questions about your thoughts on... what, exactly? Whether you agree with the company&apos;s values? How you would align to them? The minefields are so deep here.&lt;/p&gt;
&lt;p&gt;Or, if the position is coding-related in some way, you might be asked to write some code. Of course, these are often entirely &amp;quot;context-free&amp;quot;, so as to not have to worry about the business domain. This means--typically--a question specifically around algorithms. How do you insert a node into the middle of a linked list? How do you do a breadth-first search of a binary tree? How do you optimize a search of a HashMap-of-String-to-String? All of these being problems that pretty much nobody actually writes code for in 2024.&lt;/p&gt;
&lt;p&gt;For each of these, the &amp;quot;right answer&amp;quot; can take one of several forms: the interviewers are looking to &amp;quot;see how I think&amp;quot; by watching how the design or code or cultural thought evolves in response to insights gathered and the questions I ask along the way; the interviewers are looking to &amp;quot;see how good an architect/coder/person I am&amp;quot; by keeping their thoughts to themselves until we have a finished product; or the interviewers are looking to &amp;quot;see how collaborative I am&amp;quot; by watching not what&apos;s produced, but the assumptions I make along the way (instead of asking the interviewers--the customer/client proxy stand-ins--questions).&lt;/p&gt;
&lt;p&gt;Best part is, the interviewers often have their own opinions about what the &amp;quot;right answer&amp;quot; is for these (&lt;a href=&quot;https://www.youtube.com/watch?v=0oGMbAIcXCQ&quot;&gt;something something something Kubernetes, something something something comPLETE&lt;/a&gt;), and even if you present a viable alternative, if it&apos;s not aligned at least a little with their preconceived notion of what the &amp;quot;right answer&amp;quot; looks like, you fail.&lt;/p&gt;
&lt;p&gt;And even &lt;em&gt;more&lt;/em&gt; better, nobody will ever say ahead of time what the round is looking for. You&apos;re left, as a candidate, to try and figure it out on the fly. Guess wrong, and you don&apos;t pass. Don&apos;t pass the round, you don&apos;t pass the interview.&lt;/p&gt;
&lt;p&gt;And you will never, ever, EVER know why.&lt;/p&gt;
&lt;h4&gt;It&apos;s not the recruiter, it&apos;s the process&lt;/h4&gt;
&lt;p&gt;Look, recruiters, you can be as charming, heartwarming, and convivial as any human can possibly be, and all of it isn&apos;t going to matter in the long run.&lt;/p&gt;
&lt;p&gt;The problem is that the nicest recruiter in the world doesn&apos;t address the primary frustration that candidates experience: A complete lack of visibility into the recruiting process, both at a high level (what the process is like) or at a more tactical level (what&apos;s expected and/or being examined in each round).&lt;/p&gt;
&lt;p&gt;Look, put it like this: Imagine somebody sits you down in a room, and tells you that the test you&apos;re about to take is going to determine your (and your family&apos;s) financial future for the next half-dozen years or so. They then walk out of the room, without telling you what the test is on, what a passing grade looks like, or the subject you&apos;re about to be tested on. Or whether the test will be written, oral, or athletic. Or even how many tests there will be. And when it&apos;s over (whenever it is, in fact, over, because remember, they can always call you in a few weeks and tell you &amp;quot;it&apos;s time for round two&amp;quot;, or round three, or round twelve, or....) you won&apos;t actually be told your results unless you&apos;re hired/passed.&lt;/p&gt;
&lt;p&gt;Repeat this a few times, and it really won&apos;t matter what the personality of the person bringing you into the room--the process itself will break even the most cheerful, optimistic, skilled, and confident candidate.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Cheating With Chat-GPT</title>
      <link>http://blogs.newardassociates.com/blog/2024/cheating-with-gpt.html</link>
      <pubDate>Thu, 1 Feb 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/cheating-with-gpt.html</guid>
      	<description>
	&lt;p&gt;A colleague pointed out a semi-scientific study about &lt;a href=&quot;https://interviewing.io/blog/how-hard-is-it-to-cheat-with-chatgpt-in-technical-interviews&quot;&gt;interviewees cheating with ChatGPT&lt;/a&gt; hosted by interview.io; the results are not particularly great if you&apos;re relying on LeetCode-style problems: &amp;quot;Predictably, the [interviewee group using common LeetCode problems without modification] performed the best, passing 73% of their interviews. Interviewees reported that they got the perfect solution from ChatGPT. ... In our experiment, interviewers were not aware that the interviewees were being asked to cheat. As you recall, after each interview, we had interviewers complete a survey in which they had to describe how confident they were in their assessments of candidates Interviewer confidence in the correctness of their assessments was high, with 72% saying they were confident in their hiring decision.&amp;quot;&lt;/p&gt;
&lt;p&gt;Whoops! Maybe it&apos;s time to unit-test your interview process?&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;These are not reassuring numbers. When almost three-quarters of the interviews &lt;em&gt;in which the interviewees were told explicitly (by the experimenters) to not rely on their own skills, but exclusively on ChatGPT&lt;/em&gt; are considered &amp;quot;confident&amp;quot;, you really have to wonder: How good &lt;em&gt;is&lt;/em&gt; your interview process? How many false positives are you allowing through? How many false negatives?&lt;/p&gt;
&lt;p&gt;This sort of scientific testing (although, to be fair, this really needs to be done many more times, with different interviewees and interviewers, for the results to be considered scientifically conclusive) of interview processes really needs to happen a lot more. And while I&apos;ll step aside and let more-qualified psychological-testing masters tell us how to create tests of this nature industry-wide, I think there&apos;s value in considering the more localized test--that is, testing the recruiting process within your own company.&lt;/p&gt;
&lt;p&gt;But let&apos;s forget the &amp;quot;cheating with ChatGPT&amp;quot; for just a moment--because we hadn&apos;t really solved interviewing even before ChatGPT got into the mix. Most companies, their interview processes are broken--hilariously so.&lt;/p&gt;
&lt;p&gt;Lots of technology companies not only don&apos;t believe their interviewing/hiring process is broken, they think it&apos;s magnificient. As a matter of fact, I&apos;ve been told point-blank (as a candidate, no less!) that &amp;quot;Our interview process is one of the top 10% across the industry.&amp;quot; (Soooo many questions went through my mind when they said that, like, how did you measure that? Who else participated? What was the metric used here? And did you measure this yourself, did you use a neutral third-party, and did you ask the candidates their opinions? On that last point, by the way, the answer was, not surprisingly, &amp;quot;no&amp;quot;.)&lt;/p&gt;
&lt;p&gt;The basis of any test--unit- or otherwise--is the relatively simple concept that we want to validate the algorithm by putting known inputs into one end, and comparing/seeing the known/expected outputs at the other end. With code, we can do this pretty easily, since (most) code is deterministic: put a character string into the parameter of a &amp;quot;toLower()&amp;quot; function, and we expect that the result will be a character string with all the upper-cased ASCII characters to be converted to lower-case. Put the same input in, you&apos;ll always get the same result.&lt;/p&gt;
&lt;p&gt;With humans, though, this is trickier. Humans are most certainly non-deterministic, so the same inputs can yield vastly different outputs. (Insert Dr Ian Malcolm&apos;s explanation of Chaos Theory from Jurassic Park here: &amp;quot;The conditions... never repeat and vastly affect the outcome&amp;quot;.) Imagine I come to work every morning and greet the security guard at the door with the same message. &amp;quot;Morning, Joe.&amp;quot; Some mornings he may nod back. Some mornings he may smile. Some mornings he may take that as an invitation to a longer conversation. Why is Joe so wildly all over the map in his responses? Because some mornings, he had a great morning: His alarm went off on time, he woke up refreshed, his spouse made him a lovely breakfast, whatever. Some mornings, Joe has a lousy morning: his alarm failed to go off, he didn&apos;t sleep a wink, his spouse is sick, whatever. Some of it even has to do with the number of times we&apos;ve done this particular exchange--in the beginning, he may have felt I was just being polite, but then he may have noticed that I said something similar to someone else, which started a longer conversation about kids, weather, or sportsball, and Joe may be deciding that I use this as an open invitation to a deeper conversation. So many different conditions deeply affect Joe&apos;s response, and I neither control, nor have any visibility, into any of them.&lt;/p&gt;
&lt;p&gt;Now take this to your interview process: If you&apos;re like most companies, you have a team of people you draw from to conduct interviews. There&apos;s variation #1, because two different people will test and interact with candidates differently. Many companies mix-and-match the teams of people doing the interview (often just grabbing people at random when the interview time comes up), which creates yet another significant variation, as the team dynamics can change how the team comes up with an answer. The team often comes up with questions on the fly, or worse, grabs standard LeetCode problems for the candidate to solve, interacting with the candidate the entire time (all the while pushing, prodding, rewarding, or punishing with their gestures, facial expressions, words, or outright statements)&lt;/p&gt;
&lt;p&gt;We can normalize some of this--having the same interview questions, the same process, even creating a rubric for the answers--but no matter the effort, &lt;em&gt;you&apos;ll never know if you&apos;re successful unless you test it.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Which brings me to the point: Unless you test your interview process, you&apos;ll have no idea of how good, or bad, it really is.&lt;/p&gt;
&lt;h4&gt;Testing Interviews&lt;/h4&gt;
&lt;p&gt;Before I go any further in this essay, I want to make two points clear: One, I have never had the opportunity to do any of this--the orgs I&apos;ve been a part of, where I wanted to do it, explicitly shot down the idea for one reason or another; and Two, I absolutely am going to keep looking for opportunities to do this, because I firmly believe that it is a necessary prerequisite to being able to feel confident about an interview process.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Hypothesis&lt;/em&gt;&lt;/strong&gt;: That a deterministic result is obtained when a candidate is put into our hiring/interview process. &lt;em&gt;(To be fair, a perfectly deterministic result is never going to be possible with humans--there&apos;s really just too many variables in play. So let&apos;s settle for a &amp;quot;reasonably&amp;quot; deterministic result, at least until we get some experience under our belts, hmm?)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Experiment&lt;/em&gt;&lt;/strong&gt;: We will take a candidate, and ask them to perform the same steps of our interview process as we would any other candidate.&lt;/p&gt;
&lt;p&gt;Caveats:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We do not wish to change the process; changing the process would change the algorithm, and yield an untrustworthy result.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We do not with to change the interviewers; these are also part of the process. However, if the interviewers know that this is a test, they will very likely behave differently than they would in a &amp;quot;live&amp;quot; setting. Therefore, the interviewers must be kept unaware that a test is under way.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In order to be able to &amp;quot;know the outcome&amp;quot; of the experiment, we need to work with &amp;quot;known&amp;quot; inputs ahead of time--that is to say, if we put a candidate into the system who is a highly-venerated, highly-respected engineer, our interview process should identify them as a highly-senior engineer (even if we don&apos;t pick up on all the accolades or successes); similarly, if we put a random individual &amp;quot;off the street&amp;quot; with no relevant skills whatsoever through our process, we should be able to identify them as such and yield a &amp;quot;no-hire&amp;quot; response.&lt;/p&gt;
&lt;p&gt;Readers familiar with my writing will probably already be thinking what I think is the key to this process: Work with known-quantity candidates, a la, friends and colleagues of the hiring team that are known to be solid performers, for the &amp;quot;yes-hire&amp;quot; known inputs. For the known &amp;quot;no-hire&amp;quot; known inputs? Hell, use paid actors. But to be certain, give the &amp;quot;known-yes-hire&amp;quot; candidates full transparency into the process and what questions might be asked, and give the &amp;quot;known-no-hire&amp;quot; candidates explicit instructions on how to answer any questions in the negative.&lt;/p&gt;
&lt;p&gt;Doing this, either the candidates have to be unknown to the interviewers (which unfortunately means you can&apos;t really use other engineers from your company, unless your company is extremely large), &lt;em&gt;or&lt;/em&gt; you have to hide their personal and physical characteristics from the interview team (which you probably should do anyway, but that&apos;s another discussion for another day). The ideal scenario would be use people who have already been hired by your company, so as to minimize the ambiguity of the &amp;quot;outsider-as-a-yes-or-no&amp;quot; (some people would insist that even somebody like Vint Cerf is not qualified to work at this company in the network team), so tweaking your process to allow for that kind of deception is preferred.&lt;/p&gt;
&lt;p&gt;By the way, if you do this several times a month (say perhaps one in every five &amp;quot;live&amp;quot; canddiates, maybe one in ten), you can slip a &amp;quot;known-no-hire-using-ChatGPT&amp;quot; into the cycle and see how well your process responds.&lt;/p&gt;
&lt;p&gt;Critics will be adamant that this is an absolute waste of time. I recall when people said the same thing about unit tests, and before that, QA. If it&apos;s important to you, it&apos;s important to measure it, examine it, and critique it.&lt;/p&gt;
&lt;p&gt;But hey, if you want to run your interviews with a close-to-0% confidence that you&apos;re getting the right results.... you do you.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>We Need to Talk</title>
      <link>http://blogs.newardassociates.com/blog/2024/we-need-to-talk.html</link>
      <pubDate>Mon, 15 Jan 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/we-need-to-talk.html</guid>
      	<description>
	&lt;p&gt;For many years, people have ranted and railed against the dread managerial &amp;quot;Do you have a second to chat?&amp;quot; opening that has no context around it. Just Google &amp;quot;Can we talk&amp;quot; and you get something in excess of 4 billion responses, many/most of which talk about how to respond to those openings, coupled with a stern shaking finger for those who use them. But what should we use instead?&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Imagine, for a moment, you&apos;re a manager. Your job, more than anything, is to keep a steady and close pulse on the team as a whole. You need to talk to them, listen to them, respond to them, and connect with them at both an intellectual and emotional level. In many respects, you are the connection they have to the rest of the company (particularly in remote-work situations), and much of what they know about the rest of the company will flow through you. Communication is essential.&lt;/p&gt;
&lt;p&gt;But, truthfully, there&apos;s another part of the job that we often ignore in conversations like these, and that&apos;s that managers are often privy to information that they are &lt;em&gt;not&lt;/em&gt; permitted to share with anyone, or at least not until some particular deadline has been passed or some kind of criteria has been met. Confidentiality, thy name is &amp;quot;manager&amp;quot;; you must never discuss personal information about one of your team members to anyone else, even if you know (or, more often, &lt;em&gt;think&lt;/em&gt; you know) that the individual doesn&apos;t consider it personal or is comfortable with you discussing it with others. That&apos;s theirs to tell, not yours. There is so much you cannot discuss until it&apos;s &amp;quot;done&amp;quot;: upcoming promotions, demotions, hiring, firing, reorganization, performance, it&apos;s a whole list of things that must--by both law and company policy--be kept close to your chest until &amp;quot;the right moment&amp;quot;.&lt;/p&gt;
&lt;p&gt;(We will also leave alone for the moment that &amp;quot;the right moment&amp;quot; is often decided long ahead of time, and by people who aren&apos;t you or even in the room with you. Complain as much as you wish, this is not likely to change. Ever.)&lt;/p&gt;
&lt;p&gt;All of this puts a natural tension on the free and open communication that any reasonable and/or compassionate manager wants to have.&lt;/p&gt;
&lt;p&gt;Let&apos;s assume for the moment that you have news to share with one of your team. For the sake of argument, the actual news itself doesn&apos;t matter--while it would be tempting to say, &amp;quot;Oh, it&apos;s terrible news about layoffs&amp;quot; or &amp;quot;It&apos;s that dreaded separation/termination conversation&amp;quot;, the opposite is often true, too, for purposes of this blog post. Either way, as your manager, I have a piece of news that I need to share with you.&lt;/p&gt;
&lt;p&gt;Now, keep in mind a few key considerations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;I really need to have the conversation in person.&lt;/em&gt;&lt;/strong&gt; Because of the sensitive nature of the news (again, regardless of whether it&apos;s a promotion or a termination), I need to be looking at you in the face when I deliver it, for a variety of reasons. Sometimes, we have to make do with a Zoom call because we&apos;re not in the same timezone, but then it&apos;s all that much more imperative to do this &amp;quot;face-to-face&amp;quot;. Doing this over an email or a chat window is just classless and incompassionate at best, legally-liable at worst.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;This isn&apos;t just normal day-to-day news.&lt;/em&gt;&lt;/strong&gt; Often it has a time component to it, and I need to get the news to you as quickly as possible. I need to do this because...&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;The rumor mill will be flying fast and furious.&lt;/em&gt;&lt;/strong&gt; Again, the kind of news doesn&apos;t matter--somehow people know they&apos;re being promoted even when their hiring manager hasn&apos;t heard the news yet--and so it&apos;s imperative that we get together to discuss this as quickly as possible, before rumor catches up to you and gives you a false report that I would then have to spend as much time deconstructing and denying as I do giving you the real news and explaining the consequences of that.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Assuming I&apos;ve been diligent about my communications with you, I have a couple of options available with which to deliver this news:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Our weekly 1:1.&lt;/em&gt;&lt;/strong&gt; This is often a great time/place to do it, because it&apos;s just the two of us, and anything we say here can often be done in confidence. That said, however, if the news is team-wide, I am now trusting that every single person on the team will be trust-worthy and refuse to share the news with anyone else before I&apos;ve had the chance to discuss it, &lt;em&gt;and&lt;/em&gt; that everybody on the team will be disciplined about their communication and not accidentally leak the information to somebody else on the team, who will silently resent being &amp;quot;the last to know&amp;quot; (which could very well be the case, if they&apos;re the last 1:1 in the week).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;A weekly team huddle.&lt;/em&gt;&lt;/strong&gt; The weekly team huddle is often the best place to deliver team-wide news all at once, but only if it affects the entire team--individual layoffs, individual performance actions (PIPs, etc) are entirely inappropriate to bring up at the team huddle, as would be any sort of salary adjustment (whether up or down), as it&apos;s only going to invite comparisons. You&apos;re going to end up dealing with some of that in any event (people on the team will, probably, talk to one another about raises and such, regardless of what you&apos;d prefer), so you certainly want to be prepared to handle those discussions, but having those conversations out in a public form (the team huddle) is pretty much the worst place possible to have them.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Beyond those, when do you have regularly-scheduled meetings with each of your directs? Most manager&apos;s don&apos;t, and so now we get in to the world of the dreaded &lt;em&gt;unscheduled chat&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Look, let&apos;s be face it: Any time you schedule something with your direct that isn&apos;t part of a regular cadence, it&apos;s going to raise some eyebrows. And as soon as their eyebrows go up, so will their anxiety. It&apos;s a natural human response: The brain is basically hard-wired to assume the worst of a situation. (Want to really watch this in action? Send your spouse or significant other a text message with just &amp;quot;Can we talk?&amp;quot; and then don&apos;t send anything after that. Or worse, start to type a follow-up, then erase it without sending, then start to type a follow-up, then erase it without sending, and by about the fifth or sixth iteration of this, you&apos;ll have effectively pushed them into a psychotic break.)&lt;/p&gt;
&lt;p&gt;If you really want to try and ease your direct&apos;s anxiety, you can try to provide some context. &amp;quot;Hey, can we chat? I need to talk to you about your promotion.&amp;quot; That certainly provides some context to the conversation, but it also runs the risk of misinterpretation on their end. &amp;quot;I need to talk to you about your promotion&amp;quot; can be interpreted by the confident as &amp;quot;I need to tell you that you got your promotion!&amp;quot; which, when it turns out that they didn&apos;t get it, feels like an utter rejection and low blow. &amp;quot;I need to talk to you about your promotion&amp;quot; to the anxious can easily be &amp;quot;I need to tell you that you blew it and didn&apos;t get the promotion&amp;quot;, but they&apos;re also just as likely to interpret it as &amp;quot;I need to tell you that you blew it and not only did you fail to get the promotion, the CEO is furious at your impertience and wants you fired&amp;quot;, ridiculous as that may sound. (Anxiety and unwarranted assumption really knows no boundaries.)&lt;/p&gt;
&lt;p&gt;The other danger of providing some context about a conversation is that unless you can do so without giving away part of the conversation, you run the risk of the worst of all situations: When the direct replies back with a response that demands more information or explanation. Now you&apos;re in exactly the situation you didn&apos;t want to be in, trying to explain or discuss a sensitive topic over a context-less medium like text, email, or instant messenger chat. If you try and punt on the conversation, your direct stews and simmers and gets angry or upset; if you don&apos;t, you&apos;re unable to read them effectively (and vice versa) and it becomes easy to really blow the whole thing into a Really Big Deal. Definitely not high on the Ted Lasso Scale of Senstivity and Compassion.&lt;/p&gt;
&lt;p&gt;I&apos;ll be transparent here: I personally have never found a way to ask a direct for an unscheduled meeting without triggering those negative feelings, and I really don&apos;t think there is one. Thus, my only real advice or suggestions here is as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Understand that your direct is going to be on edge.&lt;/em&gt;&lt;/strong&gt; If you give them the context-free request, they&apos;re going to be assuming the worst. It&apos;s human nature, and you can&apos;t really avoid it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Minimize the window of discomfort.&lt;/em&gt;&lt;/strong&gt; For everybody&apos;s sake, do &lt;em&gt;not&lt;/em&gt; ask to chat with somebody on Friday, and then schedule the meeting for Monday afternoon. Do the request first thing Monday, instead.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Be up-front as much as you can.&lt;/em&gt;&lt;/strong&gt; Don&apos;t schedule-bomb somebody and silently drop a meeting on your direct&apos;s calendar without at least telling them in an email, &amp;quot;I need to chat with you about something, and it&apos;s a little urgent. Saw you had some free time this afternoon, grabbed it for a conversation. Talk more then.&amp;quot; Yeah, your direct is going to start doing weird gyrations in their head as they try to mentally go over everything they&apos;ve done in the last few days that might trigger this, but remember, you can&apos;t help that. And, if you just silently schedule-bomb them, it&apos;ll just be that much more surprising and panic-inducing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;For the love of all humanity, don&apos;t just cancel the meeting without reason or ghost it.&lt;/em&gt;&lt;/strong&gt; Seriously. That&apos;s also a recipe for a psychotic break, and honestly, I think it&apos;s grounds for justifiable homicide in twelve states. If you put the meeting on the calendar, be there, or at the very least postpone or reschedule it with a reason. And keep in mind, you&apos;re leaving your direct twisting in the wind during the interim--if that doesn&apos;t bother you, then maybe you lack the compassion necessary to be a good manager.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And, hopefully it goes without saying, if you &lt;em&gt;can&lt;/em&gt; provide context to the conversation, by all means do so! Then you avoid all of this, and the world is a bright and happy place again. Most of the time, anyway....&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Subtle Power of Teams</title>
      <link>http://blogs.newardassociates.com/blog/2024/the-power-of-teams.html</link>
      <pubDate>Wed, 3 Jan 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/the-power-of-teams.html</guid>
      	<description>
	&lt;p&gt;A post on LinkedIn got a little close to my heart, showing a picture of Joe Flacco (an almost-retired NFL player, for those who aren&apos;t in to sportsball) and asking, &amp;quot;Are you overlooking experienced candidates because of their age? Take a lesson from Joe Flacco, who at 38 was written off by experts as too old and past his prime. Despite sitting at home hoping for a chance, the Cleveland Browns saw potential and gave him a chance to prove himself.&amp;quot; And as one who&apos;s &lt;em&gt;cough&lt;/em&gt; not exactly fresh-out-of-school myself, I thought it was worth a comment.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;It always surprises me how often companies and hiring managers think, &amp;quot;I know! Let&apos;s save a few bucks on somebody who&apos;s never seen anything, will overreact to the tiniest of crises and completely miss the subtle cues that something serious is about to go down. No WAY that&apos;s going to come back and haunt us!&amp;quot;&lt;/p&gt;
&lt;p&gt;Look, I get it: With the rapid iteration cycles in tech, it&apos;s hard to believe that somebody who&apos;s spend 45 years writing COBOL will have much to offer to your &amp;quot;full-stack&amp;quot; Javascript team. But you&apos;re missing the forest for the trees: Most 30-year veterans haven&apos;t spent all that time in just one stack or one company. The diversity of their experience vastly dwarfs all five of your recent college grads, and even if they can&apos;t pull all-nighters like the young&apos;uns, it&apos;s because they usually don&apos;t have to.&lt;/p&gt;
&lt;p&gt;Don&apos;t get me wrong, I&apos;m not advocating for a complete reversal of position, or that you need to toss your current crew. Don&apos;t make a whole team out of 45-year COBOL veterans, but don&apos;t make one out of Javascript-slinging GenZ&apos;ers, either. Your team should be a mix of skills and experience, using diversity of team composition to cover as many possibilities as you can.&lt;/p&gt;
&lt;p&gt;To borrow another analogy, which Diagnostic Medicine doctor would you rather have in charge of your company&apos;s medical case? Cameron? Chase? Foreman? 13, Kutner, or Taub? &amp;quot;Maybe,&amp;quot; you think, &amp;quot;he&apos;s suggesting we want Dr House, sure I get it.&amp;quot; Nope. I want him AND his whole team--there&apos;s a reason House needs a team, no matter how smart he is, and he&apos;s definitely smart, because he knows he needs a team that thinks differently from him and challenges his perspective and assumptions. That&apos;s (literally) the point of the whole show.&lt;/p&gt;
&lt;p&gt;As my dad used to say, &amp;quot;Youth and boundless energy lose to old age and treachery every time.&amp;quot; ;-)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2024 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2024/2024-tech-predictions.html</link>
      <pubDate>Mon, 1 Jan 2024 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2024/2024-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;It&apos;s that time of the year again, when I make predictions for the upcoming year. As has become my tradition now for nigh-on a decade, I will first go back over last years&apos; predictions, to see how well I called it (and keep me honest), then wax prophetic on what I think the new year has to offer us.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;As per previous years, I&apos;m giving myself either a &lt;strong&gt;+1&lt;/strong&gt; or a &lt;strong&gt;-1&lt;/strong&gt; based on a purely subjective and highly-biased evaluational criteria as to whether it actually happened (or in some cases at least started to happen before 31 Dec 2023 ended). If you want to skip to the new predictions, &lt;a href=&quot;#2024&quot;&gt;scroll down&lt;/a&gt; to the next major heading.&lt;/p&gt;
&lt;p&gt;2023 was a tumultuous year, for sure--lots of tech layoffs in the early part of the year as big-player after big-player announced whole trunks of the org tree no longer had a job. It definitely created some chaos and consternation among our industry, for sure, and that was all before the collapse of Silicon Valley Bank, which sent a huge ripple through both startup and established player alike.&lt;/p&gt;
&lt;p&gt;By the way, as of this writing, despite multiple false starts, I&apos;m &lt;a href=&quot;https://www.linkedin.com/posts/tedneward_hey-network-although-it-feels-a-little-activity-7008974172001378305-YrpY/&quot;&gt;still looking for my next great adventure&lt;/a&gt; (ideally as an Developer Relations or Engineering leader-of-leaders), so if you find my analysis here to be interesting or intriguing--even if you disagree with it--perhaps there&apos;s a role in which I can do this kinds of strategic and executive thinking on your company&apos;s behalf? Would love to hear from you.&lt;/p&gt;
&lt;h2&gt;In 2023...&lt;/h2&gt;
&lt;p&gt;... I wrote a lot of stuff. (That always seems to happen when I do these.) So let&apos;s get to it; as I do each year, I&apos;ll include the full text of what I wrote in each bullet point first, then put the &lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; after it with whatever insights or comments seem relevant. (Arguably none of them are, but hey, it&apos;s my set of predictions, so....) As always, evidence is highly opinionated, mostly anecdotal, and entirely from my (and some from my professional network&apos;s) perspective, so &lt;em&gt;caveat emptor&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;To start, I wrote:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;First off, the pandemic hasn&apos;t left us, and CDC is starting to talk about masking up again. Despite desperate efforts to pretend we&apos;re clear of COVID (and related viruses), we&apos;re not, and it&apos;s going to continue to rear its head in ugly ways going forward. I don&apos;t think we&apos;re going back to mandatory stay-at-home policies, mind you, but it&apos;s going to be a couple of years of really bad winters, medically speaking. The &amp;quot;taper down&amp;quot; I talked about last year definitely seems to be in full swing (or slope, as the case may be).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Masking is still a thing in much of the Pacific Northwest, and they&apos;re still required in most medical offices, but beyond that, COVID or no COVID, people have made their choice. Aside from the performative video piece, nobody is going around ripping masks off of other peoples&apos; faces. Periodically, somebody catches COVID and is down for a week (minimum, usually two), but that seems to be a risk we&apos;re willing to accept as a nation.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Secondly, even though the Ukraine conflict continues, and inflation reared its ugly head during the end of 2022, the economy doesn&apos;t look as bad as we thought it would six months ago, and I think things are going to &amp;quot;perk up&amp;quot; once we get through the holidays. 2022 sucked, but there&apos;s a lot of reasons to think 2023 won&apos;t be nearly as bad. (Of course, we thought that about 2022 compared to 2021, and about 2021 compared to 2020, so....)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Statistically, the economy has recovered. Inflation is coming back down, unemployment is actually back to reasonable numbers, and the stock market is doing... better. Nothing is back to its pre-2019 levels, but frankly, we&apos;ll probably never be there.&lt;/p&gt;
&lt;p&gt;Meanwhile, the war in Ukraine continues, and a new one has opened in Gaza. Regardless of which side of the political spectrum you&apos;re on, everything &lt;em&gt;feels&lt;/em&gt; terrible, and the last time that happened, Jimmy Carter was President. Are we due for another &amp;quot;Morning in America&amp;quot; moment? Probably not--we&apos;re all too cynical to the media for Reagan&apos;s watershed speech to work again, but something is going to give soon, and we will all rush to embrace it, because it just doesn&apos;t &lt;em&gt;feel&lt;/em&gt; as good as it should right now.&lt;/p&gt;
&lt;p&gt;Meanwhile, on the tech front....&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;strong&gt;&lt;em&gt;Blockchain-related losses are going to be huge tax write-offs.&lt;/em&gt;&lt;/strong&gt; &lt;a href=&quot;https://www.theguardian.com/technology/2022/dec/29/unsellable-worthless-nfts-tax-write-off&quot;&gt;It&apos;s already starting&lt;/a&gt;, and other companies will follow suit as soon as they see others doing it.&amp;quot; Going to give myself a &lt;strong&gt;+1&lt;/strong&gt; on this; most big-tech firms have divested their blockchain development efforts (and advertising), and the only ones really left pursuing it are startups (most of which seem desperate to exit from what I can see). Blockchain is pretty much dead as a tech, it seems, unless you&apos;re so deeply wrapped up in it that you need it in order to survive. &lt;strong&gt;Tally: +1.&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;***Blockchain-related businesses are likely to be the target of lawsuits.***&amp;quot; Well.... &lt;a href=&quot;https://en.wikipedia.org/wiki/Sam_Bankman-Fried&quot;&gt;Sam Bankman-Fried&lt;/a&gt; comes to mind immediately, not to mention most of his inner circle. That said, there were fewer lawsuits than I expected, particularly against the media personalities that shilled for crypto (Ashton Kutcher, Matt Damon, etc), but I probably shouldn&apos;t have expected them in the first place--a friend pointed out that the famous almost never get sued for hawking a bad product. Still, lawsuits and jail time, I&apos;ll take the (debatable) &lt;strong&gt;+1&lt;/strong&gt; here. &lt;strong&gt;Tally: +2&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;strong&gt;&lt;em&gt;The fallout from the cryptocurrency nightmare is going to stain &apos;Web3&apos; for a good long time.&lt;/em&gt;&lt;/strong&gt; .... Web3 is not going to be a fun place for a while.&amp;quot; That definitely qualifies as a &lt;strong&gt;+1&lt;/strong&gt;. Every one I know, be they developer, architect, tech manager, you name it, they&apos;re all staying well clear of anything &amp;quot;Web3&amp;quot; or &amp;quot;blockchain&amp;quot;, even when the job market was at its worst. Reddit is filled with threads of curious developers asking about the &amp;quot;negative feelings about Web3&amp;quot; and most future-looking Web3 discussions seem to tie it closely to social media, which is also taking major hits right now in the courts of public opinion. &lt;strong&gt;Tally: +3&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;***Distributed systems start to embrace contract-driven development cycles.***&amp;quot; This one is harder to judge--OpenAPI hasn&apos;t reached quite the level of ubiquity that I would expect to call this a solid +1, but at the same time, there&apos;s a lot of groups/teams that are starting to look for better ways to interact with an HTTP-based API than the traditional &amp;quot;just build out the URL and HTTP header by hand....&amp;quot; approach. Lots of the contract seems to be getting buried inside official SDKs released by the API provider, which more or less provides the same kind of &amp;quot;contract&amp;quot; approach, albeit with a lot more work on the part of the API provider. Still feels like we&apos;re moving in the same direction on the ferris wheel, though, so... &lt;strong&gt;+1&lt;/strong&gt;. &lt;strong&gt;Tally: +4&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;***Microservices start to give way back to deliberate monoliths.***&amp;quot; Well, talk about interesting--not more than a week after I wrote last year&apos;s predictions, I wrote another piece, &lt;a href=&quot;https://blogs.newardassociates.com/blog/2023/you-want-modules-not-microservices.html&quot;&gt;&amp;quot;You Want Modules, Not Microservices&amp;quot;&lt;/a&gt;, and boy did that resonate--it got picked up by a bunch of news and journal services, and much of the feedback/commentary was... actually agreement (modulo the odd conspiracy theorist who is still convinced that monoliths are somehow the gateway drug to 5G nanobots in your blood controlling your mind at the every whim of Bill Gates and the Greater Dolphin Cabal of the North Atlantic). Several companies turned around and de-micro&apos;ized their architecture back into a monolith, in fact, including &lt;a href=&quot;https://thenewstack.io/return-of-the-monolith-amazon-dumps-microservices-for-video-monitoring/&quot;&gt;Amazon&lt;/a&gt;. Turns out, &lt;a href=&quot;https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing&quot;&gt;all that traffic across the network&lt;/a&gt; bouncing between a bunch of services is &lt;em&gt;bad&lt;/em&gt;! &lt;a href=&quot;https://blogs.newardassociates.com/blog/2016/enterprise-computing-fallacies.html&quot;&gt;Who could&apos;ve guessed&lt;/a&gt;? &lt;strong&gt;+1&lt;/strong&gt;, bringing my &lt;strong&gt;Tally: +5&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;***Security companies are going to need to OSS their offerings.***&amp;quot; Checking the Auth0 GitHub repositories.... Nope. It was a long shot, and it definitely didn&apos;t happen. &lt;strong&gt;-1&lt;/strong&gt; means I&apos;m now at &lt;strong&gt;Tally: +4&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;strong&gt;&lt;em&gt;Work-From-Home (WFH) continues to normalize and become &amp;quot;just another location&amp;quot;.&lt;/em&gt;&lt;/strong&gt; (Probability 0.7)&amp;quot; Well... this one&apos;s harder. For each &lt;a href=&quot;https://www.usnews.com/opinion/articles/2023-10-03/it-is-time-to-end-the-war-on-remote-work&quot;&gt;&amp;quot;It&apos;s Time to End the War on Remote Work&amp;quot;&lt;/a&gt;, there&apos;s a &lt;a href=&quot;https://www.cnbc.com/2023/10/17/the-no-1-challenge-holding-companies-back-from-offering-remote-work.html&quot;&gt;&amp;quot;Remote Work is Still &apos;Frustrating and Disorienting&apos; for Bosses&amp;quot;&lt;/a&gt;. &lt;a href=&quot;https://www.nytimes.com/2023/10/10/business/remote-work-effects.html&quot;&gt;Studies continue&lt;/a&gt;, and likely will for the remainder of this decade, and while many companies are quietly just sorting it out internally, other companies are making great noise about return to the office (or just &lt;a href=&quot;https://www.usatoday.com/story/money/business/2023/12/22/wayfair-ceo-niraj-shah-email-work-longer-hours/72010867007/&quot;&gt;&amp;quot;work more hours&amp;quot;&lt;/a&gt;, which seems to have had exacty the effect you&apos;d expect), but when they do, it generates a ton of bad PR and the executives are usually obligated to walk it back. It looks like 2024 is going to (hint, hint) see a drawdown in the attempt to get people back into the office--but we&apos;ll leave that for the next section. For now, I&apos;ll give myself a &lt;strong&gt;+1&lt;/strong&gt; simply because it does feel like it&apos;s becoming more and more normal to expect a remote gig, and that&apos;s really the definition of the word &amp;quot;normalize&amp;quot;. &lt;strong&gt;Tally: +5&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;***Somebody is going to sue over state income tax.***&amp;quot; You can see &lt;a href=&quot;https://www.city-journal.org/article/a-state-tax-war&quot;&gt;where I was coming from&lt;/a&gt; on this one, but the SCOTUS&apos; continued unwillingness to take a stand on it surprised me and continues to surprise me. Technically, I get a point for this one, since... well, &lt;a href=&quot;https://www2.law.temple.edu/10q/its-official-a-renewed-challenge-to-the-convenience-of-the-employer-test/&quot;&gt;tax law professor, New York&lt;/a&gt;, you get the picture, but this has been an ongoing fight since well before the pandemic, and it doesn&apos;t seem to have &amp;quot;ballooned&amp;quot; into the bigger fight that I thought it would be, so at best I feel it&apos;s a &lt;strong&gt;0&lt;/strong&gt;. &lt;strong&gt;Tally: +5&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;***Low-code/no-code is going to accelerate further.***&amp;quot; A lot of the low-code/no-code efforts got shoved off to the side of the mainstream tech media in 2023 because of the incredible tech hype and media storm around generative AI and natural language models, so any efforts at advancement here kinda got derailed. However, the generative AI hype wave caught up a few low-code/no-code entrants along the way, and now you can &lt;a href=&quot;https://uizard.io/&quot;&gt;build workable prototypes from napkin sketches&lt;/a&gt;, apparently. (No word on what happens if these AI-powered prototypes have access to the Internet, though.)&lt;br /&gt;
By the way, those Boston Dynamics robots are getting closer and closer to mounting guns, regardless of what &lt;a href=&quot;https://bostondynamics.com/news/general-purpose-robots-should-not-be-weaponized/&quot;&gt;the manufacturer says&lt;/a&gt;, enough so that &lt;a href=&quot;https://www.boston.com/news/local-news/2023/09/13/mass-may-outlaw-attaching-guns-to-robots/&quot;&gt;states are considering outlawing them entirely&lt;/a&gt;. Because nothing stops a T-800 like a cease-and-desist order. (I kid, I kid. Actually, no, it&apos;s more &amp;quot;I cry, I cry&amp;quot;, because it&apos;s going to happen whether BD wants it to or not.)&lt;br /&gt;
&lt;strong&gt;+1&lt;/strong&gt; means &lt;strong&gt;Tally: +6&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;***Internal tech audits will become relatively popular.***&amp;quot; If it happened, everybody kept &lt;em&gt;reallllly&lt;/em&gt; quiet about it, which you would kinda expect. But if it didn&apos;t show up in the tech press, did it really happen? &lt;strong&gt;-1&lt;/strong&gt; means &lt;strong&gt;Tally: +5&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;***Muskian-style management will be studied, cargo-culted, and lead to the failure of more than one company.***&amp;quot; &lt;a href=&quot;https://www.amazon.com/Elon-Musk-Professional-leadership-Neuralink/dp/B08R8Y3RT3&quot;&gt;&lt;em&gt;groan&lt;/em&gt;&lt;/a&gt;. &lt;a href=&quot;https://www.amazon.com/Elon-Musk-Method-Principles-Entrepreneur/dp/1943386447&quot;&gt;&lt;em&gt;sigh&lt;/em&gt;&lt;/a&gt;. &lt;a href=&quot;https://www.simonandschuster.com/books/Elon-Musk/Walter-Isaacson/9781982181284&quot;&gt;Lord save me&lt;/a&gt;. &lt;strong&gt;+1&lt;/strong&gt; I hate that I was right about this one. &lt;strong&gt;Tally: +6&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;***2023 will be the year we try to figure out what to do with all this AI stuff.***&amp;quot; Nope. Nope, nope, nope, nope, nope. &lt;strong&gt;-1&lt;/strong&gt; We haven&apos;t even figured out the difference between natural language models and generative AI, or the copyright implications of training a model on copywrit sources, or... pretty much anything beyond &amp;quot;Slap some AI on it, and it will sell!&amp;quot;. We haven&apos;t figured anything out here, and it was horrendously naive of me to think we could in just a years&apos; time. &lt;strong&gt;Tally: +5&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;strong&gt;&lt;em&gt;BONUS PREDICTION: 2024 will be the year that we start putting AI into some of our apps--like using ChatGPT for chatbots--and 2025 will be the year that we start ripping it all back out because we completely got it wrong.&lt;/em&gt;&lt;/strong&gt; (We always do this. And I see no signs that we&apos;ll stop in my lifetime.)&amp;quot; OK, that one, I got right. But it was like candy from a baby--no points.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;***Companies will accelerate their drive to become &apos;tech companies&apos;.***&amp;quot; A fair number of firms continue their &amp;quot;technology transformation&amp;quot; efforts, but nobody&apos;s really any faster or slower--or better--at it than they were before. &lt;strong&gt;-1&lt;/strong&gt; This was probably complicated by....&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;***Hiring will accelerate at the end of 1Q/2023.***&amp;quot; I kinda think I should reset all my points back to 0, because holy crap, was I wrong about this. So deeply, incredibly, soul-wrenchingly wrong. A year ago, I actually wrote this: &amp;quot;Even as companies are engaging in layoffs, these aren&apos;t the savage cuts that we saw back in the Dot-Bomb era (circa 2001) or the Great Recession (circa 2008) era.&amp;quot; Maybe back in 2022 that was a reasonable take, but then 1Q/2023 came around, and all that went out the window as big firm after big firm just pruned at their org tree, and did it savagely. This &lt;a href=&quot;https://www.trueup.io/layoffs&quot;&gt;layoff tracker&lt;/a&gt; says it perfectly: &amp;quot;So far in 2023, there have been 1,992 layoffs at tech companies with 428,335 people impacted (1,183 people per day).&amp;quot; The graph shows 108,000+ in January 2023 alone. &lt;strong&gt;Tally: 0&lt;/strong&gt; So, so wrong.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;***Entry-level positions are going to be easier to come by.***&amp;quot; Ironically, this one actually seems to be taking shape. Even as a lot of companies laid off in 2023, many of them started hiring again almost immediately (2Q, 3Q), but almost exclusively for individual contributors (ICs) and many of those roles were entry-level positions. It still isn&apos;t a great job market by comparisons against the average from the 2010s, and definitely not by comparison against the pandemic era, but it&apos;s not hopeless if you&apos;re a tech IC right now. (Management, on the other hand.... that&apos;s where a lot of the struggle still lies.) I&apos;ll take the &lt;strong&gt;+1&lt;/strong&gt; since I&apos;m desperate for points now, bringing us to &lt;strong&gt;Tally: +1&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;***Platform-oriented development is going to begin making some waves.***&amp;quot; This one is a little tricky to judge. On the one hand, we can see companies developing platforms all over the place, particularly as exemplified by... well, pretty much every startup that&apos;s gotten a round of funding since 2019. But my prediction is a little vague, and speaking honestly, I was expecting to see a bit more of a &lt;em&gt;push&lt;/em&gt; from multiple places in the developer ecosystem, which didn&apos;t happen. So... &lt;strong&gt;-1&lt;/strong&gt; takes us to &lt;strong&gt;Tally: 0&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;***Cloud will begin to shift.***&amp;quot; Now, this one was interesting. When a major talking-head like DHH talks about &lt;a href=&quot;https://world.hey.com/dhh/we-have-left-the-cloud-251760fb&quot;&gt;moving &lt;em&gt;off&lt;/em&gt; the cloud&lt;/a&gt;, it sends waves, and sure enough, companies began to do the math and realize that cloud companies are charging them at rates that generate (surprise!) a profit... to the cloud company. &lt;strong&gt;+1&lt;/strong&gt; See, that was always going to be the endgame here, because while the &lt;a href=&quot;https://www.investopedia.com/insights/what-are-economies-of-scale/&quot;&gt;economy-of-scale&lt;/a&gt; graph does mean that you can generate more of a good/service per unit if you do it at larger amounts, that graph does eventually flatten out, and more importantly, multiple larger businesses began to realize that they were probably large enough to be able to take advantage of that same graph, themselves--once they&apos;d put the initial investment in, they could, in essence, run their own private cloud, and pay even less for it than going through Azure, AWS, GCP, or any of the others. &lt;em&gt;It will always be cheaper to make it yourself, once you&apos;ve put the investment in to be able to make it yourself at scale.&lt;/em&gt; It&apos;s the same reason McDonald&apos;s makes its own buns, beef, and vegetables--it&apos;s the technology equivalent of controlling your supply chain. &lt;strong&gt;Tally: +1&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Elon will sell Twitter (perhaps involuntarily) at the end of 2023, to another tech firm (like Microsoft or Oracle).&lt;/em&gt;&lt;/strong&gt; ... And that&apos;s how the grand MuskTwitter experiment will end. Not with a bang, but with a pathetic whimper.&amp;quot;*** Well, it&apos;s the end of 2023, and... checking... nope, Musk appears to have no intention of selling off Twitter-I-mean-X-sorry. But the quality of the Twitter timeline keeps dropping, my friends and follows (the people whose opinions and insights I respect enough to follow) are slowly dropping off as well, and I&apos;m about one more unsolicited DM from Nikki Haley away from doing so myself. So, first, I take a &lt;strong&gt;-1&lt;/strong&gt; on the prediction, but in the meantime, Musk continues to drain away everything that was actually good about Twitter. &lt;strong&gt;Tally: 0&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Meanwhile, alternatives to Twitter will continue to sprout up, but none will actually be able to be everything Twitter was, partly because Twitter was (at the time) unique in its approach to social media, and as a result it created a &amp;quot;perfect storm&amp;quot; that led the platform to its current (well, pre-Muskian) level of success. That will be nearly impossible to recreate.&amp;quot;&lt;/em&gt;&lt;/strong&gt; Yeah... &lt;strong&gt;+1&lt;/strong&gt;. Sorry, Mastodon, Threads, BlueSky, and every other Twitter clone that&apos;s been released in the last year, but none of you are showing me the critical mass of &amp;quot;interesting mess&amp;quot; that Twitter became. It used to be that people I followed were also commenting and RT&apos;ing on people they followed, and made it easier for me to find new and interesting voices to follow, and the clones all just don&apos;t seem to &amp;quot;get&amp;quot; that. I suspect, going forward, that before long my only social media presence will be LinkedIn and this blog, which will make me feel a little sad and alone, but frankly I&apos;ll probably feel a lot less depressed about the world around me once I do. &lt;strong&gt;Tally: -1&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;RSS will make a comeback.&amp;quot;&lt;/em&gt;&lt;/strong&gt; Nope. &lt;strong&gt;-1&lt;/strong&gt; It hasn&apos;t, and it probably never will by this point. Sorry, folks, but RSS is essentially dead as a protocol of widespread adoption beyond where it&apos;s already in use now. &lt;strong&gt;Tally: 0&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;In summary:&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;twenty-one predictions,&lt;/li&gt;
&lt;li&gt;a bunch of hits,&lt;/li&gt;
&lt;li&gt;a few fails but mostly a &lt;em&gt;massive&lt;/em&gt; fail,&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;... leaving me with what I consider to be a completely missed round. Yikes. (I am really annoyed at how wrongly I read the room this time last year on the job market--for personal reasons, yes, but also because I really do pride myself on my ability to do these sorts of professional forecasts, and that was a huge misread.)&lt;/p&gt;
&lt;div id=&quot;2024&quot; /&gt;
&lt;h1&gt;2024 Predictions&lt;/h1&gt;
&lt;p&gt;With that settled up, let&apos;s take a look at what I think will happen across calendar year 2024. As I&apos;ve done with my predictions, I&apos;m including a probability score with each one, in much the same way intelligence officials do in their assessment reports, to give you a sense of how confident I am in the prediction.&lt;/p&gt;
&lt;h4&gt;Hiring will open up. (Probability &lt;em&gt;p&lt;/em&gt; 0.8)&lt;/h4&gt;
&lt;p&gt;The interesting thing about the layoffs is that while they continue to trickle out from various companies all the way to December of 2023, it&apos;s a trickle compared to the flood that happened in 1Q, particularly in January. More interestingly, the &lt;em&gt;kinds&lt;/em&gt; of people that are going to be hired will shift slightly--right now (end of 2023), companies are focusing on hiring ICs to fit into existing holes in their current org tree. But with the new year, and a bit of optimism in the market, they&apos;ll start growing new branches to that tree, and that will require more in the way of engineering management and &amp;quot;ancillary units&amp;quot; like developer relations, R&amp;amp;D, and so on. It&apos;ll take a while, and it&apos;ll never be like 2019, but before too long things will get stronger.&lt;/p&gt;
&lt;h4&gt;WebAssembly will gain more traction. (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;I haven&apos;t really paid much attention to WebAssembly for the past few years, because I wasn&apos;t sure where things were going. The 1.0 specification is done, but it&apos;s pretty minimal compared to other richer, more full-featured virtual instruction sets (like the JVM or the CLR). Truthfully, it&apos;s a ridiculously bare-bones spec. But, even as I say this, there&apos;s some interesting infrastructure that&apos;s targeting LLVM more and more (most notably LLVM and GraalVM), making it easier and easier for WASM to gently &amp;quot;slide in&amp;quot; to a deeper role within a dev toolchain and do some interesting things. That said, though, WASM still has yet to really demonstrate where it&apos;s real value lies--why write something to WASM binary, which generally means targeting the browser, when there&apos;s so many Javascript-centric options already? Where&apos;s the compelling value-add from the developer perspective? This is the hinge on which WASM&apos;s broad-scale applicability matters: If WASM can show how using language-X-compiled-to-WASM enables a new kind of feature or a faster/easier workflow to get to &amp;quot;done&amp;quot;, then WASM could very well begin to emerge as the infrastructure backplane for browser-based applications all over the Internet. I don&apos;t know what that compelling reason is yet, though, which is why I leave this at a 0.5 &lt;em&gt;p&lt;/em&gt;.&lt;/p&gt;
&lt;h4&gt;Generative AI will lose its luster. (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;It already has started, in many ways--memes now are common across the Internet showing ChatGPT conversation windows in which it responds to the question, &amp;quot;How do I use GitHub?&amp;quot; with &amp;quot;In order to push code to the remote server, issue the command &lt;code&gt;git branch&lt;/code&gt;...&amp;quot; in a completely erroneous and mistake-riddled answer. The stories of the lawyers who used ChatGPT to write legal briefs that turned out to be filled with inaccuracies and errors--for which they were disbarred, by the way--have cast some serious doubt on the ability of these generative AIs to &amp;quot;fire all the peons&amp;quot; whose work ChatGPT and its ilk were supposedly going to replace.&lt;/p&gt;
&lt;h4&gt;We will begin to disambiguate between generative AI and large language models (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;It happens with AI every decade or so--something new comes along, it takes our imagination by storm, and we start chanting &amp;quot;AI! AI! AI!&amp;quot; like an amped-up-on-booze-and-caffeine-pills crowd at a wrestling match. Then, as we get disenchanted with the results, the various AI firms--who have yoked their success to the success of their AI work--will start to point out that they were never &amp;quot;AI&amp;quot; companies, they were &amp;quot;large language model&amp;quot; companies and therefore never a part of the hype machine that&apos;s now augering in.&lt;/p&gt;
&lt;h4&gt;Custom AI models will begin to gain traction. (&lt;em&gt;p&lt;/em&gt; 0.6)&lt;/h4&gt;
&lt;p&gt;Making use of a large company&apos;s model for your natural language analysis needs is great, but over time, companies are going to figure out that the cost of that model will probably be smaller if it can be hosted locally, rather than constantly going to the cloud and back again. (See the economies-of-scale discussion earlier, as well as the performance and reliability implications, a la &amp;quot;The Eight Fallacies of Distributed Computing&amp;quot;.) Slowly, quietly, companies with some room in their budgets are going to start looking to develop their own models, and in many cases may find that the model&apos;s they&apos;re building don&apos;t need to be quite so large (and heavy), that in fact a &amp;quot;medium&amp;quot; language model, or even a &amp;quot;small&amp;quot; language model would work, allowing for a local presence on the same node as the rest of the processing. OpenAI and other firms are going to combat this by constantly releasing new models with new excitement and fanfare, but like the cloud itself, the basic path here will be &amp;quot;start with the hosted LLM, then as your success and budget grows, look to build--and tune--your own&amp;quot;. It&apos;ll be &amp;quot;Buy vs Build&amp;quot; decision-making, all over again.&lt;/p&gt;
&lt;h4&gt;New and interesting languages will begin to make waves. (&lt;em&gt;p&lt;/em&gt; 0.6)&lt;/h4&gt;
&lt;p&gt;I&apos;ve been saying this for years, but I keep holding out hope. Frankly, I think some of the development will be to raise the abstraction levels of what we do, because ChatGPT&apos;s success at writing code is due to the fact that 95 times out of 100, we&apos;re writing the same basic CRUD crap over and over and over again. The Pareto Principle holds here: 80% of all mobile applications (as an example) are doing the same stuff, it&apos;s just that it&apos;s a different 80% from all the rest. A language/stack that can embrace an onion-style architectural approach (allowing for &amp;quot;trap doors&amp;quot; to drop down a level of abstraction when/if necessary, such as how C/C++ allowed for inline assembly way back in the day) will be the answer here.&lt;/p&gt;
&lt;p&gt;The other element I imagine will/could be interesting to explore will be the intersection of what natural language models and compiler front-ends will look like--if we can get a language to start looking more like a natural language, it might enable some interesting DSL-type scenarios for end-users, and reduce the demands/pressures on developers to respond to every little change.&lt;/p&gt;
&lt;h4&gt;Cracks in the &amp;quot;full-stack developer&amp;quot; facade will grow. (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;The demand for the &amp;quot;full-stack developer&amp;quot; is mostly a cop-out on the part of managers, who don&apos;t want to artificially restrict their employee search because &amp;quot;hiring is hard&amp;quot;. So, instead of carefully considering what skills the current team lacks that needs shoring up, they instead scribble &amp;quot;full stack developer&amp;quot; on the job description, and proceed to rattle off every single technology that the team has ever used.&lt;/p&gt;
&lt;h4&gt;AR/VR will start showing glimmers of life (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;If AR/VR is going to achieve anything of any substantial value, it really needs to do so soon, before it is relegated to the &amp;quot;Interesting Things That Were Out Of Their Time&amp;quot; bin, like the Apple Newton and the Xerox PARC. This year might--&lt;em&gt;might&lt;/em&gt;--be the year it presents us with something, particularly given the rise in interest in wearables. Certainly, with Meta going all-in on the whole &amp;quot;Metaverse&amp;quot; thing (whoever came up with that should be fired), there&apos;s going to be no shortage of money thrown at the problem, the big question is, will there be any actual innovation around UI? Because so long as the AR/VR thing is solely game-centric, it&apos;s fairly safe to assume that the AR/VR will go right into that bin without too much hesitation. I know, games are huge industry (measured in the trillions now?), but it&apos;s not enough to support hardware; witness the difficulties even conventional gaming hardware (for example, joysticks--today&apos;s flight sims are vastly more complicated than the ones twenty years ago, yet nary a joystick to be found) has had over the decades. If AR/VR (which requires hardware specific to it) is going to reach a point that justifies buying specific hardware for it, it has to be for something more than just gaming (and please don&apos;t say &amp;quot;education&amp;quot;, because if there&apos;s one place in the world that has almost no budget, it&apos;s education).&lt;/p&gt;
&lt;h4&gt;&amp;quot;Car apps&amp;quot; will begin to become &amp;quot;a thing&amp;quot; (&lt;em&gt;p&lt;/em&gt; 0.6)&lt;/h4&gt;
&lt;p&gt;More and more vehicles out there are coming with computers in the console, offering easy connection to your mobile device. What&apos;s been lacking has been any sort of apps for it, beyond the basics (maps, audio entertainment, etc). Now that there&apos;s more of a target market, perhaps we are reaching a critical mass of potential customers to justify the investment in building apps specificall for vehicles.&lt;/p&gt;
&lt;p&gt;If this does start to take hold, it will be interesting to see what sorts of apps get built (I could imagine some CRM apps for certain kinds of salespeople, for example) and what form user interaction takes hold (voice control and interaction would be very important for drivers, for example). Frankly, though, the hard part will be the core innovation itself--what sort of apps do we want when we&apos;re driving?&lt;/p&gt;
&lt;h4&gt;Kotlin will remain an &amp;quot;Android-only&amp;quot; language (&lt;em&gt;p&lt;/em&gt; 0.5)&lt;/h4&gt;
&lt;p&gt;This one is a hard one to call, but I&apos;m flipping a coin and landing on the pessimistic side of the &amp;quot;Will Kotlin break out of Android-only?&amp;quot; question. For those who weren&apos;t following the Kotlin story at home, Kotlin has recently done a couple of things to make it more than just &amp;quot;that language you use for Android&amp;quot; by developing &lt;a href=&quot;https://kotlinlang.org/docs/multiplatform-get-started.html&quot;&gt;Kotlin Multiplatform&lt;/a&gt; and &lt;a href=&quot;https://kotlinlang.org/docs/native-overview.html&quot;&gt;Kotlin Native&lt;/a&gt;. These open up the Kotlin language for use in more situations, but their success will really hinge on how many developers actually &lt;em&gt;want&lt;/em&gt; to use Kotlin in more places than just their Android codebase.&lt;/p&gt;
&lt;p&gt;Historically, multiplatform languages have not done well, with the sole (arguable) success being that of Java--whose &amp;quot;Write once, run anywhere&amp;quot; campaign didn&apos;t really accomplish much. (Remember, most of Java&apos;s success was in the server room, not the desktop.) Native might have more possibility for success, but either one gaining any traction would be an interesting development and potentially grow Kotlin beyond just &amp;quot;an Android thing&amp;quot;.&lt;/p&gt;
&lt;h4&gt;C# and Java will continue to &amp;quot;pile on&amp;quot; with features (&lt;em&gt;p&lt;/em&gt; 0.8)&lt;/h4&gt;
&lt;p&gt;Both languages have reached a point where the weight of the language is really beyond the ability of any one person to keep track of what&apos;s there, yet each time a new release comes out, it comes with a whole slew of new proposed features designed to bring new syntax into an already-existing part of the language or an attempt to cram yet-another-interesting-idea into an already &amp;quot;overloaded-collection-of-features&amp;quot;-oriented language. (Can you really look at either C# or Java and tell me that they are &amp;quot;object&amp;quot;-oriented anymore? You can go quite a ways with either and never see or hear an object anywhere along the way by this point.)&lt;/p&gt;
&lt;p&gt;Look, maybe this is my &amp;quot;Gitoffamahlawn&amp;quot; moment to these predictions, but both of these languages are old enough to drink, they each spun up powerful and resilient platforms that have a number of newer, simpler, more-concise languages, and at a certain point in time, it&apos;s reaasonable to say, &amp;quot;This one is done. There&apos;s nothing new we need to add.&amp;quot; To keep cramming new stuff in is a terrible addiction--it&apos;s a way to show that &amp;quot;We&apos;re still hip! We&apos;re still doing cool stuff (...and therefore justify why companies should still be paying us license fees!)&amp;quot; We keep &lt;a href=&quot;https://medium.com/swlh/stop-adding-new-features-to-your-product-bed86aa5114&quot;&gt;telling startups&lt;/a&gt; &lt;a href=&quot;https://www.komododigital.co.uk/insights/feature-addiction-can-ruin-a-digital-product/&quot;&gt;not to do it&lt;/a&gt;, but our two major providers of software development tools can&apos;t seem to get the lesson themselves.&lt;/p&gt;
&lt;p&gt;Spend some time with F#. With Clojure. With Kotlin. Play with some of the new ideas (Mint, Wasp, Io, Alloy). Or even go back and experiment with some of the classics (Smalltalk, Self, LISP, Scheme). But, for your own sake, stop enabling the relentless pounding of the feature surf on the beach of your brain by breathlessly hanging on &amp;quot;What comes next&amp;quot;, because in time, you&apos;ll be battered into sand.&lt;/p&gt;
&lt;h4&gt;Crypto falls even further. Blockchain struggles to reinvent. (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;Look, faith in cryptocurrency is really at an all-time low, except for the people who are caught holding the bottom of the Ponzi pyramid, and they desperately want to hype the hell out of it so they can pass the bag on to the next level down. That won&apos;t change. Blockchain, the world&apos;s worst-designed distributed database, will continue to wrestle with the goal of finding a reason to exist, and hey, could maybe even find one bullseye, given enough darts. (Many companies that invested in Blockchain have either decided to walk away from the dartboard or else that they&apos;re going to load up on a &lt;em&gt;lot&lt;/em&gt; of darts--and maybe a shotgun or two--until they hit that bullseye.)&lt;/p&gt;
&lt;p&gt;I really would love for these two to just go away entirely, but they won&apos;t, because nothing ever dies completely. But this is the last year they&apos;re going to get much--if any--serious time in the tech press, despite the fevered efforts of a precious few on LinkedIn. (Yes, Andreeson-Horowitz is going big into it; yes, they&apos;ve been big into it since it&apos;s start; yes, there will always be people who see what they want to see, instead of following actual evidence; and yes, folks, there&apos;s still time to dive in and turn your profit, just don&apos;t be the last one holding the pyramid up!)&lt;/p&gt;
&lt;p&gt;And, for me, 2024 will be the last year I talk about this in any form.&lt;/p&gt;
&lt;h4&gt;Phishing attacks go ballistic (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;Thanks, AI! With all these generative natural language tools (like ChatGPT), it will be easier than ever to generate emails intended to trick users into surrendering their credentials to fake sites. That will lead to more breaches, more private info leaks, and more of all the wonderful things that come with those.&lt;/p&gt;
&lt;p&gt;What will make it even worse will be all the security companies that roll out &amp;quot;AI-based&amp;quot; security tools, claiming that the AI will somehow be able to better protect against those very same attacks--but while generative AI can create really good-looking human-facsimile output, it&apos;s not always great at recognizing artificially-created human-facsimile input. Which means the attackers just got a boost to their toolset, and the defenders will be looking to try and keep up this year.&lt;/p&gt;
&lt;h4&gt;Databases will incrementally improve (&lt;em&gt;p&lt;/em&gt; 0.7)&lt;/h4&gt;
&lt;p&gt;... as opposed to releasing something drastic. There is some interesting ideas percolating over in the world of &lt;a href=&quot;https://dbos-project.github.io/&quot;&gt;DBOS&lt;/a&gt;, spearheaded by one of the principals in the Postgres world, but I have a feeling that it&apos;ll take a little bit for those ideas to brew before there&apos;s really something there to evaluate. (Hope I&apos;m wrong, though.)&lt;/p&gt;
&lt;p&gt;Meanwhile, though, players in the RDBMS world will slip a new feature into the mix by polluting the relational model just that wee bit more, the NoSQL players will pick just a tiny bit more from the relational world and add that, and developers will continue to choose which player they want to play with based on criteria that touches maybe 1% of the feature set of the player they choose.&lt;/p&gt;
&lt;h4&gt;I&apos;m publishing a book (&lt;em&gt;p&lt;/em&gt; 0.8)&lt;/h4&gt;
&lt;p&gt;I and a few other folks are working on a book based on the Developer Relations Activity Patterns catalog that I drafted a ways back, expanding on the material there in a big way. That&apos;ll come out in 2024, &lt;em&gt;almost&lt;/em&gt; guaranteed.&lt;/p&gt;
&lt;p&gt;Fifteen predictions for the next twelve months. Let&apos;s see how I do this time.&lt;/p&gt;
&lt;p&gt;Talk to you all next year... if not sooner.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Tabletop RPG IT</title>
      <link>http://blogs.newardassociates.com/blog/2023/rpg-it.html</link>
      <pubDate>Mon, 4 Sep 2023 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2023/rpg-it.html</guid>
      	<description>
	&lt;p&gt;With the enforced hiatus I&apos;ve been on for the past 18 momths, I&apos;ve had some opportunities to engage in a few projects that otherwise would&apos;ve gone undone or unexeplored. One of these projects is actually indulging in a favorite pastime of mine: TableTop Role-Playing Games (or TTRPGs, for short), which I&apos;ve enjoyed since 1978. As somebody who runs a TTRPG campaign for some of my friends, I find that wading through piles of books, some of which deprecate material found in another, to be really, really ancient and antiquated, and the IT professional in me says, &amp;quot;There&apos;s got to be a better way.&amp;quot;&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Let me take a few moments to spin up the context: I&apos;ve been an avid TTRPG (tabletop role-playing game, as in D&amp;amp;D or Pathfinder, sitting around a table with friends, as opposed to video gaming versions thereof) player since 1978, when I got the &amp;quot;blue box&amp;quot; edition of D&amp;amp;D. When the pandemic started, some college buddies thought it would be a good opportunity to do some online gaming, and I offered to GM.&lt;/p&gt;
&lt;p&gt;For me, that meant an opportunity to exercise my creativity, as I&apos;ve always preferred to run campaigns out of my own worlds, rather than using the prepackaged ones that come from the vendors. This would be no different, largely because I wanted to provide a world that was tailored (somewhat) to what my players would be interested in, but also allow me some room to deviate from the traditional and explore some new ideas. For example, I&apos;ve come recently to realize that &amp;quot;players&amp;quot; and &amp;quot;monsters&amp;quot; aren&apos;t all that different from one another, aside from history, so I&apos;ve come to embrace the idea of &amp;quot;monstrous player characters&amp;quot;; you want to run a minotaur barbarian? Go for it! Kobold sorcerer? Why not? Orcish cleric of healing? Makes total sense.&lt;/p&gt;
&lt;p&gt;This also means I like to make use of other homebrewed content, such as what one might find on &lt;a href=&quot;&quot;&gt;DM&apos;s Guild&lt;/a&gt; or &lt;a href=&quot;&quot;&gt;RPGDriveThru&lt;/a&gt;, but that raises an interesting problem: with all the different sources, it can be awkward to reconcile them all, meaning either I the GM have to have every sourcebook and homebrew document ever used anywhere, or I have to have some way of creating a &amp;quot;single source of truth&amp;quot; for the different content in my game. Spells, creatures, races, classes, all of it has to be in one place so I only have one place I need to consult to keep track of it all.&lt;/p&gt;
&lt;p&gt;Enter GitHub.&lt;/p&gt;
&lt;h3&gt;Source Control&lt;/h3&gt;
&lt;p&gt;Although it&apos;s most often used for source code management across versions, tools like Git and the like can be used to keep versions of anything (including binaries, though less effectively), and I&apos;ve long used Git for holding copies of all of my professional writing. This blog, for example, is completely inside a Git repo--and, in fact, was at one point entirely CI/CD-driven. (It&apos;s not currently because I ran into some weird configuration issues with my Azure Website, and I haven&apos;t taken the time to fix it yet, instead choosing to use the uber-simplistic website-hosting provider &lt;a href=&quot;https://www.site44.com/&quot;&gt;Site44&lt;/a&gt;, which turns a Dropbox folder into a website root, perfect for static-site-generated sites like this one.)&lt;/p&gt;
&lt;p&gt;So, &lt;a href=&quot;https://github.com/tedneward/Azgaarnoth&quot;&gt;the Github repository for my world&lt;/a&gt; was born. I found a pretty nifty world map editor to create the world in, generated one with a nice mix of land and sea (I like having worlds with a good mix of both, because that opens up more varied adventuring possibilities), and lo! The world of Azgaarnoth was born. (The editor is called &amp;quot;Azgaar&apos;s World Editor&amp;quot;, so I just borrowed the first part of the editor name--seemed like a reasonable homage to me.) All of the files are written in Markdown, and the built-in VSCode editor in every GitHub repo means that if I can access the page (and log in), I can edit it right there in the browser, or I can work with it offline on a laptop for more heavy-duty editing.&lt;/p&gt;
&lt;p&gt;First steps were to lay out some basic history (8,000 years of it!) and geography, which meant taking some of what the map editor had generated for me, creating some points of conflict (this part of the world started as a single empire, then had a massive invasion by foreign entities, which stalemated) extracting some consequences across history (with no quick conquest or defeat of the invader, people got frustrated which led to civil breakaways from the empire), and laying out some rough guidelines.&lt;/p&gt;
&lt;p&gt;But.... there&apos;s more I wanted to do. &amp;quot;Single source of truth&amp;quot; really means &amp;quot;single&amp;quot; in my mind, and that holds for some game-system information (such as races and classes) as well as the world-specific stuff. So I created some Markdown versions for races and classes, which wasn&apos;t all that hard. But I also wanted to have a complete reference for every spell and creature and magic item in the world.&lt;/p&gt;
&lt;h3&gt;The GM&apos;s Spellbook&lt;/h3&gt;
&lt;p&gt;Spells are one particular point of fun, because while the core D&amp;amp;D 5th Edition rules has a pretty decent collection, there&apos;s always room for more, particularly if you want to bring some fun flavor that the players haven&apos;t seen before. (And my group, we&apos;ve all been playing since a young age, so it&apos;s often quite the stretch to bring something they&apos;ve never seen before.) This meant bringing all of the core spells into Markdown format, but also all of the homebrew and 3rd-party purchased content as well, most of which is distributed as a PDF. But I also want to be able to sort through it all without too much difficulty, too.&lt;/p&gt;
&lt;p&gt;And here&apos;s where things get interesting. A given spell has a lot of interesting metadata on it beyond its name: its level, the &amp;quot;kind&amp;quot; of spell it is (illusion, divination, etc), the classes that can cast it, and so on. Any one of these could be used to organize the master list of spells, but the truth is they&apos;re all going to be useful at some point.&lt;/p&gt;
&lt;p&gt;Sounds like a database to me!&lt;/p&gt;
&lt;p&gt;But truthfully, I didn&apos;t want to build this on top of an existing database like Postgress or MySQL; for starters, the RDBMS doesn&apos;t really &amp;quot;fit&amp;quot; with storing what is essentially a text document with a few fields of metadata around it, and if I moved all the content into the RDBMS from GitHub, I lose the &amp;quot;quick editing&amp;quot; ability that GitHub provides, &lt;em&gt;plus&lt;/em&gt; now anybody who wants to edit or add new spells to the list has to be SQL-trained to do it (or I have to build an editor). I kinda still want the source of truth to be GitHub, rather than a more formal RDBMS.&lt;/p&gt;
&lt;p&gt;Actually, why not leave GitHub as the database? Each entry is a Markdown file with predetermined blocks in it for various data elements (&amp;quot;Duration&amp;quot;, &amp;quot;Casting Time&amp;quot;, etc), with each of those elements identified by being bolded in Markdown format. Since each spell needs to be uniquely named, that becomes the &amp;quot;primary key&amp;quot; for the spell, stored in a flat list (directory). Thus, a spell looks like the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#### Magic Missile
*1st-level evocation* (Sorcerer,Wizard)
___
- **Casting Time:** 1 action
- **Range:** 120 feet
- **Components:** V, S
- **Duration:** Instantaneous
---
You create three glowing darts of magical force. Each dart hits a creature of your choice that you can see within range. A dart deals 1d4 + 1 force damage to its target. The darts all strike simultaneously, and you can direct them to hit one creature or several.

***At Higher Levels.*** When you cast this spell using a spell slot of 2nd level or higher, the spell creates one more dart for each slot level above 1st.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... and is stored in &lt;code&gt;magic-missile.md&lt;/code&gt;. So long as the formatting doesn&apos;t deviate from the above, I have some easy parsing markers to work from.&lt;/p&gt;
&lt;p&gt;Now, I need some kind of tool that knows how to parse these into a form that can be manipulated and queried. Let&apos;s be honest--any language would&apos;ve worked for this (the parsing here is not complicated, and each spell is essentially a flat record), so I decided to go with Python because why not?&lt;/p&gt;
&lt;p&gt;Thus was born &amp;quot;SpellTool&amp;quot;: a Python script that rips through a directory filled with these Markdown files, parses each into its own &amp;quot;Spell&amp;quot; object, and allows for some predetermined sorting (such as finding all the spells that can be cast by Sorcerers) and output. It&apos;s not a full-fledged database (I can&apos;t do ad-hoc queries on it--yet), but it&apos;s not that far off from it. Obviously it&apos;s not nearly as fast or storage-efficient as a B-tree-based system would be, but it&apos;s also directly editable by myself or other &amp;quot;domain experts&amp;quot;, which is every bit as valuable, if not more so.&lt;/p&gt;
&lt;p&gt;But the Python fun doesn&apos;t quite stop there.&lt;/p&gt;
&lt;h3&gt;Enter Mkdocs&lt;/h3&gt;
&lt;p&gt;One thing I found from my players is that as much as &lt;em&gt;I&lt;/em&gt; love the GitHub interface, they were a little less fond of it. Honestly, that&apos;s not unreasonable--GitHub was not designed for the casual individual. Plus, the URLs that GitHub was putting up for each of the spells was... clunky. And truthfully, the Markdown format is not the easiest thing in the world to read if you&apos;re not familiar with it. (It&apos;s not &lt;em&gt;hard&lt;/em&gt; to read, mind you, just... awkward.) All of this goes away if I convert the Markdown to HTML and put it all on a simple website (such as the aforementioned Site44).&lt;/p&gt;
&lt;p&gt;Fortunately, Python has a great tool, MkDocs, which was obviously intended as a documentation management tool for Python libraries, but it serves my purposes perfectly well, since it takes a collection of Markdown files, transforms each into HTML, but also recognizes relative links and honors them. Plus, any links that don&apos;t seem to line up with an actual file are flagged during the process (since they&apos;ll likely be a broken link after the translation is done), giving me some &amp;quot;compile-time warnings&amp;quot; along the way.&lt;/p&gt;
&lt;p&gt;The results, by they way, are what&apos;s on &lt;a href=&quot;http://azgaarnoth.tedneward.com&quot;&gt;the website&lt;/a&gt; now. If you&apos;ve ever spent any time looking at Python docs, you&apos;ll recognize the format instantly, and the &amp;quot;Next/Previous&amp;quot; links are pretty broken, but I can either live with it as-is, or figure out how to customize or turn those off later.&lt;/p&gt;
&lt;h3&gt;Enter npctool&lt;/h3&gt;
&lt;p&gt;The most recent thing I&apos;ve wanted to do (for years, actually) is create a tool that generates NPCs (non-player characters) for use during the campaign. After all, why should players be the only ones with all the goodies (in the form of special abilities, spells, and so on)? Some of my most successful campaigns have been because the PCs are standing against a villain who is sporting some of the same kinds of abilities as they are.&lt;/p&gt;
&lt;p&gt;But as the players get higher in level, quickly putting together an NPC that&apos;s their peer (or superior) is tricky, because the game system is really expecting that you painstakingly craft each level of experience. Most GMs just &amp;quot;fake it&amp;quot; or hand-roll an NPC and use that singular NPC for a while. Me, I like having a fair number of them, partly because it&apos;s reasonable to expect that PCs will have more than just one nemesis across their careers, but also because it keeps things varied and interesting to have some different &amp;quot;feels&amp;quot; in the campaign. For example, in the current campaign, the first adventure was the party had to go up against a would-be lich who swiped the lair of a real lich. (Lots of undead.) The second adventure saw the PCs going out to a recent shipwreck to rescue an item before it was lost. (Lots of seaborn creatures.) Each had some different NPCs involved, but you can bet that as we move into the third adventure, the NPCs who weren&apos;t outright killed in each adventure are figuring out how to &amp;quot;get back at&amp;quot; the PCs.&lt;/p&gt;
&lt;p&gt;In essence, what I needed was a tool that could quickly rip through each level of an NPC&apos;s career, answering whatever customization questions that arose, and when the NPC was &amp;quot;finished&amp;quot;, calculate all the necessary &amp;quot;to hit&amp;quot; and damage and other level-variable calculations ahead of time. Thus was born the &amp;quot;NPCBuilder&amp;quot;, another Python script that will generate NPCs either interactively or from a simple text script:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Decide which?
1: Ability Scores
2: Gender
3: Race
&amp;gt;&amp;gt;&amp;gt; 1
You chose Ability Scores
Method:
1: Standard (&amp;lt;function generatenpc.&amp;lt;locals&amp;gt;.selectabilities.&amp;lt;locals&amp;gt;.standard at 0x1074d8900&amp;gt;)
2: NPC (&amp;lt;function generatenpc.&amp;lt;locals&amp;gt;.selectabilities.&amp;lt;locals&amp;gt;.npcstandard at 0x1074d8860&amp;gt;)
3: Hand (&amp;lt;function generatenpc.&amp;lt;locals&amp;gt;.selectabilities.&amp;lt;locals&amp;gt;.handentry at 0x1074d8ae0&amp;gt;)
4: Randomgen (&amp;lt;function generatenpc.&amp;lt;locals&amp;gt;.selectabilities.&amp;lt;locals&amp;gt;.randomgen at 0x1074d8a40&amp;gt;)
5: Average (&amp;lt;function generatenpc.&amp;lt;locals&amp;gt;.selectabilities.&amp;lt;locals&amp;gt;.average at 0x1074d89a0&amp;gt;)
&amp;gt;&amp;gt;&amp;gt; 5
You chose (&apos;Average&apos;, &amp;lt;function generatenpc.&amp;lt;locals&amp;gt;.selectabilities.&amp;lt;locals&amp;gt;.average at 0x1074d89a0&amp;gt;)
Decide which?
1: Gender
2: Race
&amp;gt;&amp;gt;&amp;gt; 1
You chose Gender
Choose gender: 
1: Female
2: Male
&amp;gt;&amp;gt;&amp;gt; 2
You chose Male
Decide which?
1: Race
&amp;gt;&amp;gt;&amp;gt; 1
You chose Race
Choose a race: 
1: Siren (&amp;lt;module &apos;Sirens&apos;&amp;gt;)
2: Kobold (&amp;lt;module &apos;Kobolds&apos;&amp;gt;)
3: Dwarf (&amp;lt;module &apos;Dwarves&apos;&amp;gt;)
4: Reborn (&amp;lt;module &apos;Reborn&apos;&amp;gt;)
5: Half-Ogre (&amp;lt;module &apos;Half-Ogres&apos;&amp;gt;)
6: Elf (&amp;lt;module &apos;Elves&apos;&amp;gt;)
7: Tabaxi (&amp;lt;module &apos;Tabaxi&apos;&amp;gt;)
. . .
33: Sahuagin (&amp;lt;module &apos;Sahuagin&apos;&amp;gt;)
34: Triton (&amp;lt;module &apos;Tritons&apos;&amp;gt;)
35: Genasi (&amp;lt;module &apos;Genasi&apos;&amp;gt;)
&amp;gt;&amp;gt;&amp;gt; 6
You chose (&apos;Elf&apos;, &amp;lt;module &apos;Elves&apos;&amp;gt;)
Subrace: 
1: Dark (&amp;lt;module &apos;Elf-Dark&apos;&amp;gt;)
2: Bright (&amp;lt;module &apos;Elf-Bright&apos;&amp;gt;)
3: Shadow (&amp;lt;module &apos;Elf-Shadow&apos;&amp;gt;)
4: Wood (&amp;lt;module &apos;Elf-Wood&apos;&amp;gt;)
5: Shadowmark (&amp;lt;module &apos;Elf-Shadowmark&apos;&amp;gt;)
6: High (&amp;lt;module &apos;Elf-High&apos;&amp;gt;)
7: Winged (&amp;lt;module &apos;Elf-Winged&apos;&amp;gt;)
8: Fey (&amp;lt;module &apos;Elf-Fey&apos;&amp;gt;)
9: Sea (&amp;lt;module &apos;Elf-Sea&apos;&amp;gt;)
10: Wild (&amp;lt;module &apos;Elf-Wild&apos;&amp;gt;)
&amp;gt;&amp;gt;&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The scripted version is essentially a simple &amp;quot;pipe&amp;quot; of answers to the prompts that come up, so that generating an NPC along particular lines (say, an 8th-level Sahuagin Cleric of the Tempest Domain) can be generated by using the following script:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Ability Scores,Hand,13,11,12,12,13,9,Race,Sahuagin,Cleric,Medicine,Religion,Tempest,Yes
Cleric,Yes
Cleric,Yes
Cleric,WIS,CON,Yes
Cleric,Yes
Cleric,Yes
Cleric,Yes
Cleric,WIS,CON,No
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... where each &amp;quot;Yes&amp;quot; at the end of the line is the answer to the prompt &amp;quot;Do you want to add another level?&amp;quot;. The above script, then, produces the following output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;### Name
*Medium humanoid (Sahuagin) Cleric (Tempest) 8, any alignment*
&amp;gt;___
&amp;gt;- **Armor Class** 10 (DEX (+0))
&amp;gt;- **Hit Points** 55 (8d8 + 8)
&amp;gt;- **Speed** 20 ft, swimming 40 ft
&amp;gt;___
&amp;gt;|**STR**|**DEX**|**CON**|**INT**|**WIS**|**CHA**|
&amp;gt;|:-:|:-:|:-:|:-:|:-:|:-:|
&amp;gt;|15 (+2)|11 (+0)|14 (+2)|12 (+1)|16 (+3)|9 (-1)|
&amp;gt;___
&amp;gt;- **Proficiency Bonus** +4
&amp;gt;- **Saving Throws** Wis +7,Cha +3
&amp;gt;- **Damage Vulnerabilities** 
&amp;gt;- **Damage Resistances** 
&amp;gt;- **Damage Immunities** 
&amp;gt;- **Condition Immunities** 
&amp;gt;- **Skills** Medicine +7, Religion +5
&amp;gt;- **Proficiencies** Light armor,Medium armor,Shields,Simple weapons,Martial weapons,Heavy armor
&amp;gt;- **Senses** darkvision 60 ft, blood 20 ft, passive Perception 13
&amp;gt;- **Languages** Common,Sahuagin,Aquan
&amp;gt;___
&amp;gt;***Blood Frenzy.*** You have advantage on melee attack rolls against any creature that doesn&apos;t have all its hit points.
&amp;gt;
&amp;gt;***Limited Amphibiousness.*** You can breathe air and water, but need to be submerged at least once every 8 hours to avoid dehydration. For each 8 hours period you do not submerge, you suffer one additional level of exhaustion.
&amp;gt;
&amp;gt;***Shark Telepathy.*** You can communicate simple ideas with sharks. They may understand you, but you have no way of understanding them.
&amp;gt;
&amp;gt;***Blood in the Water.*** Your specialized sense of smell can detect blood. You are aware of creatures within 20 feet that have hit points below their maximum, and can bleed. When in water, this range extends to 60 feet.
&amp;gt;
&amp;gt;***Channel Divinity: Destructive Wrath.*** When you roll lightning or thunder damage, you can use your Channel Divinity to deal maximum damage, instead of rolling.
&amp;gt;
&amp;gt;***Thunderous Strike.*** When you deal lightning damage to a Large or smaller creature, you can also push it up to 10 feet away from you.
&amp;gt;
&amp;gt;***Channel Divinity (2/Recharges on short or long rest).*** See below for the details of each use.
&amp;gt;
&amp;gt;***Divine Strike.*** Once on each of your turns when you hit a creature with a weapon attack, you can cause the attack to deal an extra 1d8 thunder damage to the target.
&amp;gt;
&amp;gt;#### Actions
&amp;gt;***Bite.*** Melee Weapon Attack: +6 to hit, reach 5 ft., one target. Hit: 1d4 + 2 piercing damage.
&amp;gt;
&amp;gt;***Channel Divinity: Turn Undead.***  You can use one of your uses of Channel Divinity to turn undead. Each undead that can see or hear you within 30 feet of you must make a Wisdom saving throw. If the creature fails its saving throw, if it is a CR of 1 or lower it is destroyed; otherwise it is turned for 1 minute or until it takes any damage.A turned creature must spend its turns trying to move as far away from you as it can, and it can&apos;t willingly move to a space within 30 feet of you. It also can&apos;t take reactions. For its action, it can use only the Dash action or try to escape from an effect that prevents it from moving. If there&apos;s nowhere to move, the creature can use the Dodge action.
&amp;gt;
&amp;gt;***Cleric Spellcasting (Wis, at level 8. Recharges on long rest).*** 4 cantrips known. 11 spells prepared. Spell save DC: 15, Spell attack bonus: +7
&amp;gt;
&amp;gt;Spells always prepared: [fog cloud](http://azgaarnoth.tedneward.com/magic/spells/fog-cloud/),[thunderwave](http://azgaarnoth.tedneward.com/magic/spells/thunderwave/),[gust of wind](http://azgaarnoth.tedneward.com/magic/spells/gust-of-wind/),[shatter](http://azgaarnoth.tedneward.com/magic/spells/shatter/),[call lightning](http://azgaarnoth.tedneward.com/magic/spells/call-lightning/),[sleet storm](http://azgaarnoth.tedneward.com/magic/spells/sleet-storm/),[control water](http://azgaarnoth.tedneward.com/magic/spells/control-water/),[ice storm](http://azgaarnoth.tedneward.com/magic/spells/ice-storm/)
&amp;gt;
&amp;gt;* *Cantrips:* 
&amp;gt;* *1st (4 slots):* 
&amp;gt;* *2nd (3 slots):* 
&amp;gt;* *3rd (3 slots):* 
&amp;gt;* *4th (2 slots):* 
&amp;gt;
&amp;gt;#### Reactions
&amp;gt;***Wrath of the Storm (3/Recharges on long rest).*** When a creature within 5 feet of you that you can see hits you with an attack, you can cause the creature to make a Dexterity saving throw (DC 15). The creature takes 2d8 lightning or thunder damage (your choice) on a failed saving throw, and half as much damage on a successful one.
&amp;gt;
&amp;gt;
&amp;gt;#### Bonus Actions
&amp;gt;***Sharks Frenzy (Recharges on short or long rest).*** You can make a special attack with your Bite. If the attack hits, it deals its normal damage, and you gain 2 temporary hit points. These temporary hit points disappear when you finish a long rest.
&amp;gt;
&amp;gt;***Channel Divinity: Harness Divine Power.*** You can expend a use of your Channel Divinity to regain one expended spell slot, the level of which can be no higher than 3.
&amp;gt;

#### Description
***Race: Sahuagin.*** A fish-like monstrous humanoid species that lives in oceans, seas, underground lakes, and underwater caves.

***Class: Cleric.*** Clerics are intermediaries between the mortal world and the distant planes of the gods. As varied as the gods they serve, clerics strive to embody the handiwork of their deities. No ordinary priest, a cleric is imbued with divine magic.

***Divine Domain: Tempest.*** 

***Magic Item: Uncommon Permanent.***

***Magic Item: Uncommon Permanent.***
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The magic items at the bottom are entirely level-based, as described by the 5th-ed DMG. As the GM, of course, I reserve the right to amp up (or down) the NPC&apos;s inventory as feels right, always keeping in mind, of course, that players love to loot the bodies of their fallen opponents. Spells are something I always figure I&apos;m going to want to decide post-creation, so I don&apos;t bother trying to assign (or prompt for) those ahead of time. The rest, though, that&apos;s all based on the various benefits of race (and subrace, if applicable) and class/subclass.&lt;/p&gt;
&lt;p&gt;Gleaned from where, you ask? Why, from the Markdown describing each race and class itself, of course.&lt;/p&gt;
&lt;h3&gt;Enter Literate Markdown&lt;/h3&gt;
&lt;p&gt;Before you start getting excited that I&apos;ve somehow built a Large Language Model for parsing Markdown and understanding 5th-ed D&amp;amp;D rules, let me cool you off ahead of time: Nope. Instead, I decided that the quickest/easiest thing would be to write those &amp;quot;rules&amp;quot; in Python. However, after a first effort where I painstakingly flipped between Python script and Markdown files, I realized I really wanted the Python script rules to be much &amp;quot;closer&amp;quot; to the code and vice versa, ideally, right next to each other.&lt;/p&gt;
&lt;p&gt;A number of years ago, Donald Knuth promoted a concept called &amp;quot;literate programming&amp;quot;, in which documentation and executable code were intermingled (&amp;quot;woven&amp;quot;) together into a single file. In most modern programming languages, we can have extensive documentation blocks that are essentially well-formatted comments (Javadocs, for example), but I wanted something of the opposite--documentation with well-formatted code blocks.&lt;/p&gt;
&lt;p&gt;Well, as it turns out, Markdown supports that, so in theory, I could do my own &amp;quot;Literate Python&amp;quot; if I could somehow get a Python interpreter to skip past everything that wasn&apos;t in a Markdown triple-backtick code block, like what we see here:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# [Orc](../Creatures/Orcs.md)

```
name = &apos;Orc&apos;
description = &amp;quot;***Race: Orc.*** &amp;quot;
type = &apos;humanoid&apos;
```

* **Ability Score Increase.** Your Strength score increases by 2, your Constitution score increases by 1, and your Intelligence score is reduced by 2.

```
def level0(npc):
    npc.description.append(&amp;quot;***Race: Orc.*** &amp;quot;)

    npc.STR += 2
    npc.CON += 1
    npc.INT -= 2
```

* **Age.** Orcs reach adulthood at age 12 and live up to 50 years.

* **Alignment.** Orcs are vicious raiders, who believe that the world should be theirs. They also respect strength above all else and believe the strong must bully the weak to ensure that weakness does not spread like a disease. They are usually chaotic evil.

* **Size.** Orcs are usually over 6 feet tall and weigh between 230 and 280 pounds. Your size is Medium.

```
    npc.size = &apos;Medium&apos;
```

* **Speed.** Your base walking speed is 30 feet.

```
    npc.speed[&apos;walking&apos;] = 30
```

* **Darkvision.** You can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can&apos;t discern color in darkness, only shades of gray.

```
    npc.senses[&apos;darkvision&apos;] = 60
```

* **Aggressive.** As a bonus action, you can move up to your speed toward an enemy of your choice that you can see or hear. You must end this move closer to the enemy than you started.

```
    npc.bonusactions.append(&amp;quot;***Aggressive.*** You can move up to your speed toward an enemy of your choice that you can see or hear. You must end this move closer to the enemy than you started.&amp;quot;)
```

* **Menacing.** You are proficient in the Intimidation skill.

```
    npc.skills.append(&amp;quot;Intimidation&amp;quot;)
```

* **Powerful Build.** You count as one size larger when determining your carrying capacity and the weight you can push, drag, or lift.

```
    npc.traits.append(&amp;quot;***Powerful Build.*** You count as one size larger when determining your carrying capacity and the weight you can push, drag, or lift.&amp;quot;)
```

* **Languages.** You can speak, read, and write Common and Orc.

```
    npc.languages.append(&amp;quot;Common&amp;quot;)
    npc.languages.append(&amp;quot;Orcish&amp;quot;)
```
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;My answer to this lies in the fact that Python, as a source-executable language, knows how to take source and turn it into an executable module; if I can figure out how to tap into that, I can write my own skimmed-down &amp;quot;loader&amp;quot; that knows how to parse a Markdown file, skip everything that&apos;s not in a code block, and take the result and feed it to the standard Python module-loading mechanism:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def loadmodule(filename, modulename=None):
    def parsemd(mdfilename):
        pythoncode = &amp;quot;&amp;quot;
        with open(mdfilename) as mdfile:
            lines = mdfile.readlines()
            codeblock = False
            for line in lines:
                if line[0:3] == &amp;quot;```&amp;quot;:
                    codeblock = not codeblock
                    continue

                if codeblock == True:
                    pythoncode += line

        if SAVEPY != None and SAVEPY in mdfilename:
            with open(&apos;./Python/&apos; + os.path.basename(mdfilename) + &apos;.py&apos;, &apos;w&apos;) as pyfile:
                pyfile.write(pythoncode)
        return pythoncode

    def builddict(module):
        global classes
        global races
        builtins = {
            &amp;quot;allclasses&amp;quot;: classes,
            &amp;quot;allraces&amp;quot;: races,
            &amp;quot;traits&amp;quot;: traits,
            &amp;quot;spelllinkify&amp;quot;: spelllinkify,
            &amp;quot;choose&amp;quot;: choose,
            &amp;quot;replace&amp;quot;: replace,
            &amp;quot;random&amp;quot;: randomlist,
            &amp;quot;dieroll&amp;quot;: dieroll,
            &amp;quot;min&amp;quot;: min,
            &amp;quot;len&amp;quot;: len,
            &amp;quot;print&amp;quot;: print,
            &amp;quot;types&amp;quot;: types
        }
        for (key, value) in builtins.items():
            module.__dict__[key] = value

    literatecode = parsemd(filename)
    if len(literatecode) &amp;gt; 0:
        if verbose: print(literatecode)
        if modulename == None:
            modulename = os.path.splitext(os.path.basename(filename))[0]
        module = types.ModuleType(modulename)
        builddict(module)
        exec(literatecode, module.__dict__)
        return module
    else:
        warn(f&amp;quot;{filename} has no literate code&amp;quot;)
        return None
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The heart of this &lt;code&gt;loadmodule&lt;/code&gt; function is in the &lt;code&gt;exec&lt;/code&gt; call five lines from the end--that&apos;s the Python3-preferred mechanism for transforming source into an executable module. Thus, this whole thing is broken up into three parts: the &lt;code&gt;parsemd&lt;/code&gt; nested function rips through a Markdown file and keeps only those lines inside the triple-backtick blocks, the &lt;code&gt;builddict&lt;/code&gt; function creates a dict (key-value pairs data structure) containing the &amp;quot;globals&amp;quot; that will be in scope when building this module, and the body of &lt;code&gt;loadmodule&lt;/code&gt; itself calls &lt;code&gt;parsemd&lt;/code&gt; to get the code, &lt;code&gt;builddict&lt;/code&gt; to build the globals (with my own set of top-level functions for each module to be able to rely on), creates a &lt;code&gt;ModuleType&lt;/code&gt; object into which to pour the executable code, and &lt;code&gt;exec&lt;/code&gt;s it.&lt;/p&gt;
&lt;p&gt;Voila. Literate Markdown.&lt;/p&gt;
&lt;p&gt;From here, I can have each race, subrace, class, subclass, and even feats and/or backgrounds be its own Python module. If I then couple some conventions (every module has a top-level &amp;quot;name&amp;quot; and &amp;quot;description&amp;quot; field, for example, along with &amp;quot;level&lt;em&gt;N&lt;/em&gt;&amp;quot; functions that define what that class or subclass does at level &lt;em&gt;N&lt;/em&gt;) with this, I have an interesting set of modular... er, modules... that independently describe how they affect an NPC at each discrete level of experience.&lt;/p&gt;
&lt;p&gt;And, if I add more classes (unlikely), races (distinctly possible), subclasses (very likely), or feats (also very likely), all I need to do is drop the literate Markdown into the appropriate directory, and my npcbuilder will pick them up automatically. (Note that if a given Markdown file has no code in it, I don&apos;t try to load it, and if there&apos;s a &amp;quot;SAVE_PY&amp;quot; environment variable set, I save the extracted Python in it for easier debugging.)&lt;/p&gt;
&lt;h3&gt;Current state and TODOs&lt;/h3&gt;
&lt;p&gt;The one thing I dislike about this so far (aside from the fact that I really wish that LLM did exist, so I wouldn&apos;t have to write out the literate code by hand!) is that now the descriptions are clogged with code blocks that appear in all the HTML. I think this is pretty easily fixable--MkDocs has hooks for &amp;quot;plugins&amp;quot;, which can customize the output, so I think I can write a plugin that discards all code blocks (since I don&apos;t need them, since this isn&apos;t a code project it&apos;s a D&amp;amp;D project).&lt;/p&gt;
&lt;p&gt;There&apos;s a few other things that I find myself wishing I had, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a city-generator tool (in progress) that will use some seed info and randomization to create the outlined sketch of each of the several-hundred-or-so cities I have on the map, not to mention the unmentioned thousands of towns and villages that aren&apos;t mentioned anywhere on the map.&lt;/li&gt;
&lt;li&gt;Each city, of course, has NPCs at various places within it, so of course I want to call out to my npctool to generate each of those. In fact, I kinda want to figure out how to tie all of these tools together more coherently into a well-oiled package, but I don&apos;t quite know (in my head) what that looks like or how they should work together.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But hey, I&apos;m not hired anywhere yet, so there&apos;s more to keep me busy.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Own, Collaborate, Inform</title>
      <link>http://blogs.newardassociates.com/blog/2023/oci.html</link>
      <pubDate>Mon, 4 Sep 2023 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2023/oci.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;tl;dr&lt;/em&gt; While having some conversations with a client, we got to talking about teams, processes, and how to partition work. I realized, as I was talking, that while RACI is a reasonable way of thinking about such things, it&apos;s a little complicated, and I prefer a slightly simpler model: OCI.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;For those who aren&apos;t familiar with RACI, it&apos;s an acronym that stands for &amp;quot;Responsible, Accountable, Consulted, Informed&amp;quot;, also known as a &amp;quot;Responsibility Area Matrix&amp;quot; in some circles. The idea is that for a given process or area of work (dare I say &amp;quot;value stream&amp;quot;), you line the individuals or the teams involved in a column on the left-hand-side, then across the top you create columns labeled &amp;quot;Responsible&amp;quot;, &amp;quot;Accountable&amp;quot;, &amp;quot;Consulted&amp;quot; and &amp;quot;Informed&amp;quot;.&lt;/p&gt;
&lt;p&gt;As you go through the different teams, or the different steps in a process, you examine the &amp;quot;players&amp;quot; in the left-most column, and determine whether they are responsible, accountable, consulted, or informed about the work being done. In essence, we are figuring out the degree of involvement around a given process or work, as part of coming to an understanding around who is doing what. (But not necessarily when--that adds a whole new dimension to the problem.)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;More thorough explanations can be found on &lt;a href=&quot;https://www.usemotion.com/blog/raci-chart&quot;&gt;Usemotion&lt;/a&gt; and &lt;a href=&quot;https://asana.com/resources/raci-chart&quot;&gt;Asana&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;My issue comes with some of the separation of the columns; specifically, I think it allows for too much overlap and conflates some concepts. Consider the eplanation of each of the four terms from the Usemotion blog (linked above):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Responsible&lt;/strong&gt; These are the individuals, pairs, or groups who do the work to complete the task or deliverable. Each task should have at least one responsible person.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Accountable&lt;/strong&gt; These are the individuals, pairs, or groups who delegate and review a team’s work. They are typically in a leadership or management role and ensure that the responsible person or team knows their expectations and completes the work on time. Each task should have only one “Accountable” person.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Consulted&lt;/strong&gt; These individuals provide input and feedback on the work being done. They have a stake in the outcome because it could affect their current or future work. Not every task needs a consulted person, but the project manager should consider all possible stakeholders when creating the RACI chart.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Informed&lt;/strong&gt; These are the individuals or groups that need to be kept up-to-date on the progress of a project but don’t need to be consulted for decision-making. They might include the heads or directors of teams or the senior leadership in a company.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But... who &amp;quot;owns&amp;quot; the thing?&lt;/p&gt;
&lt;h3&gt;Goals, Microservices, RACI, oh my&lt;/h3&gt;
&lt;p&gt;One of the things I&apos;ve discovered in my time managing teams and consulting to executives is that teams (and people within teams) function best when they have clear, distinct goals. Ideally, that should be a singlular noun: goal. When the team or the individual knows what they&apos;re doing such that it can describe it in a single sentence (without being a runon!), you have a much clearer sense of who&apos;s doing what.&lt;/p&gt;
&lt;p&gt;In short, this is called &amp;quot;ownership&amp;quot;, and it&apos;s a large part of what the whole microservices architectural model was trying to drive towards, what Amazon now refers to as a team being &amp;quot;single-threaded&amp;quot;: they own their inputs, they own their outputs, they own the maintenance, the whole nine yards. &amp;quot;No shared anything&amp;quot; is another way of referring to it. It has nothing to do with the size of the service, or the team, but whether they have a clear sense of what they work on.&lt;/p&gt;
&lt;p&gt;(By the way, that doesn&apos;t line up well to the use of single-function microservices at all well, does it? That&apos;s because the first use of the term &amp;quot;microservice&amp;quot; is more about organizational design, whereas the single-function AWS Lambda or Azure Function is more about distributed system design, and we need to stop pretending that the two are synonymous.)&lt;/p&gt;
&lt;h3&gt;The Case&lt;/h3&gt;
&lt;p&gt;Suppose you have two teams, each supporting their own service, and both make use of a shared database. Let&apos;s call the first team the &amp;quot;Sales Microservice&amp;quot; team and the second team the &amp;quot;Marketing Microservice&amp;quot; team. Clearly both will have need of much of the same data--Sales will need customer information (to know where to ship the product, for example), and Marketing will need customer information (to know if the customer has bought into the latest iteration of our bright and shiny product or not).&lt;/p&gt;
&lt;p&gt;The data people in the back of the room are already starting to squirm uncomfortably, because they can see all sorts of opportunities for violations of data integrity: if we &lt;em&gt;don&apos;t&lt;/em&gt; put this customer information into a shared database, there&apos;s all kinds of opportunities for trouble. &amp;quot;If the customer moves, we might send the product to the wrong place!&amp;quot;, they&apos;ll whimper, &amp;quot;Or we&apos;ll send them a coupon for 25% off the thing they just bought. So many ways to embarrass ourselves, we just have to have the database shared between these two teams.&amp;quot;&lt;/p&gt;
&lt;p&gt;Fair enough. But who owns it?&lt;/p&gt;
&lt;p&gt;&amp;quot;Nobody owns it,&amp;quot; they respond, &amp;quot;It&apos;s a shared database.&amp;quot;&lt;/p&gt;
&lt;p&gt;OK, but who makes sure it&apos;s still running? Who&apos;s paying for the rack or the cloud or whatever hardware and software we&apos;re using to make use of this database? Because somebody is going to do those pesky maintenance things, right?&lt;/p&gt;
&lt;p&gt;The heads are starting to turn, and they&apos;re beginning to realize where this is going. (Actually, if they&apos;re data professionals, they already know the right answer: The dedicated Database Group owns it!) For any given hardware or software &amp;quot;thing&amp;quot; inside the company, somebody has to own it, or it&apos;s going to fall apart eventually.&lt;/p&gt;
&lt;p&gt;And let&apos;s not get started on what happens when the Sales team wants to break a column or a field or a table or a document up into smaller parts, but Marketing doesn&apos;t see the need. One way to solve this, of course, is to put the shared database into the Database Group, and now each team has to bring their requests for modification to the Database Group, who will schedule the modifications to happen, please be sure to allow up to 4 to 6 weeks for us to process your request, and make sure your business case has been approved by the VP of Database Engineering ahead of time, who will need to schedule time with both the VPs of Marketing and Sales as part of the vetting process....&lt;/p&gt;
&lt;p&gt;Yeah, now we see why shared databases aren&apos;t quite as popular as they once were. We may have traded one problem off for another, but that&apos;s a different discussion for another day. Let&apos;s try this again: Sales and Marketing each need customer information.&lt;/p&gt;
&lt;h4&gt;Enter RACI&lt;/h4&gt;
&lt;p&gt;Traditionally, this is where the business consulting excitedly jumps into the room and starts waving Excel spreadsheets around: &amp;quot;We can do a RACI exercise and figure out who is in which column!&amp;quot; The theory being, of course, that once we&apos;ve established who is Responsible and who is Accountable, we&apos;ll have some clear indications about who is going to do what or decide what.&lt;/p&gt;
&lt;p&gt;Except....&lt;/p&gt;
&lt;p&gt;Have you ever been accountable for something that you weren&apos;t responsible for? As in, your work/outcome/bonus depended on the work that somebody else was doing? This is the classic definition of stress, and in general it works against the notion of &amp;quot;autonomy&amp;quot;, a critical aspect to creating a dynamic and viable team. Consider Asana&apos;s description of these two roles:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Responsible.&lt;/strong&gt; This person is directly in charge of the work. There should only ever be one Responsible role per task so you know who to go to with questions or updates. If a task has more than one Responsible person, you can lose clarity and cause confusion. Instead, aim to add additional collaborators as some of the other RACI roles, which can have more than one person.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Accountable.&lt;/strong&gt; The Accountable person is responsible for overseeing overall task completion, though they may not be the person actually doing the work. There are two ways to assign an Accountable role. Sometimes, the Accountable is the project manager (or even the Responsible, though in that case the person is taking on two different roles during the task workflow). In these cases, the Accountable is responsible for making sure all of the work gets done. In other cases, the Accountable is a senior leader or executive who is responsible for approving the work before it’s considered complete. Like the Responsible role, there should only ever be one Accountable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I mean, would you want to be the project manager in this scenario? You&apos;re Accountable for the work done, but not being Responsible means you&apos;re not doing the work, you&apos;re just checking up on everybody who&apos;s doing the work. And if that Accountable individual is a manager, you have a recipe for micromanagement in a coffee cup.&lt;/p&gt;
&lt;p&gt;This does not strike me as a great state of affairs.&lt;/p&gt;
&lt;h4&gt;Enter OCI&lt;/h4&gt;
&lt;p&gt;I think the original terms of Responsible and Accountable felt intuitive to the folks who first started using the RACI diagram, but as we&apos;ve gotten more familiar with autonomous and self-organizing teams, particularly in the view of how we like to organize development teams around microservice architectures, I think we need to revamp the acronym a little. Thus do I present the OCI diagram: Owner, Collaborator, Informed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Owner.&lt;/em&gt;&lt;/strong&gt; If you own the thing, you own the thing: You are responsible for it, you are accountable to it, and any buck having to do with the thing stops with you. This is your baby, and you get all the credit and all the blame for it. No questions, no exceptions.&lt;/p&gt;
&lt;p&gt;This is, remember, what the microservice approach was after in the first place: single-threaded. If I own it, I can make changes to it, because if it blows up, it&apos;s on me.&lt;/p&gt;
&lt;p&gt;But we rarely exist in a vacuum, which is why we have....&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Collaborators.&lt;/em&gt;&lt;/strong&gt; In the case of a microservice or a database, this will oftne be the consumers of the thing. I own its implementation, but I have responsibilities to others, and we negotiate some kind of deal (formally or informally) around what their needs are and the degree to which I satisfy them. They&apos;re not being &amp;quot;consulted&amp;quot;, which isn&apos;t always clear as to the degree of the relationship--do they get to veto an idea? do they get to weigh in on the idea? As a collaborator, it&apos;s more clar that they&apos;re involved, in some capacity, and therefore they have some say in it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Informed.&lt;/em&gt;&lt;/strong&gt; Lastly, there&apos;s those folks who aren&apos;t involved, but need to know because they do some other things around it. Perhaps they consume the API provided by the service, or they kick of a new process every time this process reaches a certain step. And so on.&lt;/p&gt;
&lt;p&gt;You can start to see how the OCI approach begins to work for both processes and software: in a customer complain scenario, when a complain comes in, a Customer Service rep often takes the complaint and passes it off to the relevant part of the company. After all, they&apos;re Responsible for that which the customer is complaining about. But if we turn this on its head a little, and ask, &amp;quot;Who owns this complaint?&amp;quot; we get to what I think is the better approach: The Customer Service Rep owns this complaint, and is both responsible and accountable for its resolution.&lt;/p&gt;
&lt;p&gt;You might well argue that I&apos;ve changed the focus of what the RACI discussion should&apos;ve been, and that may be true. Half the time, though, as a philosopher, the goal is to ask the right question--and often enough, I think the right question is, &amp;quot;Who owns this?&amp;quot;&lt;/p&gt;
&lt;h4&gt;Good fences&lt;/h4&gt;
&lt;p&gt;One of my favorite &amp;quot;isms&amp;quot; (pithy sayings that denote or describe something I think is an important idea or philosophy) is that &amp;quot;Good Fences Make Good Neighbors&amp;quot;.&lt;/p&gt;
&lt;p&gt;When I was just starting fifth grade, we moved to one of those half-acre lots that are the definition of the sprawl in LA. One of the very first things we did was to put up a wall between ourselves and our neighbor, Reg. I had no real idea why--Reg was a nice enough guy, very pleasant and chatty (as LA neighbors go, anyway--you generally don&apos;t talk much to your neighbors in LA), and whenever a ball sailed over the wall, he was happy to either grab it (if we was outside) or leave his gate unlocked so we could go grab it.&lt;/p&gt;
&lt;p&gt;So why the wall, I asked my Dad. &amp;quot;Because good fences make good neighbors&amp;quot;, he replied. &amp;quot;This way it&apos;s clear which part of the property belongs to whom, and if there&apos;s a problem with the sprinkler system, for example, we can know whose system its with and who needs to fix it.&amp;quot; But there&apos;s a small strip of lawn in the front right between the two driveways extending out to the street, and we didn&apos;t run the all all the way down that, why not? &amp;quot;Well....&amp;quot; and then he changed the subject.&lt;/p&gt;
&lt;p&gt;Later, when I was given (&amp;quot;gifted&amp;quot;, my father said proudly, as he handed off a chore to me that he hated doing) the responsibility of mowing the lawn, I was told that Reg and us traded off mowing that little strip. No formality to it, just if you were out mowing and it hadn&apos;t been mowed yet, you just took the ten minutes necessary to mow it, and figured roughly that it would all come out even between us in the end.&lt;/p&gt;
&lt;p&gt;(Persoally, I tried to make sure I always started mowing the lawn after Reg did, so that I had that much less chore to do. Pretty petty, but hey, i was 13, and mowing the lawn in 110-degrees-F heat is not my idea of a fun time on a summer Saturday afternoon.)&lt;/p&gt;
&lt;p&gt;When I go visit the Midwest or back East (in the US), I see all these homes with no fences between them, and I&apos;m always curious as to who mows what between the two homeowners. I ask folks, sometimes, if I happen to know the people living there, how they know who mows what. Every time, I find that they&apos;ve answered the &amp;quot;OCI&amp;quot; question in their own informal terms; they usually say something along the lines of, &amp;quot;Oh, I just mow to where I think the property lines are&amp;quot; or &amp;quot;Well, we kinda agreed where the dividing line was.&amp;quot; (One friend told me everybody on the block contributes to an enterprising kid&apos;s college fund by paying him to mow everybody&apos;s lawn--which neatly answers the question of &amp;quot;Who owns mowing this?&amp;quot;)&lt;/p&gt;
&lt;p&gt;In a business setting, you ask &amp;quot;Who owns this&amp;quot; not because you&apos;re looking to start (or end) turf battles between teams; you ask because that way, if I know the ball landed in your part of the yard, I can either tell you (if I think you didn&apos;t know already) or I can trust you to toss it back over the fence (if I think you know already) when you get around to it, and vice versa. It&apos;s about making it clear where the boundaries are between our teams, so that we&apos;re each clear on who&apos;s doing what.&lt;/p&gt;
&lt;p&gt;And sometimes, the act of going through one of these &amp;quot;ownership&amp;quot;/OCI discussions reveals that there&apos;s gaps--and that&apos;s the best kind of result, because now we have spotted a hole that we didn&apos;t know was there before, and can (imediately!) move to address it. The act of drawing the fence means checking the property lines, and every time you do that, ou discover something new about your property, your neighbors&apos;, or both.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Good fences make good neighbors.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>You don&apos;t want passion</title>
      <link>http://blogs.newardassociates.com/blog/2023/the-passion-fallacy.html</link>
      <pubDate>Sun, 25 Jun 2023 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2023/the-passion-fallacy.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;tl;dr&lt;/em&gt; Recently, while sitting in the speaker ready room at &lt;a href=&quot;https://vslive.com/events/nashville-2023/home.aspx&quot;&gt;VSLive Nashville&lt;/a&gt;, I had a lovely conversation with &lt;a href=&quot;https://www.linkedin.com/in/andugan/&quot;&gt;Angela Dugan&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/in/amber-vanderburg/&quot;&gt;Amber Vanderburg&lt;/a&gt; about something I&apos;ve been saying for a few years now: &lt;strong&gt;I don&apos;t want to hire passionate people, I want to hire professional people.&lt;/strong&gt; Turns out, Harvard Business Review agrees with me.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Passion is, by definition, illogical, and often leads people to act without thinking--we call them &amp;quot;crimes of passion&amp;quot; for a reason. Mostly, though, the distinction here is that the professional will do the parts of the job they dislike just as they will the parts they like--the professional knows it&apos;s a job, not a life choice or an identity.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Buy vs Build... Over Time</title>
      <link>http://blogs.newardassociates.com/blog/2023/buy-vs-build-over-time.html</link>
      <pubDate>Wed, 22 Mar 2023 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2023/buy-vs-build-over-time.html</guid>
      	<description>
	&lt;p&gt;It&apos;s the age-old question of our industry--do we buy something to take care of a need, or do we build the thing ourselves? No matter which way you go, it seems like somebody comes around later and makes it clear you chose wrong. The deep secret, however, is that no matter which way you choose, you&apos;re likely to be wrong later, not because you chose wrong, but because the context of the choice changed.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;This particular post, as is common, was inspired by a LinkedIn post:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;At Tonic, we once tried to build our own integration engine. It looked simple enough. And it worked. The only problem was what we built lacked a UI. And our goal was to separate integration work from engineering work (can’t do that without a UI). To achieve that would have needed to rebuild the equivalent of MuleSoft or Coreppoint. After a year, I made the team do a formal evaluation of external options and we picked an integration engine and sunset our internal product. &lt;a href=&quot;https://www.linkedin.com/posts/borisglants_team-work-engineering-activity-7044374379052376064-t0Yu?utm_source=share&amp;amp;utm_medium=member_desktop&quot;&gt;post&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I know a lot of engineers will look at this and blame the author for having chosen poorly. I argue that they chose correctly.&lt;/p&gt;
&lt;h2&gt;Buy vs build&lt;/h2&gt;
&lt;p&gt;It seems like such a (relatively) easy choice: If we buy something, we don&apos;t have to build it. Vendors provide support, including bug fixes. This saves our engineering hours for the real problem we&apos;re trying to address. Plus, the purchased tool will almost-always be more polished and feature-rich than what we build. But buying something costs money! And if we build something, we can tailor it specifically to our needs, with no need for workarounds and weird adapters that turn an otherwise straightforward process into a Rube Goldberg machine.&lt;/p&gt;
&lt;p&gt;So, to decide which is the &amp;quot;right&amp;quot; choice, we need only figure out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;if the vendor product has the features we&apos;re looking for, for at least the near- and short-term future,&lt;/li&gt;
&lt;li&gt;if the vendor product is at the right price point,&lt;/li&gt;
&lt;li&gt;if the vendor product will be supported (and how) for the length of time we need (in other words, is the vendor likely to go bankrupt),&lt;/li&gt;
&lt;li&gt;and if the vendor product can integrate into the rest of our software development fabric (processes, tools, languages, databases, etc).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And yet, stories of having made the wrong decision are so, so common. Why?&lt;/p&gt;
&lt;p&gt;Decisions are always made within a context; most of the bullet items above don&apos;t really address the context of the decision directly, but rely on that context indirectly. Price, for example, can be a very complicated thing, including up-front and recurring costs, but also support and maintenance investment of time and energy. (Ask any IT leader about the costs of installing an Oracle database on-premise, and you&apos;ll get an earful.)&lt;/p&gt;
&lt;p&gt;In the beginning of a project, we may not have enough experience or we may not have the bandwidth to really understand the nuances of the choice (whichever it is!). If the project doesn&apos;t go very far, then a &amp;quot;buy&amp;quot; decision was probably unwise, because now we&apos;re left with a product we don&apos;t need, or it provides capacity and features that we&apos;ve never taken advantage of yet still paid for. If the project suddenly sees huge growth and potential further growth with additional needs, then the &amp;quot;build&amp;quot; decision was a bad one, because now we need those features and polish.&lt;/p&gt;
&lt;p&gt;Rather than lament the &amp;quot;wrong&amp;quot; decision made a year ago for a buy-vs-build decision, accept that you can only make the best decision you can &lt;em&gt;given your current context&lt;/em&gt;, and accept that it&apos;s entirely possible--in fact it might even be likely--that the context will change and lead you to making a different decision down the road.&lt;/p&gt;
&lt;p&gt;And that&apos;s OK. Because we&apos;re always making decisions without perfect information (in this case, we can never know the future context or how it will differ from the current one), we have to accept that some of our bets won&apos;t pay off the way we thought. Waiting for the context to change, however, is never a great answer, &lt;em&gt;because the context is always changing&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;Opportunity Cost&lt;/h2&gt;
&lt;p&gt;When I was a younger man, back in college when it was much more common to put your own desktop computer together yourself out of parts, friends and I would debate whether we wanted to buy a new computer rig. New motherboards were coming out, new graphics cards, faster hard drives, you name it. One friend always held off, saying, &amp;quot;There&apos;s a faster version coming out in a month, and if I buy now I&apos;m just going to regret not having waited.&amp;quot; I said the same for a while, until I realized that I was never going to buy anything, because there was &lt;em&gt;always&lt;/em&gt; going to be something faster coming down the pipeline. Yes, Apple has released the M2 MacBookPro--but if we wait until next year, they&apos;ll have an M3 MacBookPro, and it&apos;ll be so much better because (something something something).&lt;/p&gt;
&lt;p&gt;In economist circles, we call the cost of making a decision and losing the benefit of choosing otherwise the &lt;em&gt;opportunity cost&lt;/em&gt;. Consider a simple decision: My wife wants to go to a Korean BBQ joint that just opened up, but I want to go to the steakhouse I like. If I choose to insist on my choice, the opportunity cost of not choosing to go to the Korean place will be (a) I won&apos;t discover that it&apos;s actually a pretty good place, (b) I won&apos;t get a chance to watch K-Pop band music videos, and (c) I may end up sleeping on the couch tonight. (Of course, my wife will be paying on opportunity cost of not choosing to go to the steakhouse, but that&apos;s a different conversation, and one she has to have with herself.)&lt;/p&gt;
&lt;p&gt;In the case of buying computer hardware, the opportunity cost of waiting is to spend a whole year continuing to work/play on the even-older rig that I was looking to upgrade or replace. But opportunity cost cuts both ways! Choosing to &amp;quot;buy now&amp;quot; means that I may have to watch with a certain amount of envy as my roommates get to play a game that&apos;s even &lt;em&gt;faster&lt;/em&gt; on their upgraded hardware, at least until I can do my upgrade, and then they get to salivate over my new purchase.&lt;/p&gt;
&lt;p&gt;Within the &amp;quot;buy v build&amp;quot; decision, the real focus should be on opportunity costs: If we do build something now, what are we paying in opportunity cost? If we do buy something now, what can we &lt;em&gt;not&lt;/em&gt; buy later, because we spend the money? For a lot of startups, for example, money is extremely tight, so that &amp;quot;what can we not spend money on&amp;quot; becomes a very important factor. For a lot of VC-backed startups, on the other hand, money &lt;em&gt;isn&apos;t&lt;/em&gt; the critical-path resource, and now the real conversation becomes &amp;quot;what engineering hours would we not have, preventing us from building out some feature or another&amp;quot; if we build.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;The buy-vs-build conversation, as you can see, is never just about the vendor product feature set and the time/energy it would take engineers to build the same. It&apos;s about the context of the situation, and the opportunity cost we pay when we make the decision. Throw in the fact that the project&apos;s or company&apos;s context can change (sometimes drastically and sometimes instantaneously), and you have a recipe for a basic realization: &lt;strong&gt;&lt;em&gt;You&apos;re never going to be always right.&lt;/em&gt;&lt;/strong&gt; Or, to be more accurate, the decision you make today has absolutely no guarantee that it&apos;s going to be the right decision the further away we get from the decision point. The best we can do is make the decision for today, accept that we pay an opportunity cost in doing so, and keep an eye for when the context has changed enough such that we need to consider revisiting the decision.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>AI-generated Applications</title>
      <link>http://blogs.newardassociates.com/blog/2023/ai-writing-code.html</link>
      <pubDate>Fri, 17 Mar 2023 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2023/ai-writing-code.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; With the recent spate of AI-driven engines (like ChatGPT) that have been shown to be able to build applications from a complete spec, a lot of folks are having a bit of an existential crisis (or else gleefully pointing out somebody else&apos;s existential crisis). Nowhere is this more pronounced than in tech--the very industry that gave us ChatGPT may now be eating itself for breakfast! (Click here to find out more!)&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;As is common, a post on LinkedIn triggered this thought; this time, it&apos;s from my friend &lt;a href=&quot;https://www.linkedin.com/in/aaronerickson&quot;&gt;Aaron Erickson&lt;/a&gt;, who wrote:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;I give it 3-5 years before AI makes low end &amp;quot;give me a spec and I give you code&amp;quot; style contracting that job shops do utterly obsolete. If all an agency does is write code to a spec, your business model is about to become irrelevant.&amp;quot; --&lt;a href=&quot;https://www.linkedin.com/posts/aaronerickson_benefits-of-using-gpt-are-really-in-your-activity-7042580186478911489-cJDd?utm_source=share&amp;amp;utm_medium=member_desktop&quot;&gt;post&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This was in turn in response to an earlier post which said, &amp;quot;Last night I used GPT-4 to write code for 5 microservices for a new product. A (very good) dev quoted GBP 5k and 2 weeks. GPT-4 delivered the same in 3 hours, for USD 0.11. Genuinely mind boggling.&amp;quot;&lt;/p&gt;
&lt;p&gt;No, it&apos;s really not that all that mind-boggling. It&apos;s an indicator of something I&apos;ve been believing (and speaking about) for many years: &lt;strong&gt;&lt;em&gt;Our tools are not elevating our game.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;Levels of Abstraction&lt;/h2&gt;
&lt;p&gt;Part of the goal of any programming language is to take abstract concepts (like functions, procedures, objects, and so on) and transform them (compile them) into low-level constructs that a CPU knows how to execute (machine code). Different languages choose different levels of abstraction as first-class concepts; Smalltalk chose a very high level of abstraction (objects and messaging), whereas C chose a very low level of abstraction. In fact, C was originally intended as a &amp;quot;portable assembler&amp;quot; for most UNIX machines--hence it&apos;s heavy use of pointers and memory locations as part of its &amp;quot;surface area&amp;quot; when programming in it. It&apos;s why C was known as a &amp;quot;systems&amp;quot; language--you could build operating systems with it.&lt;/p&gt;
&lt;p&gt;C++ chose to bring object-orientation to C, but for the most part, Bjarne Stroustrup wanted to keep the flavor and abstraction level of C intact. &amp;quot;If you don&apos;t use it, don&apos;t pay for it&amp;quot; was a common theme in the days of C++, and so for example, compiled classes wouldn&apos;t contain a v-table unless the class had an actual virtual method in it somewhere. References were pointers but without the ability to pointer-math them. (It&apos;s OK, you could always convert it back to an address with a cast.) And so on.&lt;/p&gt;
&lt;p&gt;Other C++-inspired languages, such as Java or C#, followed the C++ model pretty closely, but even languages like Python adhere pretty closely to a lot of the things C++ and C held up. Slowly they&apos;ve been taking steps away from the low-level nature of early C/C++ code, but still there&apos;s a ton of features in each of these languages that reflect an ancestry of a &amp;quot;portable assembler&amp;quot;.&lt;/p&gt;
&lt;p&gt;And we&apos;re using those languages to write microservices and full-stack applications?&lt;/p&gt;
&lt;h2&gt;Degrees of Differentiation&lt;/h2&gt;
&lt;p&gt;Meanwhile, in the world where microservices are being built, we have dozens of languages and frameworks that all &amp;quot;make it easier&amp;quot; to write microservices, and almsot without exception, most of these microservices are all doing roughly 80% the same thing: take an incoming API request, do some logic to it, store it into a database behind the service. We debate over which languages to use, which frameworks to use, and which databases to use, but fundamentally it&apos;s all the same thing: we&apos;re rebuilding the same stuff with some (maybe) different &amp;quot;business logic&amp;quot; scattered in there somewhere.&lt;/p&gt;
&lt;p&gt;The desktop, mobile, and web applications we build, meanwhile, all very much do the same things and display the same things and validate the same things. And in each case, we may argue over which web framework to use, which unit testing tools to use, and so on, and so on, &lt;em&gt;ad infinitum&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;A long time ago, early in my career, I went to work for a company that had a team building an application to help nurses in a call center take phone calls for a variety of things: referrals to doctors, general guidelines around whether to go to the ER, questions about their insurance plan, and so on. This was the first generation of a now-ubiquitous feature for insurance companies, but the Director of Development summed up the C++/Windows 2-tier client-server application and Oracle database very simply: &amp;quot;It&apos;s just dialogs over data.&amp;quot;&lt;/p&gt;
&lt;p&gt;Folks, it&apos;s almost &lt;em&gt;all&lt;/em&gt; just dialogs over data. The dialogs have gotten more sophisticated and have different kinds of input to handle, but fundamentally, every health care, every financial, every e-commerce app... they&apos;re all just &amp;quot;dialogs over data&amp;quot;.&lt;/p&gt;
&lt;p&gt;And when you see that, you begin to realize that maybe instead of trying to write the next amazing object-oriented language that incorporates &lt;em&gt;this&lt;/em&gt; feature from someplace else or adds &lt;em&gt;that&lt;/em&gt; idea from some other language, we need to start thinking about how we elevate the abstraction level entirely.&lt;/p&gt;
&lt;h2&gt;What about....&lt;/h2&gt;
&lt;p&gt;Think about this for a second. Imagine we want to build a system that allows attendees to sign up for talks by speakers at a conference. The object world spots three clear objects there: Attendee, Speaker, Talk. Three classes, with properties and methods. A few restrictions, obviously, such as limits on the number of attendees in a given talk, or that Speakers can &amp;quot;share&amp;quot; a Talk (give it together), and so on. We could easily come up with a half-dozen or more &amp;quot;business rules&amp;quot; without thinking about it too hard, and I&apos;m sure we could get that number up to two dozen or more if we wanted to add a few more concepts (like Room, or prerequisite Talks before you can attend a particular Talk).&lt;/p&gt;
&lt;p&gt;How long would it take you to build this application, from scratch, as a &amp;quot;front-end&amp;quot; (I&apos;ll let you pick web, mobile, and/or desktop) talking to a &amp;quot;back end&amp;quot; storing data in a database?&lt;/p&gt;
&lt;p&gt;And yet, we&apos;ve built something like this dozens of times before.&lt;/p&gt;
&lt;p&gt;And we&apos;re wondering why an AI engine, which does &lt;em&gt;really well&lt;/em&gt; keying off of thousands of examples of near-exactly-the-same-thing, knows how to build one of these?&lt;/p&gt;
&lt;p&gt;Surprise: This is a large part of the reason low-code/no-code tools are creating a huge surge in interest right now. The low-code/no-code tool takes an opinionated &amp;quot;line&amp;quot; through all the different layers in an application stack, and suddenly you can turn out an application with some slightly-adjusted business logic that is ready to go in moments. How hard would it be to see a &amp;quot;low-code/no-code microservice&amp;quot; tool before long? Honestly, I&apos;m kinda surprised that it hasn&apos;t already made it out the door yet.&lt;/p&gt;
&lt;h2&gt;Steps forward&lt;/h2&gt;
&lt;p&gt;Aaron&apos;s right--if we don&apos;t elevate our game, we&apos;re going to find that AI can churn out these kinds of applications with ease; in fact, it&apos;ll probably get so good it&apos;ll have one meta-pattern stamped somewhere in its silicon axons and dendrons and it&apos;ll just &amp;quot;fill in&amp;quot; the salient spots. All the way up until I can&apos;t anymore, I mean.&lt;/p&gt;
&lt;p&gt;One of the more interesting exercises to play is to take a look at &lt;a href=&quot;https://en.wikipedia.org/wiki/Naked_objects&quot;&gt;Naked Objects&lt;/a&gt;. It&apos;s not a fun place for programmers to hang out sometimes, because it suggests that somebody could build an app with this in a fraction of the time, feels like low-code/no-code, what happens when we need to customize something, and so on.&lt;/p&gt;
&lt;p&gt;But let&apos;s stop for a moment and consider: Naked Objects are a re-imagining of what Smalltalk (and Self) tried to build, which was an &lt;em&gt;entire environment&lt;/em&gt; that contained front-end all the way through to storage. Gemstone, for example, had automatic data storage baked in to its Smalltalk development environment, so building an application there meant you had literally the entire &amp;quot;full stack&amp;quot; in one place, ready to go.&lt;/p&gt;
&lt;p&gt;Ironically, so did Microsoft Access. And Visual Fox Pro.&lt;/p&gt;
&lt;p&gt;In a previous post, I talked about what &lt;a href=&quot;../2023/what-i-want-to-build.html&quot;&gt;I want to build&lt;/a&gt;, and this kind of an environment is high on that list of desirables. I don&apos;t think it needs to be an industry-spanning &amp;quot;take over the world&amp;quot; kind of language/tool/environment, though; I think it can actually be built out of existing off-the-shelf frameworks and tools, tuned to a particular corporate domain, allowing for developer and non-developer alike to create applications and extensions to the core platform.&lt;/p&gt;
&lt;p&gt;It&apos;s simply a question of when we will stop chasing after assembly language, and genuinely embrace a higher level of abstraction.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Embracing &quot;Old&quot; Tech</title>
      <link>http://blogs.newardassociates.com/blog/2023/embracing-old-tech.html</link>
      <pubDate>Wed, 1 Mar 2023 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2023/embracing-old-tech.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; It&apos;s a common problem, and one we&apos;ve seen in the industry several times--a technology (language, framework, platform, whatever) is making a significant, backwards-incompatible change, meaning any code written in &amp;quot;v.N&amp;quot; (the current, stable version) will require some coding changes if the project wants to move to the next &amp;quot;v.N+1&amp;quot; version. During v.N+1&apos;s incubation, everybody gets excited about the new features, and nobody wants to start a project on v.N. And that&apos;s a flawed take.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;This particular post was inspired by Cory House&apos;s Tweet below:&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;I feel like &lt;a href=&quot;https://twitter.com/nextjs?ref_src=twsrc%5Etfw&quot;&gt;@nextjs&lt;/a&gt; is in a weird spot at the moment. &lt;br&gt;&lt;br&gt;I can’t recommend Next 12 because it’s “old” tech. You’ll want to convert to 13 as soon as it’s stable. &lt;br&gt;&lt;br&gt;And, I can’t recommend Next 13 because it’s in Beta. &lt;br&gt;&lt;br&gt;Thus, I can’t recommend Next at all until 13 is stable.&lt;/p&gt;&amp;mdash; Cory House (@housecor) &lt;a href=&quot;https://twitter.com/housecor/status/1631136992422445056?ref_src=twsrc%5Etfw&quot;&gt;March 2, 2023&lt;/a&gt;&lt;/blockquote&gt; &lt;script async src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;p&gt;... but to be fair to Cory, this is hardly new. I saw the same thing happen when AngularJS became Angular, when C++ broke from C, and quite frankly it&apos;s the discussion every time Microsoft announces a new presentation technology (WinForms vs WPF vs MAUI vs oh hell I&apos;ve lost track where we are now).&lt;/p&gt;
&lt;p&gt;The conundrum is clear: &lt;em&gt;Do we actually want to create a new project using &amp;quot;old&amp;quot; tech?&lt;/em&gt; And my response is equally clear: Of course you do.&lt;/p&gt;
&lt;h2&gt;The Fallacy of the New Tech&lt;/h2&gt;
&lt;p&gt;A long time ago, I blogged about &lt;a href=&quot;http://blogs.newardassociates.com/blog/2016/enterprise-computing-fallacies.html&quot;&gt;the Fallacies of Enterprise Computing&lt;/a&gt;. The very first fallacy is this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;New technology is always better than old technology&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And I tried to be pretty subtle about it, too:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;This cannot be emphasized enough: This is fallacious, idiotic, stupid, and brain-dead.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Well, subtle for me, anyway.&lt;/p&gt;
&lt;p&gt;I&apos;ll leave it to you to read the full text of the fallacy, but to be fair, there&apos;s a slightly different scenario here.&lt;/p&gt;
&lt;h2&gt;The Fallacy of the New Version&lt;/h2&gt;
&lt;p&gt;First off, let&apos;s be really clear--anything that causes the reaction Cory describes (&amp;quot;Thus, I can&apos;t recommend Next at all until 13 is stable&amp;quot;) is something that every framework/language/platform author desperately wants to avoid, because it hurts their adoption. This is partly why these authors avoid backwards-compatible changes entirely, and ironically, it hurts their long-term viability.&lt;/p&gt;
&lt;p&gt;Look at Python2 vs Python3, for example. Python3 has cleaned up several significant contradictions in the language that Python2 was stuck with, and frankly, despite all the hullablloo around it, it was a necessary shift. (And yes, there&apos;s been a fair amount of words written on that transition.)&lt;/p&gt;
&lt;p&gt;But in the long run, Python3&apos;s language model is much easier to understand for those changes, and overall it hasn&apos;t hurt Python3&apos;s adoption or use, &lt;em&gt;because nobody stopped using Python2&lt;/em&gt;. (In fact, you can argue Python has the opposite problem.) It&apos;s clear that people can, and have, continued to work with the old version of Python and been quite successful--in fact, it&apos;s not unreasonable to suggest that this has been true for any v.N-vs-v.N+1 debate, at least the ones that I&apos;m aware of. (Yes, Virginia, there are new WinForms apps being built even today!)&lt;/p&gt;
&lt;p&gt;Why should Cory keep recommending and using Next 12?&lt;/p&gt;
&lt;h3&gt;The New Version Isn&apos;t Guaranteed to Work&lt;/h3&gt;
&lt;p&gt;Any time a tech is making a backwards-incompatible change, there&apos;s a strong chance (guarantee, really) that the new version is going to have bugs. Subtle bugs. Nasty bugs. Bugs that will only be found as hundreds/thousands/millions of users will find. There&apos;s a reason why my dad, the pilot, said &amp;quot;You never want to fly the model A of any airplane&amp;quot; and in our industry we said &amp;quot;Never use any Microsoft product until version 3&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Waiting for Next 13 to be stable could be an unacceptable wait time.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Time Stands Still for No Woman (or Man)&lt;/h3&gt;
&lt;p&gt;How long will you need to wait for the stable version to be ready? Will your customers/clients be willing to wait that long? Chances are good that putting a &amp;quot;hold&amp;quot; on the project&apos;s development until that threashold is crossed is an unacceptable delay. Hey, even if it&apos;s six months, you risk the budget allocated will go away, and let&apos;s not even imagine for a moment that you can have a dev team sitting on their hands all that time. They &lt;em&gt;will&lt;/em&gt; get allocated to a different project, and that one will very likely not be willing to send them back when you&apos;re finally ready.&lt;/p&gt;
&lt;p&gt;And what&apos;s the cost of starting the project now with Next 12? &amp;quot;We know we will be taking on technical debt--we&apos;ll have to rewrite parts of the code when the new version comes out.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;You&apos;re always going to need to rewrite parts of the code. Get over it.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;The Fallacy of Writing It Once&lt;/h3&gt;
&lt;p&gt;Here&apos;s a fact: things change. Technologies will grow and evolve. Platforms will emerge, platforms will go away. Languages will be new, mainstream, then legacy. Frameworks... well, we all know the lifecyle of the Javascript framework closely resembles that of the fruit fly. The point is, the things we use to build applications are in a constant state of evolution and change.&lt;/p&gt;
&lt;p&gt;And even, if by some miracle, the development world (particularly the open-source part of it) were to suddenly stand up, declare &amp;quot;We&apos;re finished! It&apos;s all done! There&apos;s nothing new to add!&amp;quot;, the business world doesn&apos;t. New competitors, new businesses, new ideas, new partners, new &lt;em&gt;everything&lt;/em&gt; means that &lt;em&gt;as soon as you ship, your legacy begins&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Michael Feathers is quoted as saying that legacy code is any code which is untestable; personally I think that legacy code is any code that&apos;s been deployed. It&apos;s all legacy code; the key question is how much &amp;quot;legacy&amp;quot; are we talking?&lt;/p&gt;
&lt;p&gt;Or, in other words, what&apos;s the technical debt for this particular release?&lt;/p&gt;
&lt;h3&gt;Technical Debt is not Always Bad&lt;/h3&gt;
&lt;p&gt;We developers have come to regard technical debt as universally bad--there are some who will be quick to point out that ANY amount of technical debt is bad and therefore to be avoided like the plague. This is, in many respects, the implicit heart of what Cory&apos;s tweeting about above: &amp;quot;I know that migrating from Next 12 to Next 13 will require change, which means you will begin your project with technical debt even from the first line of code. Therefore, I cannot in good conscience recommend a path that incurs technical debt.&amp;quot;&lt;/p&gt;
&lt;p&gt;This is silly--every project starts with technical debt, and it&apos;s my assertion that you cannot build software without incurring technical debt. Some debt you won&apos;t discover until later in the project, but it&apos;s a fallacy to assume that any deployed software--even &amp;quot;Hello world!&amp;quot;--has no technical debt. There&apos;s always something.&lt;/p&gt;
&lt;p&gt;And in the words of eXtreme Programming and the agile movement that followed it, &amp;quot;embrace change&amp;quot;.&lt;/p&gt;
&lt;h3&gt;A Use-Now, Upgrade-Later Strategy&lt;/h3&gt;
&lt;p&gt;To Cory, I would say this: Go ahead and use Next 12. Even if you end up having to rewrite a significant chunk of the code, it&apos;s a known tech debt that you capture, document, and even perhaps start some parallel development against betas of Next 13 to make sure you&apos;re not coding/architecting yourself into a corner. But the show must go on, and so must the development, so use Next 12. Maybe consider some abstractions to hide the pivot points that the 12-to-13 migration will require. Maybe you find that 13 is more stable than you thought and you can embrace it even before it&apos;s shipped in a stable form. Any way you slice it, you are moving forward, a lot of code will be built that &lt;em&gt;won&apos;t&lt;/em&gt; be affected by the migration, and you will even be able to ship something before Next 13 comes out.&lt;/p&gt;
&lt;p&gt;And if you find, during that parallel 13-based development track, that 13 isn&apos;t stable at all, and you want to wait until 14 or 15, you haven&apos;t crippled yourself by waiting.&lt;/p&gt;
&lt;h3&gt;But What About Alternatives?&lt;/h3&gt;
&lt;p&gt;&amp;quot;Hey, you&apos;re forgetting that we don&apos;t have to use Next! We could use....&amp;quot; Yes, you can, absolutely. But that takes the conversation into a different dimension: Should we use Next 12 or should we use (some competitor)? That&apos;s an entirely different question to what Cory was tweeting originally (v.N vs v.N+1). It&apos;s a fair one, but changes the basis of the conversation.&lt;/p&gt;
&lt;p&gt;To be fair, it&apos;s not an unreasonable one--perhaps there&apos;s a close competitor that can do everything Next 12 can do. In which case it&apos;s a near-guarantee that you won&apos;t even need to think about upgrading to Next 13, which could very well be a win! Yay!&lt;/p&gt;
&lt;p&gt;But to avoid using a thing at all because a new version of it is coming out soon... that&apos;s a mistake.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>What has tech brought us?</title>
      <link>http://blogs.newardassociates.com/blog/2023/what-has-tech-brought-us.html</link>
      <pubDate>Tue, 21 Feb 2023 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2023/what-has-tech-brought-us.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Tech has brought us many wonderful things, but if we take a step back from the hustle and bustle of recent releases, media excitement, and vendor advertising, we begin to realize that the tech-fueled vessel sailing to utopia that we were ready to embark on just a decade and a half ago... has kinda sunk.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Recently, &lt;a href=&quot;https://www.linkedin.com/posts/payamazadi-nyc_as-far-as-i-can-tell-the-only-improvement-activity-7033685140727812096-CWM3&quot;&gt;a LinkedIn post&lt;/a&gt; captured an accurate (if depressing) realization about the technology industry as a whole; I&apos;ve excerpted parts of it in order to weigh in:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As far as I can tell, the only improvement in my quality of life resulting from the massive improvements in tech is that I can unlock my door and turn on my lights from anywhere in the world using my phone. Which is cool!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let&apos;s stop and consider the past decade: 2012 - 2022. There&apos;s been no real sea-change in hardware, other than &amp;quot;smartphones got faster CPUs, more storage, and more cameras.&amp;quot; Laptops are basically laptops, servers are basically servers, and while both got faster and more (RAM, storage, bandwidth, whatever), they&apos;re entirely unrecognized from what they were ten years ago.&lt;/p&gt;
&lt;p&gt;Consider the app stores: What is in here that dramatically changed anything? Most of the wildly successful apps are directly tied to commercial consumption: Everybody has a rideshare app (Uber, Lyft, etc), everybody has a food-ordering app (Doordash, Uber Eats, etc), and pretty much every restaurant or grocery store has some kind of app, either in-house or a service, that coordinates ordering and &amp;quot;take away&amp;quot; service.&lt;/p&gt;
&lt;p&gt;But what about medical apps? Nutrition apps? Apps that will help you navigate financial problems? A few companies are promoting their apps as doing such, but they inevitably get sucked into the commercial vacuum and end up being a mouthpiece for a retail entity--Truebill, for example, got sucked into the vortex that is the Rocket Mortgage family of companies, and was rebranded as Rocket Money (or something).&lt;/p&gt;
&lt;p&gt;Consider the FAANG: Google, for example, has released a number of new things in the last decade, which, by the way, have almost universally been unsuccessful, meaning Google&apos;s only real success stories are Google search, GMail, and Android, all of which were either before 2012 or right close to it. &lt;em&gt;Nothing&lt;/em&gt; Google has done in the last decade has left a mark.&lt;/p&gt;
&lt;p&gt;Microsoft has Azure, but each successive wave of Windows? Meh. Office? Meh. Even their principal developer stack, .NET, hasn&apos;t made any significant definitive mark except with the people already using it.&lt;/p&gt;
&lt;p&gt;Netflix? Canceling their custom-created content as fast as they release it--but the basic service is still the same. Facebook? &amp;quot;The Metaverse!&amp;quot; and &apos;nuff said about that one.&lt;/p&gt;
&lt;p&gt;Apple? MacBooks are now running ARM CPUs which is pretty much just &amp;quot;more&amp;quot; like we said earlier. Phones are still handheld touch computers; Pads are still larger handheld touch computers. Heck the largest iPad is essentially a touch-screen laptop just without the keyboard. They&apos;ve even discontinued the iPod entirely. Arguably, their most revolutionary product in the last ten years has been... earbuds. Wireless earbuds.&lt;/p&gt;
&lt;p&gt;Social media? I think by now we&apos;ve come to realize that social media has as many nuclear-bomb-yield minefields as it does benefits.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The proposition that tech improvement = humanity improvement was always dubious and extremely risky. In fact it’s quite likely that the opposite is true, tech improvement = humanity regression.&lt;/p&gt;
&lt;p&gt;In particular, tech utopia was always fake news. Crypto was never going to bank the unbanked. FAANG was never going to solve the energy crisis or make our economy more inclusive. Weird little app X from San Francisco transformed nobody’s life outside of the equity holders for more than a few minutes.&lt;/p&gt;
&lt;p&gt;It is true social indicators are at lifetime highs but they’ve barely moved in these last 15 years of tech’s golden era, and many indicators have steadily trended down since November 2016. Tech utopians claiming credit for any of that progress sounds like theft, and shirking any responsibility for its decline abdication.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Consider this: Most of us--particularly the Millennials and the GenZers--are actually &lt;em&gt;less happy&lt;/em&gt; because of our phones. We spend more time looking for &amp;quot;likes&amp;quot; online than we are in talking to friends at a restaurant about what we like. We&apos;ve substituted social media for actual socializing. Tinder taught a whole generation how to &amp;quot;swipe right&amp;quot;, Netflix brought us &amp;quot;Netflix and chill&amp;quot;, but neither actually helped a generation find actual love or happiness.&lt;/p&gt;
&lt;p&gt;And it wasn&apos;t for lack of investment....&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Amazon’s operating expenses for the last 3 years totals USD 1.3 TRILLION. What do we have to show for that spend? Weird crappy speakers cluttering our houses and deliveries of shit we could’ve just as easily bought at a store. ... For comparison, Amazon spent almost as much in the last 3 years as America spent on national defense during the lowest 3 defense spending years of the Obama administration (average 500b).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And that&apos;s only Amazon&apos;s investment. That doesn&apos;t begin to consider what Google has thrown into its products--how much has Google thrown at self-driving cars, trying to one-up Tesla? Microsoft has at least avoided THAT mess, but has its own AR/VR/XR (extended reality) mess that it&apos;s starting to draw down from. Which is nothing compared to Facebook&apos;s mess. Or the ongoing dumpster fire that is Twitter--but we already talked about social media above. (44 BILLION USD, all so that Elon Musk could make sure to show up in everybody&apos;s timeline--so long as you didn&apos;t block him, which a lot of us did a loooooong time ago.)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Tech will improve humanity if we build tech for the purpose of improving humanity AND validate its delivery when it’s done. Tech will not improve humanity if we build tech for any other reason, or build it for the right reasons without associated social indicator metrics to measure against.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here&apos;s a question for us all going into 2023 as the layoffs put a LOT of tech talent onto the street with nothing to do for the next few months: What could tech do? What kind of things could a technologist, armed with some free time and some money, build to make the world a better place? Or even just make a small sliver of the world a better place? How could we leverage what we know about building software platforms, and turn that into societal good instead of just more dollars/Euro/yen?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If I’m wrong about tech utopians, I’d expect the mass layoffs to lead to a cascade of new products built for social good. If I’m right about them, expect more tech that is very useless but very attractive for VCs to one up each other.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I hate to be a betting man betting on either of these outcomes, but here&apos;s my hope: That the technologists who found some degree of power and flexibility in the pandemic, and refused to let it go when their companies ordered them back to the office, will now find the means to explore some ideas that aren&apos;t just &amp;quot;X, but for Y&amp;quot; kinds of tired VC pitches. Don&apos;t build &amp;quot;Uber, but for pets&amp;quot;. Build a platform that allows those who are in need of social services to find the nearest one that offers the aid they need. Don&apos;t build &amp;quot;Doordash, but for rock-climbing equipment&amp;quot;. Build a platform that makes it easier for teachers to wade through YouTube to find actual educational supplemental content (and deliver it without the YouTube algorithm leading kids to white supremacy videos).&lt;/p&gt;
&lt;p&gt;Let&apos;s build some tech for social good.&lt;/p&gt;
&lt;p&gt;Not just greed.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>A DevRel Activity Pattern Language</title>
      <link>http://blogs.newardassociates.com/blog/2023/devrel-activity-pattern-language.html</link>
      <pubDate>Mon, 20 Feb 2023 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2023/devrel-activity-pattern-language.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Developer Relations consists of a number of different activities that accomplish different things, but nobody&apos;s ever really sat down and talked about when to use which activity over another. I thought it was time to bring all of them together into a single, cohesive &amp;quot;whole&amp;quot;. Being a fan of patterns, I thought the best way to do that was to weave them together into a pattern language.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;If you&apos;re already familiar with pattern languages and how to use them, or you&apos;re just impatient, go ahead and &lt;a href=&quot;../../devrel/activities/index.html&quot;&gt;jump to the language&lt;/a&gt;. If you&apos;re a more patient sort, or if you&apos;re not sure how to use pattern languages, read on. (And if you come back here after taking a quick look at the catalog to see a little bit more about how to use it, I promise I won&apos;t tell anyone.)&lt;/p&gt;
&lt;h2&gt;What is a pattern language?&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Pattern_language&quot;&gt;Wikipedia defines it thusly&lt;/a&gt;: &amp;quot;A pattern language is an organized and coherent set of patterns, each of which describes a problem and the core of a solution that can be used in many ways within a specific field of expertise. ... A pattern language can also be an attempt to express the deeper wisdom of what brings aliveness within a particular field of human endeavor, through a set of interconnected patterns. ... (O)rdinary people can use this design approach to successfully solve very large, complex design problems.&amp;quot;&lt;/p&gt;
&lt;p&gt;In this scenario, the &amp;quot;very large, complex design problem&amp;quot; is that faced by a Developer Relations team, particularly its leader (team lead, Director, or VP): Of the large number of different activities we can do, which ones best accomplish our goals? Where can we put our precious resources (time and money) to get the most return? How best do we interact with the developer communities we serve (for the particular definition of &amp;quot;best&amp;quot; we care to define)?&lt;/p&gt;
&lt;p&gt;In essence, the pattern language offers at least a modicum of structure: to conduct a Developer Relations &lt;em&gt;campaign&lt;/em&gt;, first identify the &lt;em&gt;persona&lt;/em&gt; of developer you seek to reach, the &lt;em&gt;results&lt;/em&gt; (metrics, perhaps?) that will tell you you have reached them, and the &lt;em&gt;activities&lt;/em&gt; that will help you best achieve those results. (This is a pretty high-level oversimplification of running a DevRel organization... but not too high-level, and not too oversimplified, I think.)&lt;/p&gt;
&lt;h3&gt;OK, what&apos;s a persona?&lt;/h3&gt;
&lt;p&gt;In a nutshell, your target. Your audience. Your chosen developer demographic. It goes by many names, but in essence, it&apos;s a description of the kind of developer you&apos;re trying to reach. It may be easier to explain by example. Imagine you are working for a NoSQL database company, one that historically has been used for one purpose (perhaps as a caching layer) but has recently made some technical changes that enable it for use in a variety of other scenarios. As the VP of DevRel, your job is to bring the idea of using it in those other scenarios to light within the developer communities.&lt;/p&gt;
&lt;p&gt;Consider these personae:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tina&lt;/strong&gt; is 25 and a front-end developer at ACME Manufacturing. She knows Javascript (React, mostly), CSS, and HTML, and works on software that provides UI to the various services that manage ACME&apos;s supply chain system with their partners. She has been coding for two years, having graduated from a coding bootcamp after college, and she has recently started dabbling with the use of document-oriented NoSQL databases over HTTP from her front-end applications.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Abdi&lt;/strong&gt; is 32 and a back-end developer at Netflix, where he focuses primarily on building ultra-reliable systems that never crash--or when they do, recover nearly instantly. He is a CS graduate from the University of Washington, been building back-end systems since he graduated, and spends nearly as much time reading about enhancements to the Gossip protocols as he does tips on how to better program in Rust (which is what he uses on the job).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Shawon&lt;/strong&gt; is 45 and runs an engineering team at Publix Markets (a grocery store chain). The team builds software to help the store manage its inventory and supply chain, and its most recent &amp;quot;big project&amp;quot; was the pandemic-inspired &amp;quot;grocery delivery service&amp;quot;, in which customers can shop online, have store employees pick out the relevant items, and either have them ready for fast pick-up at the store location, or use a delivery driver to bring them to the customer directly. Shawon&apos;s background is as a former developer (C++, back in the day), but she hasn&apos;t touched code directly in ten years.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Which of these is more likely to be interested in your messaging, enough to take a harder look at your product/service? Now, where does that individual go for information? Which developer portals, which conferences, which magazines (print or online), and so on? Establishing your target persona (or personae, there may be several) helps streamline the decision-making process around &amp;quot;which developers&amp;quot; you want to reach.&lt;/p&gt;
&lt;p&gt;Note: While it might be tempting to &amp;quot;re-use&amp;quot; personas like the ones above, don&apos;t. Take the time to build your own--it serves as a useful reason for the DevRel team to get into a room with all the other teams (Sales, Marketing, Product, Engineering, whatever) and talk about exactly who this product/service is for. Some of your peer teams will have already done this exercise, some won&apos;t, but everyone--including Engineering--will benefit from the time spent building them.&lt;/p&gt;
&lt;h3&gt;Wait, so I&apos;m supposed to use &lt;em&gt;all&lt;/em&gt; of them?&lt;/h3&gt;
&lt;p&gt;Oh, Lord, no! The pattern language is an attempt to categorize and summarize &lt;em&gt;all&lt;/em&gt; of the different kinds of activities, but it&apos;s in no way intended as a &amp;quot;check every item off on this list&amp;quot; kind of collection. In fact, I&apos;ll argue that even &lt;em&gt;trying&lt;/em&gt; to use them all is itself a huge red flag! Look at your goals, look at your available resources (bandwidth and budget), and make deliberate choices selectively that help get you closer to your goals.&lt;/p&gt;
&lt;p&gt;Keep in mind that most DevRel team strategies will want to make use of several activities simultaneously, so choose ones that have a good mix of reach and interactivity; &lt;a href=&quot;../../devrel/activities/conference-session.html&quot;&gt;Conference Sessions&lt;/a&gt; have good interactivity, but limited reach, so consider pairing them with &lt;a href=&quot;../../devrel/activities/live-streaming.html&quot;&gt;Live Streaming&lt;/a&gt; to boost reach, and perhaps advertise both using &lt;a href=&quot;../../devrel/activities/social-media.html&quot;&gt;Social Media&lt;/a&gt;. And so on.&lt;/p&gt;
&lt;h2&gt;So... show me!&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;../../devrel/activities/index.html&quot;&gt;DevRel Activity Pattern Language&lt;/a&gt; is not &amp;quot;finished&amp;quot;, in that no pattern language is ever really finished--there&apos;s always realizations and/or innovations that can be captured, analyzed, and categorized. Pattern languages are intended to be somewhat informal, yet hopefully comprehensive.&lt;/p&gt;
&lt;p&gt;Also, if you&apos;ve done DevRel for a few years now, you may find yourself a little underwhelmed. It is not uncommon for people who have &amp;quot;lived this&amp;quot; for years to look at a pattern language and growl, &amp;quot;But I already know all these things! I&apos;ve done this before!&amp;quot; The same was true of the original &lt;a href=&quot;https://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612&quot;&gt;Design Patterns&lt;/a&gt; book thirty years ago.&lt;/p&gt;
&lt;h3&gt;How do we use this?&lt;/h3&gt;
&lt;p&gt;What a pattern language does is provide us with a unified lexicon--a glossary--that we can all agree on without having to define our definitions every time a new person joins the meeting, as well as a framework by which to think about the choices we make and how they might easily work together with other choices and/or directions. Additionally, it can help give newcomers to the field a &amp;quot;leg up&amp;quot; on understanding the breadth and depth of the space, and provide a reference tool as they wade through this new space we call Developer Relations. And, honestly, I&apos;m looking forward to using this as a reference when hashing out my next DevRel team strategy--and I&apos;m hoping you will, too.&lt;/p&gt;
&lt;h3&gt;What if I&apos;m not the DevRel leader?&lt;/h3&gt;
&lt;p&gt;There&apos;s a couple of ways it can still be useful: as a list of all the &lt;em&gt;possible&lt;/em&gt; things you could be doing, so that you can suggest a few during team meetings; as a list to discuss with the rest of your team so that you can have more focused conversations about goals and objectives; and maybe even a way to think about your own activities when writing up your accomplishments for the year/quarter/resume.&lt;/p&gt;
&lt;h2&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;If you find it useful, I&apos;m glad; if you don&apos;t, I&apos;m sad, but thank you for your time anyway. And if you&apos;re &lt;em&gt;really&lt;/em&gt; excited by this, perhaps you want to consider contributing some time to it by dropping me a note with your feedback? (And yes, I&apos;d love to consider your company hiring me to run your DevRel org!)&lt;/p&gt;
&lt;h3&gt;Thanks&lt;/h3&gt;
&lt;p&gt;Much thanks to Chris &amp;quot;Woody&amp;quot; Woodruff, Scott McAllister, and Matthew Groves, for their feedback, ideas, challenges, and suggestions.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>When to Command (and When to Collaborate)</title>
      <link>http://blogs.newardassociates.com/blog/2023/when-to-command.html</link>
      <pubDate>Mon, 6 Feb 2023 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2023/when-to-command.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Managers and leaders are often told contradictory things when discussing how to interact with their teams, and those new to the role often mistake collaboration for abdication of authority.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Before we dive too deep, let me make one note about glossary here: &lt;em&gt;Leaders&lt;/em&gt; are those who are in a position of &lt;em&gt;informal&lt;/em&gt; authority, whereas &lt;em&gt;managers&lt;/em&gt; are those in a position of &lt;em&gt;formal&lt;/em&gt; authority. In other words, a leader might recommend somebody be promoted, or fired, but only a manager can actually provide the promotion or start the termination. The reason for the difference is clear--where leaders may have some kind of &lt;em&gt;popular&lt;/em&gt; or &lt;em&gt;moral&lt;/em&gt; position, managers have accountability to their teams. A leader might not get promoted when the people who follow them aren&apos;t successful, but a manager can (and does) get fired.&lt;/p&gt;
&lt;p&gt;(If you think of the term &amp;quot;manager&amp;quot; as a perjorative and/or insult, implying that managers are just shufflers of paper--figuratively or literally--then we have strongly different definitions.)&lt;/p&gt;
&lt;h2&gt;Team Interaction&lt;/h2&gt;
&lt;p&gt;As mentioned earlier, new managers/leaders are often given conflicting information regarding what the role of management/leadership is like. Perhaps most famous (and most widely misunderstood) of those aphorisms is Harry Truman&apos;s &amp;quot;The Buck Stops Here&amp;quot;. It&apos;s often taken to imply that Truman was the one responsible for making all the decisions, referencing a line from one of his speeches: &amp;quot;The President--whoever he is--has to decide. He can&apos;t pass the buck to anybody. No one else can do the deciding for him. That&apos;s his job.&amp;quot; In truth, it actually meant that he held himself &lt;em&gt;responsible&lt;/em&gt; for those things which happened on his watch, as evidenced by another speech: &amp;quot;You know, it&apos;s easy for the Monday morning quarterback to say what the coach should have done, after the game is over. But when the decision is up before you -- and on my desk I have a motto which says The Buck Stops Here&apos; -- the decision has to be made.&amp;quot;&lt;/p&gt;
&lt;p&gt;What Truman understood, as most successful Presidents have also figured out, is that while the President will receive lots of insight and advice from a whole army of people much smarter than he (or she, in the future) will ever be in particular subjects, the President is ultimately the one that must &amp;quot;own&amp;quot; the decision. That doesn&apos;t mean he is responsible for coming up with all of the details of the plan; far from it.&lt;/p&gt;
&lt;p&gt;Usually, during the &amp;quot;normal&amp;quot; course of events, analysts within the various Departments of the United States government will write &amp;quot;position papers&amp;quot;, describing the benefits and drawbacks of a particular proposal. Analysts are constantly at work writing these papers for a variety of positions, some real and some hypothetical. (Military planners do the same, often preparing for situations that may seem nonsensical in the moment--how might the US Army invade a friendly nation?--but then become useful when the context of the situation changes--such as when the US invaded Panama during Manuel Noriega&apos;s rule.) When the President needs to make a policy decision around a particular issue, position papers are requested or retrieved, and the authors are sometimes asked to present their paper to the President&apos;s staff or to him directly. The staff can debate, ask questions, float ideas, and do all the things that we&apos;ve come to expect of any sort of conference meeting, but in the end, there&apos;s only one voice that truly matters: the President&apos;s.&lt;/p&gt;
&lt;p&gt;The President of the United States makes the decision on the policy, and relies on his staff to carry out the execution of that policy. If that policy accomplishes its aims, the President reaps the reward of having made the &amp;quot;right&amp;quot; call. (Except from the opposing party, who will take great pains to point out all the ways that call led to undesirable consequences.) If that policy has negative side effects, or the policy fails to accomplish what it intended to do, the President has to defend that decision in the press to his constituents (and to the opposing party again).&lt;/p&gt;
&lt;p&gt;He &amp;quot;owns&amp;quot; the decision: He makes it, and then owns the ramifications of that choice.&lt;/p&gt;
&lt;h2&gt;Ownership&lt;/h2&gt;
&lt;p&gt;This notion of &amp;quot;ownership&amp;quot; is frequently the hot potato of corporate communication. It is, I believe, the main reason that so many people want nothing to do with leadership or management roles--it&apos;s one thing to be responsible for your own work; to then be asked to make decisions for and about others, that scares people. When you couple that fear with the accountability that comes with making a decision, that drives many away entirely.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;You can be many things in Western corporate life, but one thing you cannot be is wrong.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As a manager on a team, you own the decisions made by that team. The buck stops with you: whatever happens with this decision, you are the one that must answer for the consequences. If the decision leads to positive outcomes, you get to claim the credit. If the decision leads to negative outcomes, you must accept the blame.&lt;/p&gt;
&lt;h2&gt;Ownership is not unilateralism&lt;/h2&gt;
&lt;p&gt;Because of this, many new managers often feel that they are the unilateral decision-maker. Any decision must be &lt;em&gt;their&lt;/em&gt; decision. Because, after all, if the team&apos;s performance reflects directly on the manager, and the team&apos;s performance is rooted in decisions the team makes, then the manager has to be involved in every decision.&lt;/p&gt;
&lt;p&gt;Thus does the new manager descend directly into micromanagement, and finds simultaneously that (a) they have zero time to do anything but make decisions, and (b) their team feels entirely powerless and meaningless. Employee surveys and feedback tell the new (micro)manager that their team lacks innovation or enthusiasm--which only reinforces to the micromanager that the team needs to make less decisions, because if they&apos;re not doing well, how can they be trusted to make good decisions? The spiral continues until the team breaks somehow--either team members are fired, or quit, or the team is broken up, or the manager is fired or (worse) promoted.&lt;/p&gt;
&lt;p&gt;Not falling into this trap is the first bit of advice given to new managers: &amp;quot;Collaborate. Listen to your team. Hold meetings and be the last person to speak your opinion.&amp;quot; And so on.&lt;/p&gt;
&lt;h2&gt;Death by Consensus&lt;/h2&gt;
&lt;p&gt;This then leads to the second pitfall of new managers: no decision can be reached until the team collectively agrees to it. Meetings among the team take on the nature of an academic board of discussion, in which each of the professors who are experts in their own field weigh in with their opinions and analysis, with the intent that logic and deductive reasoning and debate will reveal the truth in time. &amp;quot;If everybody is convinced,&amp;quot; the theory goes, &amp;quot;then collectively the right decision has been reached&amp;quot;.&lt;/p&gt;
&lt;p&gt;This &amp;quot;management-by-consensus&amp;quot; says, in essence, that it&apos;s not the &lt;em&gt;manager&lt;/em&gt; that makes the call, it&apos;s the &lt;em&gt;team&lt;/em&gt; that makes the call. After all, if the decision goes well, that means that the team &lt;em&gt;collectively&lt;/em&gt; gets to share in the credit, so what&apos;s not to love, right? (And, less-often mentioned, if there&apos;s blame to get apportioned, well, the team as a whole shares the blame, so unless the company is going to fire the &lt;em&gt;entire&lt;/em&gt; team over it....)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Management-by-consensus is essentially an abdication of authority.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Consider an average scenario: An issue has come up, and a decision needs to be made. The consensus manager, seeing this, calls the team together and presents the issue. The team debates for a while, and after some period of time, one of several outcomes emerge:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Only one person in the room has an idea of what to do, and everybody in the team likes it. Consensus achieved!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;One person has an idea of what to do, and others in the room contribute modifications to the plan, which everyone agrees are improvements. Consensus achieved!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;No one in the room has any ideas. A few half-hearted ideas are tossed out, but nothing gains much traction. Somebody makes a suggestion that seems like the least-worst option, so everybody agrees to that as the decision. Consensus achieved!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Multiple people have ideas of what to do, and hearty debate ensues. At the conclusion of the meeting, one plan is agreed by everyone to be the clear winner. Consensus achieved!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Multiple people have ideas of what to do, and hearty debate ensues. As the debate wears on, though, no one plan emerges as the best chocie. A decision needs to be made, however, so individual parts of different plans are each combined into a single plan that everyone in the room can grudgingly agree to, since it seems to be the best compromise. Consensus achieved!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Multiple people have ideas of what to do, and hearty debate ensues. As the debate wears on, though, no one plan emerges as the best chocie. A decision needs to be made, however, but nobody can agree on how to achieve that compromise. The decision is postponed until the team can meet again. By agreeing to defer the decision to a later meeting, the team has reached agreement. Consensus achieved!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Multiple people have ideas of what to do, and hearty debate ensues. As the debate wears on, though, no one plan emerges as the best chocie. A decision needs to be made, however, but one individual (or more) believes that their plan is the superior choice, and will not agree to anything other than the selection of their plan. In essence, they hold the meeting hostage until everybody agrees to their plan. Consensus achieved!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&apos;re starting to notice a pattern here, that the &amp;quot;consensus achieved&amp;quot; isn&apos;t always a positive thing, you&apos;re picking up on the underlying problem of management-by-consensus: consensus often undermines the very confidence in the decision that it was intended to create. The team may have agreed, but individuals are often frustrated, hurt, or even angry at the decision (or the lack thereof).&lt;/p&gt;
&lt;p&gt;What&apos;s worse is that the manager, by having abandoned their ownership of the decision, has lost the respect and confidence of the team--that consensus manager is now, at best, an arbitrator, and at worst, a spectator.&lt;/p&gt;
&lt;h2&gt;The Buck Stops Here&lt;/h2&gt;
&lt;p&gt;As a manager of a team, you are (literally) paid to own decisions. There will come times when the team will need a decision to be made, but cannot agree on what that decision needs to be. Some may have an agenda they wish to see fulfilled, some may genuinely believe they have a better perspective; their intentions do not matter. What matters is that they disagree on what the decision will be. In those moments, the decision is--and must be--yours to make. The buck stops with you, and that means that at times, you will need to make decisions that may be unpopular with some of your team. You don&apos;t do it capriciously or maliciously, and you certainly don&apos;t do so in such a way that somebody takes it personally, but you have to do it.&lt;/p&gt;
&lt;p&gt;You are the manager. It&apos;s your decision to own.&lt;/p&gt;
&lt;p&gt;Two interesting stories are told about this phenomenon:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;When Dwight Eisenhower served as the Supreme Commander of Allied Forces during World War II, he faced the dilemma of sending many to their deaths with the invasion of Normandy.  Balancing many variables, the window to go or wait came down to a poor set of choices.  On the day planned for the invasion, the weather was uncooperative and the fog and cloud cover would keep Allied bombers from supporting the invasion force.  Eisenhower’s team was split over the decision to invade or postpone.  As was observed and reported, Eisenhower stared out the window into the fog for a long moment, turned around and said, &apos;We’ll go.&apos;&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Eisenhower had, in the room, some of the best, sharpest military minds, and the combined might of millions of men and women, the political will of two empires (one rising, one fading), and all the best minds that could be brought to the problem. They poured millions of man-hours into the analysis of the problem. In the end, though, it came down to weather: Would the weather hold up well enough to permit the landings? Some said yes, some said no, and either could&apos;ve been right. In the end, Eisenhower didn&apos;t call for a vote, nor did he continue to wrangle his staff to reach a consensus. The decision was his, and he made it.&lt;/p&gt;
&lt;p&gt;What history often doesn&apos;t tell, when telling that story, is that Eisenhower then retreated to his office to write two letters/speeches: one that praised the troops for the successful landings, and one taking full responsibility for the failure of the Allied forces to land on the Normandy coast. Eisenhower knew, full well, that credit for the success lay with the troops who stormed the shores and manned the ships and flew the aircraft. Failure, however, was his, because his was the decision that sent them.&lt;/p&gt;
&lt;p&gt;You could argue that Eisenhower was a brilliant strategist who had a feel for the vibe of the campaign. You could argue that he had a greater sense of his troops&apos; capabilities. You could even argue that it was a coin flip result, and he got lucky at the right time. It doesn&apos;t really matter for our purposes &lt;em&gt;why&lt;/em&gt; the D-Day landings were successful--all that mattered is that Eisenhower knew the decision--and the accountability for that decision--lay with him, and him alone.&lt;/p&gt;
&lt;p&gt;The buck stopped with him.&lt;/p&gt;
&lt;p&gt;Another, similar, story carries within it a slightly different lesson:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;The Illinois football team was on the brink of beating number one ranked Ohio State.  It was 4th and 1 in Illinois territory with over 8 minutes to go and the Illinois coach decided to punt.  Ohio State called a timeout and during this interval, the Illinois QB convinced the coach that they had not worked hard, practiced early and long for months (and for much of their lives) to give the ball back to Ohio State and lose with a potential drive.  The coach reversed his decision, Illinois went on to make the first down, and ultimately eat up the clock en-route to &lt;a href=&quot;https://ohiostatebuckeyes.com/no-1-ohio-state-loses-28-21-to-illinois/&quot;&gt;the major upset of the year&lt;/a&gt;.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Notice here the coach (the manager) made a decision, but was convinced by others on his staff to make a different decision. As the manager, &lt;em&gt;if you have hired your team well, you are not the smartest person in the room&lt;/em&gt;. Other people will have different perspective. They will have vision or skills or connections that you lack. They may well (and most likely will) be the ones who are executing on the decision, and if they believe they can pull it off, they might well be able to.&lt;/p&gt;
&lt;p&gt;Had Illinois failed to convert, it&apos;s reasonable to assume that many would have held the coach responsible for that decision--even though his quarterback, the one executing the play (along with 10 other players) were the ones actually &amp;quot;doing the work&amp;quot;. The manager (coach) reversed his decision, and the team responded with a win. (Literally.)&lt;/p&gt;
&lt;p&gt;As a manager, being open to your team&apos;s contrarian positions and thoughts help you shape your own decision-making. Creating a psychologically safe environment in which your team can bring their dissenting opinions to you--and be heard--is a major part of the manager&apos;s job. You want, and need, the experts on your staff to bring their expertise and provide you with as much relevant information and evidence as they can. The team may even agree on what the decision should be. But, ultimately, the decision(s) rest with you. The accountability of those decisions are held up to you.&lt;/p&gt;
&lt;p&gt;If you are the manager, you own the decision.&lt;/p&gt;
&lt;h2&gt;Crisis scenarios&lt;/h2&gt;
&lt;p&gt;It is important to note that there are times when extenuating circumstances require that the traditional pace and process of decision-making be cast aside for something more streamlined. These are often (if not always) crisis situations, and during those times your management &lt;em&gt;and&lt;/em&gt; leadership skills are put to the test.&lt;/p&gt;
&lt;p&gt;During those situations, many of the normal rules of management have to be set aside. During a crisis, your team will be looking to you not just for decisions, but much, much more. They will be unsure of themselves, particularly if this is their first crisis, and many will be afraid to make a decision because they believe it&apos;s better to do nothing than do something wrong (which often is the exact opposite of the truth). During those times, you&apos;ll need to find your &amp;quot;command voice&amp;quot;--that tone of voice that makes it clear that you are in control here. No yelling (unless it&apos;s necessary to be heard), no blaming, and no distraction.&lt;/p&gt;
&lt;p&gt;The practical details of how to handle a crisis vary from situation to situation, but in general, think about the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dive into details. During normal day-to-day operations, you&apos;ll often let your team handle any small details that come into their areas of expertise, but during a crisis it&apos;s usually important to understand any and all of the details that surround the crisis. And equally important to discard those details that aren&apos;t involved in the crisis. (Knowing the difference between the two is a hard but necessary process of filtration that you&apos;ll develop both in the moment and over time.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Be present. Your presence, as the visible (figurative or literal) icon of where the buck stops will help the team focus on their individual portions of responsibility. You may also want (or need) to take a hands-on role during the crisis, but remember that you are the authority figure here, and you need to be available for more questions and/or decisions. This is not the time to be delegating to somebody on the team--own it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ask for questions, ask for input, but don&apos;t ask somebody else to make the decision(s).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Crisis situations will often showcase your leadership skills, but in the end the success or failure of the crisis situation&apos;s resolution will hinge on your management skills, the formal authority vested in you, and your willingness to own all the decisions made.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;When taking on a management role you are accepting the accountability of what happens on your team&apos;s watch. The team will be filled with experts and expertise, but ultimately the decisions that the team needs made will be ones that you will have to make. Sometimes the team will come together collectively to figure out the best decision to make, but ultimately, it&apos;s not theirs to make or own--it&apos;s yours.&lt;/p&gt;
&lt;p&gt;Keep in mind, by the way, that there are a few situations where you may deliberately play &amp;quot;the Management Card&amp;quot;, and veto or overrule your team&apos;s consensus because you believe you have a different answer than what they can see. This is certainly your prerogative as the manager, but doing so spends a great deal of your management credibility, and had better pay off in ways that build (and enhance) that credibility--in other words, you better be &lt;em&gt;damn&lt;/em&gt; right if you do this. (And if you end up being wrong, you&apos;d better be the first person to admit it!)&lt;/p&gt;
&lt;p&gt;Leadership might mean helping the team come to the best decision, but management means owning them.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Player/Coach Fallacy</title>
      <link>http://blogs.newardassociates.com/blog/2023/player-coach-fallacy.html</link>
      <pubDate>Fri, 20 Jan 2023 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2023/player-coach-fallacy.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Many companies look to hire individuals who are both leader and individual contributor (IC) on the same team. These are often referred to as &amp;quot;Player/Coach&amp;quot; kinds of roles, and people in these roles often find a distinct lack of success over time.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;The problem is that this role sets people up for failure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The role will inevitably gravitate (and spike) to one of either the leader role or the IC role.&lt;/strong&gt; An Engineering Management Player/Coach, particularly if they are a new leader, will often index hard on their engineering skills, and spend too much time writing code (and &amp;quot;fixing&amp;quot; code written by others on the team, which undermines confidence and trust). A DevRel Player/Coach, particularly if they are a new leader, will index hard on giving presentations and doing webinars and writing blog posts and such. In both cases, the Player/Coach, being more recently a Player (and likely a successful one at that, hence the promotion), will neglect their Coaching duties in favor of &amp;quot;getting things done&amp;quot;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Coaching expectations then don&apos;t get met.&lt;/strong&gt; The team finds that their leader has no time for 1:1s with them, and/or team members miss opportunities to engage in their own career growth because the Player/Coach is spending too much time Playing. In some cases, the hiring of the rest of team never happens, all because the Player/Coach doesn&apos;t have the time (because they&apos;re &amp;quot;too busy doing the IC work&amp;quot;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Separations follow.&lt;/strong&gt; Either the team members slowly drift away to other teams where they can get better support, or the Player/Coach gets frustrated that their performance reviews (and/or anonymous survey results from the team) are sub-par, or the Player/Coach&apos;s manager takes steps to &amp;quot;correct&amp;quot; the situation. In the worst of these cases, the whole plan for the team is abandoned.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;You cannot have two Priority-One goals at the same time.&lt;/strong&gt; If you are there to be an individual contributor, management tasks distract you from your purpose; likewise, if you are there to be a manager, IC tasks distract you. No role is ever 100% one and not the other, but there should never be ambiguity as to which is your primary focus.&lt;/p&gt;
&lt;p&gt;Now, having said all this, it&apos;s still a common scenario for hiring managers to want to hire a &amp;quot;Player/Coach&amp;quot;, particularly in the early stages of a team&apos;s formation. The idea, simply put, is that until the team is built, the Player/Coach will need to be &amp;quot;hands on&amp;quot; until the team&apos;s construction is complete and the Player/Coach can move to full-time coaching.&lt;/p&gt;
&lt;p&gt;If that&apos;s the case (and this is speaking from having done this three or four times now), then here&apos;s the way to do it, assuming that no team actually exists at the time of the Player/Coach&apos;s hire:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The first six months are spent being 100% IC.&lt;/strong&gt; This gives the Player/Coach the chance to identify the goals for the team, spent a little &amp;quot;time in the trenches&amp;quot; to see what their team will need to be doing and how to do it, and get to know some of the other teams around them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The next six months are spent hiring.&lt;/strong&gt; This means the principal focus is on staffing up the team, but since that likely won&apos;t take 100% of the Player/Coach&apos;s time, the remaining time is to continue the activities that were started in the prior six months. As each team member is hired, the Player/Coach will need to put more and more of their time into onboarding, mentoring, and managing, leading to the point where....&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The team is staffed, and now the entire focus is on management.&lt;/strong&gt; Once the team is hired and in place, the Player/Coach needs to hand off all of their IC activities to members of the team (regardless of the Player/Coach&apos;s personal feelings about some of the activites--love them or hate them, they &lt;em&gt;all&lt;/em&gt; need to be turned over), and from this point forward, focus exclusively on growing and improving the team.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&apos;ve done this several times now, and if I were to do it again, I would consider any of these to be &amp;quot;red flags&amp;quot;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The timeframe for beginning the team hiring is beyond six months.&lt;/strong&gt; Organizational inertia is a subtle and ugly thing. The Player/Coach is often very good as a Player, and the organization will often be very, very incentivized to keep them in a Player role. In which case, simply admit that you don&apos;t need the manager, hire a senior or Principal-level IC, and move on.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The team size is not going to be larger than 2.&lt;/strong&gt; Setting up a situation in which a manager is managing a single person is probably the most ridiculous thing any organization can do. It&apos;s often the result of poor planning and/or failure to secure a real commitment to the team&apos;s existence--&amp;quot;We want to see how this goes and grow incrementally&amp;quot; is often the explanation, and it&apos;s weak sauce. Either there is a need, and the team needs to be built to fill it, or there is no need. Companies that build a team of manager+1 are often feeling inconclusive about whether the need exists, don&apos;t have the insight into their own company to be able to validate whether the need exists, or don&apos;t have the budget to afford the team. All of these are red flags that the team likely won&apos;t be around a year from now.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The company won&apos;t commit to headcount for the team until they&apos;ve seen the Player/Coach in the role for a while.&lt;/strong&gt; This is because the individual has zero credibility within the company, and it&apos;s a terrific way to set them up for failure. Without any sort of &amp;quot;executive support&amp;quot; to help them build their own cred, the Player/Coach will have to fall back to IC activities to build that cred, and doing so will only emphasize that &amp;quot;we never needed a team after all&amp;quot;. It becomes a self-fulfilling prophecy.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&apos;s tempting to look at the idea of the Player/Coach and believe that it&apos;s manageable, particularly in the early days of a team&apos;s formation, and conclude &amp;quot;We can make it work.&amp;quot; I agree, but only when there&apos;s a clear transition plan in place (ideally enforced by paperwork, so the plan can&apos;t go awry when the situation changes even slightly). Anything else is likely to lead to a boulevard of broken dreams.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Full-Stack Developer Fallacy</title>
      <link>http://blogs.newardassociates.com/blog/2023/full-stack-developer-fallacy.html</link>
      <pubDate>Thu, 19 Jan 2023 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2023/full-stack-developer-fallacy.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Lots of companies are spending exorbitant amounts of time trying to track down and hire &amp;quot;full stack&amp;quot; developers, and finding them difficult to find. This is probably because there is no such thing, and reveals a deep weakness in the hiring manager&apos;s thinking.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2&gt;Definition&lt;/h2&gt;
&lt;p&gt;As we begin, let&apos;s start with a working definition of the &amp;quot;full-stack developer&amp;quot; (or FSD, for short). Tossing this into Google yields (for me) the top result of:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Full stack technology refers to the entire depth of a computer system application, and full stack developers straddle two separate web development domains: the front end and the back end.&lt;br /&gt;
&amp;quot;The front end includes everything that a client, or site viewer, can see and interact with. By contrast, the back end refers to all the servers, databases, and other internal architecture that drives the application; usually, the end-user never interacts with this realm directly.&lt;br /&gt;
&amp;quot;The easiest way to put the full stack into perspective is to imagine a restaurant. The front end encompasses the well-decorated, comfortable seating areas where visitors enjoy their food. The kitchen and pantry make up the “back end” and are typically hidden away from the customer’s view. Chefs (developers) gather permanently stored materials from the pantry (the database) and perform operations on it in the kitchen (the server), and then serve up fully-prepared meals (information) to the user.&lt;br /&gt;
&amp;quot;Front end developers work to optimize the visible parts of an application for web browsers and mobile devices. Front end platforms are usually built with HTML, CSS, and JavaScript; however, they can also be made via pre-packaged code libraries or content management systems like WordPress. Back end developers, in contrast, refine the software code that communicates with servers, databases, or other proprietary software that conveys information to front end interfaces.&lt;br /&gt;
&amp;quot;Those knowledgeable in both front end and back end are called full stack developers, meaning they are well versed in both disciplines.&amp;quot;&lt;br /&gt;
(from &lt;a href=&quot;https://bootcamp.learn.utoronto.ca/blog/what-is-a-full-stack-developer/#&quot;&gt;https://bootcamp.learn.utoronto.ca/blog/what-is-a-full-stack-developer/#&lt;/a&gt; )&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;... which seems a reasonable working definition. However, I would argue that for most companies, particularly those trying to find FSDs for microservices-based teams, there&apos;s a few more disciplines left out of the above definition:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Testing: Writing unit- and integration tests.&lt;/li&gt;
&lt;li&gt;Database: Defining and maintaining databases, including schema and data migrations.&lt;/li&gt;
&lt;li&gt;Deployment: Familiarity with tools like Docker, Kubernetes, Istio, and the other services and products that are used to deploy the service/application.&lt;/li&gt;
&lt;li&gt;InfoSec: JWTs, OAuth, OpenID, and other tools of the trade to keep malicious-intent individuals at bay.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;... which is in addition to the original two disciplines (front-end/presentation, and back-end/distribution), each of which is arguably made up of other disciplines (front-end usually requires some degree of UI/UX design, and back-end often requires familiarity with distributed systems principles).&lt;/p&gt;
&lt;p&gt;(By the way, we&apos;re also not really taking into account that a &lt;em&gt;web&lt;/em&gt;-based FSD is likely to need a different set of skills than a &lt;em&gt;mobile&lt;/em&gt; FSD. Some areas, like the back-end, might share many of the same skills, but the closer you get to the front-end, the more likely divergence is going to occur.)&lt;/p&gt;
&lt;p&gt;Which, if you&apos;re thinking about it, is a relatively astounding amount of stuff for any single person to have stored away in their head, much less accessible at any given point in the day.&lt;/p&gt;
&lt;h2&gt;Jacks-of-All-Trades&lt;/h2&gt;
&lt;p&gt;The intent here is to hire people who are &amp;quot;jacks of all trades&amp;quot;, meaning they know a little about a lot of things.&lt;/p&gt;
&lt;p&gt;Historically, recruiters have talked about different &amp;quot;shaped&amp;quot; people:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&amp;quot;I&amp;quot;-shaped people&lt;/em&gt;, who have a great deal of knowledge in a very narrow range of topics (think about the developer who knows everything there is to know about a particular database, but nothing about HTML, CSS, Javascript, or even other databases),&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;quot;_&amp;quot;-shaped people&lt;/em&gt;, who are the original jacks-of-all-trades, with much breadth but little depth, and&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;quot;T&amp;quot;-shaped people&lt;/em&gt;, who have some depth in a small number of topics, but then a little breadth in more topics.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It may sound like the FSD is a &amp;quot;_&amp;quot;-shaped person, with wide breadth, except that often recruiters are looking for significant depth to go along with all that breadth. &amp;quot;Candidates must have 10 years HTML, 12 years CSS, 27 years with Istio, ...&amp;quot; and so on. In essence, the goal for the FSD-candidate search is to find &amp;quot;box&amp;quot;-shaped people, who have width breadth &lt;em&gt;and&lt;/em&gt; wide depth.&lt;/p&gt;
&lt;p&gt;That... just isn&apos;t going to happen. Not naturally, anyway.&lt;/p&gt;
&lt;p&gt;Any developer who&apos;s been in the industry for more than a few years generally will have their experience skewed in some particular direction down one (possibly two) of those above disciplines. Some will really like database and back-end systems (that&apos;s me, honestly), while others will find front-end and testing interesting.&lt;/p&gt;
&lt;p&gt;(Note that I&apos;m picking these combinations somewhat at random--I&apos;ve met people whose happy place was any combination of the two, including front-end and InfoSec.)&lt;/p&gt;
&lt;p&gt;If we take the Malcolm Gladwell measurement of &amp;quot;expertise&amp;quot; as being 10,000 hours in any particular area, and we assume a working year of 2,000 hours each (50 weeks at 40 hours each week), that&apos;s &lt;em&gt;five years&lt;/em&gt; to achieve expert status in that field. Now, if we assume that you work full-time in one discipline, having depth in all five disciplines means that &lt;em&gt;you aren&apos;t a qualified full-stack developer for 25 years.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;And, of course, nothing will change during that time to invalidate what you learned two expertises ago.&lt;/p&gt;
&lt;h2&gt;Hiring Manager Fail&lt;/h2&gt;
&lt;p&gt;How did we get here? There&apos;s a few theories, but my personal one is that it&apos;s a failure on the part of the hiring manager. A &lt;em&gt;huge&lt;/em&gt; failure.&lt;/p&gt;
&lt;p&gt;Look at it this way: Imagine you&apos;re running a team building a mobile application. Your team currently consists of the following six people, each of whom has distinctly different skills (all of which your team is using):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Alfred: HTML/CSS, Selenium testing&lt;/li&gt;
&lt;li&gt;Betty: HTML/CSS/Javascript, OAuth/OpenID&lt;/li&gt;
&lt;li&gt;Cassandra: Postgres, OpenAPI, Spring&lt;/li&gt;
&lt;li&gt;David: Postgres, Azure/AWS, Docker&lt;/li&gt;
&lt;li&gt;Esther: Docker, Javascript, JWTs&lt;/li&gt;
&lt;li&gt;Francisco: Kubernetes, Istio, AWS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now imagine that your boss comes to you and (given the current climate as I write this) demands that you lay one of these people off. Which do you choose? Anyone you let go is going to leave a huge hole that might be partially plugged by one of the others on the team, but not completely. You &lt;em&gt;might&lt;/em&gt; be able to send the rest to some training classes or online training videos to learn what is now no longer covered on your team, but that&apos;s going to take time, and while they&apos;re learning you&apos;re still vulnerable there, and that assumes that others on the team &lt;em&gt;want&lt;/em&gt; to learn whatever it is you&apos;re missing.&lt;/p&gt;
&lt;p&gt;Now, let&apos;s look at it if you have a team of FSDs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Amanda: Full-stack&lt;/li&gt;
&lt;li&gt;Bob: Full-stack&lt;/li&gt;
&lt;li&gt;Charlie: Full-stack&lt;/li&gt;
&lt;li&gt;Denise: Full-stack&lt;/li&gt;
&lt;li&gt;Evan: Full-stack&lt;/li&gt;
&lt;li&gt;Freida: Full-stack&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Well! Now when the request comes down from above, you don&apos;t have to play jigsaw puzzles with the team--you pick the one that&apos;s either the most expensive or the most junior (or is on a PIP or is the biggest pain in your--), and &lt;em&gt;voila&lt;/em&gt;, problem solved. Or, if one of them chooses to leave, again, you just put out a request to Recruiting to hire another one of those FSDs, and you&apos;re back to full strength!&lt;/p&gt;
&lt;p&gt;What&apos;s more, when the team is doing on-call rotation, each team member has the same skill set coverage, so that there&apos;s no &amp;quot;fallback&amp;quot; or &amp;quot;chain&amp;quot; that needs to be followed depending on what went wrong; in the first team, if Betty got paged because of an escalation having to do with the Postgres database, she lacks that skill, and somehow we need to get either Cassandra or David on the line, even though they&apos;re not on call this sprint. &lt;em&gt;Bleah.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So, from a hiring manager&apos;s perspective, the FSD approach makes their life much, much easier.&lt;/p&gt;
&lt;p&gt;And frankly, that&apos;s weak management--the manager&apos;s job &lt;em&gt;isn&apos;t&lt;/em&gt; to make their own life easier, their job is to make the &lt;em&gt;team&apos;s&lt;/em&gt; life easier. Yes, it&apos;s going to be a pain to juggle responsibilities and/or get team members cross-trained in other areas so we always have a &amp;quot;principal&amp;quot; and &amp;quot;secondary&amp;quot; expert on any tool or library or technology the team uses. Yes, when one of them leaves, you&apos;re going to have to lean on the other(s) to help fill the gap, and do more training to get yourself back to a &amp;quot;principal&amp;quot;/&amp;quot;secondary&amp;quot; expert within the team.&lt;/p&gt;
&lt;p&gt;But when those people leave, now finding somebody who has one or maybe two disciplines under their belt means the candidate hiring process goes from &amp;quot;years&amp;quot; to &amp;quot;months&amp;quot;. Plus, it simply acknowledges the reality that nobody is a &amp;quot;box-shaped&amp;quot; individual, no matter what their resume states.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Don&apos;t try to hire full-stack people; build full-stack teams.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>A DevRel Activity Ontology</title>
      <link>http://blogs.newardassociates.com/blog/2023/devrel-activity-ontology.html</link>
      <pubDate>Sat, 14 Jan 2023 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2023/devrel-activity-ontology.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt;: Newcomers to Developer Relations are often curious as to what, exactly, makes up the range of activities that a Developer Advocate (and related individuals) undertake. In this post, I look to provide an ontology and means by which to examine what artifacts satisfy what needs, and how it isn&apos;t just about what artifacts a DevAd produces.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;First of all, if you haven&apos;t seen James Ward&apos;s &lt;a href=&quot;https://jamesward.com/2021/09/26/the-seven-artifacts-of-developer-advocacy-projects/&quot;&gt;&amp;quot;Seven Artifacts of Developer Advocacy Projects&amp;quot;&lt;/a&gt;, I highly recommend it before continuing onwards here.&lt;/p&gt;
&lt;p&gt;Let me begin with &lt;a href=&quot;../../devrel/&quot;&gt;my working definition of Developer Relations&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;That part of the company that engages with developers, both internal and external to the company, for the purpose of using that relationship for net gain to both sides. This can take the form of many things, but ultimately, (a) it&apos;s aimed at developers, (b) it&apos;s intended to facilitate greater positivity to one or both sides, and (c) it centers around developer activities of one form or another (that is, it could be technical, &amp;quot;human skill&amp;quot;, or process, but it kinda-sorta has to be around the world of software development).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;NOTE:&lt;/em&gt;&lt;/strong&gt; Some folks will take issue with the part of my definition that starts it off: &amp;quot;This is that part of the company....&amp;quot;, arguing that it&apos;s not limited to companies, i.e., open-source communities engage in Developer Relations. That may be true, but what we&apos;re seeing is that by the time the OSS community gets to the point of formalizing their relationship to the developers using their products/tools, they&apos;ve usually formed some kind of foundation and it becomes somebody&apos;s job to take that relationship on.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Keep in mind that in James&apos; post, he appears to be thinking that &amp;quot;for any given DevRel &lt;em&gt;project&lt;/em&gt;, these are seven things that can come out of each.&amp;quot; So, for example, if the DevRel team works on a code sample (maybe it&apos;s a React example of how to use the company&apos;s SDK), this is the list of things that can all be obtained from that single investment of time and energy:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Code Samples&lt;/li&gt;
&lt;li&gt;A Blog Post&lt;/li&gt;
&lt;li&gt;A Presentation and/or Video&lt;/li&gt;
&lt;li&gt;A Hands-On Workshop&lt;/li&gt;
&lt;li&gt;Broad Social Media Reach&lt;/li&gt;
&lt;li&gt;Product Feedback&lt;/li&gt;
&lt;li&gt;Enriched Community, Partner, or Customer Relationships&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;... and he&apos;s right, to be sure. Matter of fact, I&apos;m a &lt;em&gt;huge&lt;/em&gt; proponent of that mindset--if you&apos;re going to spend the time to learn a thing, amortize the cost by spreading the benefit of that learning around and into as many things as you can. I&apos;ve written magazine articles (or series of articles), blog posts, training classes, conference workshops, breakout session conference slides, and more, out of learning just one new thing (like a new framework or a new language or a new library).&lt;/p&gt;
&lt;h2&gt;An Activity Ontology&lt;/h2&gt;
&lt;p&gt;But there&apos;s a deeper element here, around how we choose each activity and what we get out of each. As I see it,each of these provides value along three different &amp;quot;axes&amp;quot; of value to a DevRel team (and to the company that sponsors them):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Reach&lt;/em&gt;&lt;/strong&gt;: How &amp;quot;far&amp;quot; does this artifact go? How many people can see it and/or consume it? Those things done over the Internet tend to have a large reach (particularly if the artifact is someplace where Google can find it and pop it up during search results), whereas those things done in person (such as the hands-on workshop) will have very short reach, since participation requires physical presence. For example, a blog post can echo across the entire world within minutes, and even across time itself--certain blog posts just keep getting rediscovered by new readers. That kind of reach is just not possible with an in-person workshop done at a conference event, even if the workshop has a thousand people in it (which, by the way, is categorically impossible to do--a group that size isn&apos;t doing a hands-on workshop, they&apos;re watching you lecture).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Interactivity&lt;/em&gt;&lt;/strong&gt;: This is the fidelity of communication--how &amp;quot;conversational&amp;quot; is the artifact? This in many cases is in inverse proportion to reach, but not always. The blog post doesn&apos;t really allow for great conversation (yes, you can open up comments on the blog, but we all know what happens when you do, and it&apos;s not pretty), whereas a workshop really requires a high degree of interactivity with the attendees. The blog post author doesn&apos;t learn much from their audience when posting the blog--the workshop facilitator, however, can learn all kinds of things from the attendees via the questions they ask, the problems they run into, the questions they don&apos;t ask, and so on.&lt;br /&gt;
There&apos;s an important note to the points of Reach and Interactivity, though: Although the blog post and the in-person workshop may seem like they are mutually exclusive--and for some tools they are--they don&apos;t always have to be. I can do an &amp;quot;in-person workshop&amp;quot; over something like Zoom that can reach across the world, and if we record it, we get more Reach. I can make sure the blog post has comments enabled and people assigned to react and respond to the comments--or we can take the blog post to Hacker News or Reddit or StackOverflow, and make sure we keep a sharp eye on any discussion that emerges there, and increase our Interactivity. Reddit isn&apos;t &lt;em&gt;as&lt;/em&gt; interactive as an in-person workshop, but that doesn&apos;t mean it is entirely a one-way communication, either.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Direction&lt;/em&gt;&lt;/strong&gt;: One thing James hints at, but doesn&apos;t really call out strongly, is the idea that DevRel is a circular exercise: DevRel should be talking to both those developers inside the company as well as those outside of it. This means the usual activities of bringing development discussions to developers that might be customers of the company&apos;s product, but also bringing feedback from those developers on the outside back into the company for further discussion and/or examination.&lt;/p&gt;
&lt;p&gt;Let&apos;s also put something out here: DevRel can be just as much about mentoring and catering to the developers &lt;em&gt;inside&lt;/em&gt; the company as it does &lt;em&gt;outside&lt;/em&gt; of it. Particularly with the efforts around &amp;quot;inner-sourcing&amp;quot;, wherein companies (particularly large ones) practice the same processes and practices for open-source projects on internal projects, it can be important for a DevRel team to be just as focused on bringing awareness and engagement to developers internal to the company as external. Matter of fact, I first engaged in this with my DevRel team at Smartsheet, where we took over the internal-facing &amp;quot;Lunch Talks&amp;quot; (also known as &amp;quot;Brown Bags&amp;quot; at other companies, where an internal employee talks about a subject over lunch) and internal training; did the same thing at Rocket Mortgage, where we created the &amp;quot;Tech Speaker Series&amp;quot; (where we had industry names do virtual all-day workshops for our engineers during the pandemic). So not all activities of DevRel are externally-facing, and realistically, &lt;em&gt;any&lt;/em&gt; activity that is typically done externally-facing can also be done internally-facing.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;A DevRel Activity Catalog&lt;/h2&gt;
&lt;p&gt;So with these three axes in mind, we can start to categorize some of the activities that a DevRel team does (whether around a particular project or not), with the idea that &lt;em&gt;if your company is looking to enhance its reach, it&apos;s interaction, or change/adjust its direction of engagement, we can choose activities accordingly&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;The Foundation&lt;/h3&gt;
&lt;p&gt;First, we have the primary colors of the DevRel spectrum:&lt;/p&gt;
&lt;h4&gt;Code&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Also known as&lt;/strong&gt;: Samples/Examples; SDKs; Tests&lt;br /&gt;
&lt;strong&gt;Reach&lt;/strong&gt;: &lt;em&gt;High&lt;/em&gt; - Code can go anywhere a browser can be fired up, and since most languages are freely available, anyone who can see the code can usually grab tools to build and run it.&lt;br /&gt;
&lt;strong&gt;Interactivity&lt;/strong&gt;: &lt;em&gt;None-to-Low&lt;/em&gt; - Yes, I can file bug reports and raise issues on GitHub, but those are properties of GitHub, not the code. The code itself is pretty much entirely on its own, and the recipient is left to figure out what the code is trying to tell them.&lt;br /&gt;
&lt;strong&gt;Direction&lt;/strong&gt;: Code can be passed to anyone, internal or external, so long as there aren&apos;t legal entanglements around it.&lt;/p&gt;
&lt;h4&gt;Presentation&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Also known as&lt;/strong&gt;: YouTube; Webinars; Conferences (sessions); Meetings (customers or others)&lt;br /&gt;
&lt;strong&gt;Reach&lt;/strong&gt;: &lt;em&gt;Depends&lt;/em&gt; If the presentation is &amp;quot;live&amp;quot;/in-person, the reach is constrained to the physical space the audience can fit within. If the presentation is &amp;quot;broadcast&amp;quot; over video-capture platforms (like Zoom), then the reach grows significantly. If the presentation is recorded, that reach now extends beyond the moment in which the presentation is being given, adding longevity to the reach.&lt;br /&gt;
&lt;strong&gt;Interactivity&lt;/strong&gt;: &lt;em&gt;Depends&lt;/em&gt; The traditional presentation is one-way (from the speaker to the audience), and is often referred to as &amp;quot;eyes-forward&amp;quot; or &amp;quot;lecture-style&amp;quot;. While a presenter can certainly gain some insight and feedback from questions asked during the presentation, most presentations are 75%+ presenter-talking, with some being 90%, 95% or even 100% presenter&apos;s voice, leaving only a small amount of room for that feedback. If the presentation is recorded or broadcast, the interactivity drops significantly.&lt;br /&gt;
&lt;strong&gt;Direction&lt;/strong&gt;: &lt;em&gt;Bidirectional&lt;/em&gt; It all depends on the audience composition.&lt;/p&gt;
&lt;h4&gt;Writing&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Also known as&lt;/strong&gt;: Documentation; Articles; Blog posts&lt;br /&gt;
&lt;strong&gt;Reach&lt;/strong&gt;: &lt;em&gt;High&lt;/em&gt; Thanks to the power of Internet protocols (such as RSS) and search engines, writing can be made available through a variety of mechanisms and consumed by literally any of millions of people online at any given moment.&lt;br /&gt;
&lt;strong&gt;Interactivity&lt;/strong&gt;: &lt;em&gt;None-to-Low&lt;/em&gt; While it&apos;s certainly possible for written pieces to have a &amp;quot;comments section&amp;quot; wherein readers can offer up thoughts and feedback, experience has taught us that unmoderated comments are usually a fast track to noise and spam, decreasing the quality of the feedback to zero quickly.&lt;br /&gt;
&lt;strong&gt;Direction&lt;/strong&gt;: &lt;em&gt;Bidirectional&lt;/em&gt; Writing is commonly used to reach both an internal and an external audience.&lt;/p&gt;
&lt;h4&gt;Social&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Also known as&lt;/strong&gt;: Twitter/LinkedIN/Facebook; GitHub; StackOverflow; Forums; Conferences (floor); Conferences (sponsorship)&lt;br /&gt;
&lt;strong&gt;Reach&lt;/strong&gt;: &lt;em&gt;High&lt;/em&gt; - The various &amp;quot;communication platforms&amp;quot; of the community are neither writing nor presentation but fast becoming its own medium. The longevity is debatable, and the risk can sometimes be high, but the reach can be astounding. Keep in mind, though, this isn&apos;t limited to just the traditional social media platforms--GitHub long ago figured out its role in life is as a developer social platform. And those are just the &lt;em&gt;online&lt;/em&gt; platforms--analog platforms (like conferences) have been around for a long, long time.&lt;br /&gt;
&lt;strong&gt;Interactivity&lt;/strong&gt;: &lt;em&gt;High&lt;/em&gt; - These platforms don&apos;t accomplish anything unless people are using them, and if they&apos;re using them, by definition there&apos;s interactivity there. Interactivity is off-the-charts high here.&lt;br /&gt;
&lt;strong&gt;Direction&lt;/strong&gt;: &lt;em&gt;Mostly external&lt;/em&gt; While certain social media players (&lt;em&gt;cough&lt;/em&gt; Facebook) experimented with specific instances of their platform running internally to the company (that is, on the company&apos;s intranet), it does not seem to have &amp;quot;taken off&amp;quot; in a widespread manner to replace the more traditional tools like &amp;quot;internal websites-plus-email-plus-Slack/Discord/chat&amp;quot;.&lt;/p&gt;
&lt;p&gt;It&apos;s important to realize that anything can be amplified by announcing their existence over social channels--the ubiquitous &amp;quot;Hey come to my talk in room 5 at the Ritzy Glass Hotel on the 30th of February&amp;quot; blast over every social media platform, that&apos;s table stakes. Being on the floor at a conference talking with developers is intrinsically a high-interactivity activity, while &lt;em&gt;sponsoring&lt;/em&gt; at a conference (as in, name on the banner above the floor and on the website) is lower Interactivity, but higher Reach.&lt;/p&gt;
&lt;h3&gt;The Hybrids&lt;/h3&gt;
&lt;p&gt;Then, we have the secondary colors of the spectrum, made up by blending two of the above together:&lt;/p&gt;
&lt;h4&gt;Code + Writing&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Also known as&lt;/strong&gt;: Tutorials; Reference API Documentation; Books; Articles; blog posts&lt;br /&gt;
&lt;strong&gt;Reach&lt;/strong&gt;: &lt;em&gt;High&lt;/em&gt;&lt;br /&gt;
&lt;strong&gt;Interactivity&lt;/strong&gt;: &lt;em&gt;Low to none&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;Code + Pesentation&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Also known as&lt;/strong&gt;: Workshops; Hands-on-Labs; Code Review; Training&lt;br /&gt;
&lt;strong&gt;Reach&lt;/strong&gt;: &lt;em&gt;High&lt;/em&gt;&lt;br /&gt;
&lt;strong&gt;Interactivity&lt;/strong&gt;: &lt;em&gt;Low to none&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;Code + Social&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Also known as&lt;/strong&gt;: Gists; Posts&lt;br /&gt;
&lt;strong&gt;Reach&lt;/strong&gt;: &lt;em&gt;High&lt;/em&gt;&lt;br /&gt;
&lt;strong&gt;Interactivity&lt;/strong&gt;: &lt;em&gt;Low to none&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;Keep in mind, this isn&apos;t an exhaustive list of everything a DevRel team might do. For example, part of what isn&apos;t on this list is &amp;quot;Participation in unowned OSS projects&amp;quot;--that is to say, OSS projects that aren&apos;t &amp;quot;owned&amp;quot; or founded by the company. (Microsoft currently participating in the development and enhancement of the OpenJDK is one such example.) In these cases, the goal here may be to help the company&apos;s DevRel activity by being a good player in a partner&apos;s ecosystem, or it may be to support some other corporate goals.&lt;/p&gt;
&lt;p&gt;Now, based on the DevRel team&apos;s goals, different activities (and their variations) can be selected deliberately to match. If the team needs to broaden developers&apos; awareness of the company and/or its tools (sometimes referred to as &amp;quot;brand marketing&amp;quot;), high-reach activities are called for, without as much concern for interactivity. If the company wants to engage more deeply with the community--perhaps as a stepping stone to creating a formal &amp;quot;close friends group&amp;quot; (such as Microsoft MVP, Google GDE, and other programs), then activities high in social factors should be evaluated. Need to help Sales boost some numbers? Social will help, ideally in combination with high interactivity, so that potential sales targets can be more easily identified and pursued. (Saving salespeople from making cold calls/emails--and your community members from having to receive them--makes everybody happier.)&lt;/p&gt;
&lt;p&gt;There&apos;s probably deeper ontological analysis lurking in here, and maybe even a full patterns catalog, but releasing earlier and oftener is a bonus, so... have at! :-)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Where does DevRel fit on an org chart?</title>
      <link>http://blogs.newardassociates.com/blog/2023/where-devrel-fits.html</link>
      <pubDate>Sun, 8 Jan 2023 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2023/where-devrel-fits.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt;: The Developer Relations org isn&apos;t exactly Engineering, but it&apos;s not entirely Marketing, and it often isn&apos;t really Sales. So if you&apos;re a company looking to find a home for your nascent (or currently-existing) DevRel team, where do you put it?&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Let&apos;s consider some of the traditional places a DevRel team appears first.&lt;/p&gt;
&lt;h2&gt;Engineering&lt;/h2&gt;
&lt;p&gt;This often seems like the most natural place for a Developer Relations team--after all, developer advocates often come from engineering backgrounds, most DevRel activities involve code in various ways, and, after all, their target audience usually work in Engineering departments themselves, so.... This is the right place to put them, right?&lt;/p&gt;
&lt;p&gt;Unfortunately, while this might be a reaonsable second choice, it&apos;s not ideal. Engineering teams&apos; sense of success is to ship things, often &amp;quot;at scale&amp;quot;, and that mentality often carries over into the DevRel team, leading the goals of the team to be centered around shipping things (blog posts, code samples, etc). Worse, the emphasis of &amp;quot;scale&amp;quot; leads engineering management to concentrate on actions that reach the largest number of recipients, regardless of the quality of the connection. &lt;em&gt;DevRel needs to be a loop, connecting with developers outside the company, and bringing that information back around internally&lt;/em&gt; and the team can&apos;t do that if the conversations are always one-way with little to no loopback.&lt;/p&gt;
&lt;p&gt;&amp;quot;But, what about things like documentation, samples, tutorials, and so on?&amp;quot; These are all good things that need to be done, particularly if the company promotes a product or an API (whether that&apos;s the principal item for sale or not), but these can be done by &lt;em&gt;Technical Content Creator&lt;/em&gt;s, such as &lt;em&gt;Technical Writers&lt;/em&gt; do for documentation.&lt;/p&gt;
&lt;h2&gt;DevRel inside Marketing&lt;/h2&gt;
&lt;p&gt;It&apos;s a common place to put the DevRel team, particularly in developer tools/products/services companies. The reasoning here is pretty straightforward: if the company wants to connect with developers in order to convince them to buy/use the &amp;quot;thing&amp;quot; (the tool/product/service), put them in the Marketing team and let them do the Marketing things to attract them. Go to conferences, write the blogs, but more importantly, go out there and show off the &amp;quot;thing&amp;quot; and get developers excited about it.&lt;/p&gt;
&lt;p&gt;It&apos;s not optimal to put the team here, though, for a variety of reasons.&lt;/p&gt;
&lt;p&gt;Marketing is often a &amp;quot;one-way&amp;quot; exercise, the goal being to create awareness of the product and bring them to the &lt;a href=&quot;https://useinsider.com/glossary/top-of-the-funnel/&quot;&gt;&amp;quot;top of the funnel&amp;quot;&lt;/a&gt; (meaning the &amp;quot;sales funnel&amp;quot;, the euphemism for the collection of people who move through the process around purchasing a product). Developer &amp;quot;relations&amp;quot; means having a relationship with the developer community, not just talking at them.&lt;/p&gt;
&lt;p&gt;Practically speaking, the goals of the Marketing team will often differ in substance from what a DevRel team needs to do. For example, Marketing&apos;s metrics will often revolve around &amp;quot;page hits&amp;quot; or &amp;quot;eyeballs&amp;quot; or &amp;quot;site stickiness&amp;quot;, all of which revolve around the number of people and amount of time that arrive at the website or booth to find out more information. There&apos;s little to zero measurement around the &lt;em&gt;depth&lt;/em&gt; of the connection, and even less emphasis on taking the feedback from the developer community.&lt;/p&gt;
&lt;p&gt;What&apos;s more, the lines of communication between the Marketing team and the Engineering team are often quite &amp;quot;distant&amp;quot;. If the DevRel team cannot get feedback from the developer community outside the company to the developer community inside the company, then they&apos;re not really &amp;quot;relating&amp;quot; to developers anymore, and they&apos;re really just &lt;em&gt;Technology Marketing&lt;/em&gt; or &lt;em&gt;Developer Marketing&lt;/em&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;SIDEBAR: The bigger the distance between any two nodes in the organization chart tree, the harder it is to communicate on a regular basis. By this, I mean, if Alice and Bob both report to Mary, their distance is 0 from each other; if they both don&apos;t report to somebody until reaching the CEO on the org chart, then they&apos;re essentially at opposite ends of the Earth from one another. That distance makes it nearly impossible to set up a regular conversation, because the day-to-day of those two orgs is enough to create organizational resistance in a variety of ways. Try it if you don&apos;t believe me sometime--set up a regular recurring 1:1 with somebody from Legal or somebody from the shop floor or some other department that&apos;s miles and miles away from you on the org chart, and see how long your 1:1 lasts.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While it makes sense for the DevRel team to be in constant communication and alignment with the Marketing team, &lt;em&gt;DevRel needs to be independent enough to not be held to &apos;top-of-funnel metrics&apos; and instead held accountable to things that promote total engagement with developers&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;DevRel inside Sales&lt;/h2&gt;
&lt;p&gt;In some organizations, particlarly the ones that sell products/services to developers, there&apos;s a natural tendency to put the DevRel team in Sales, since the DevRel team relates to developers, and the target demographic for buying the product or service is developers, and DevRel team members &lt;em&gt;are&lt;/em&gt; developers, so.... Natural fit, right?&lt;/p&gt;
&lt;p&gt;Oh my goodness, no.&lt;/p&gt;
&lt;p&gt;First off, developers grow up to learn a pathological distrust--if not downright dislike--of anything that smells like Sales. Let&apos;s be honest, a lot of that is learned behavior from their predecessors (aka me and my generation), which may not be fair. (Probably isn&apos;t fair, to be honest.) Part of that distrust stems from sleazy Sales campaigns that my generation was exposed to; I still remember the day the Symantec Java IDE hit the streets and its salespeople boasted--without a hint of caution or hesitation--that their IDE would enable a &amp;quot;400% productivity boost&amp;quot; just by using their IDE instead of any of their competitors. It was complete and utter fabrication with zero basis in reality, but it&apos;s not the first time--nor will it be the last--that a sales pitch aimed at words like &amp;quot;productivity&amp;quot; or &amp;quot;scalability&amp;quot; or &amp;quot;cost savings&amp;quot; as tangible reasons to purchase a product. Salespeople have an unwholesome reputation, that they will say or do anything to &amp;quot;close the deal&amp;quot;, regardless of the factual accuracy of what&apos;s being said, and developers want zero part of that.&lt;/p&gt;
&lt;p&gt;When the DevRel team goes out into the community to connect with the community, &lt;em&gt;they need to build relationships based on a basis of mutual trust: That I as a DevRel, I&apos;m a developer too, and I know where you&apos;re coming from and I&apos;m here to help you be better at what you do.&lt;/em&gt; Theoretically, salespeople should be coming from a similar perspective in a variety of other domains; it&apos;s why we have commercials in which we see people facing the camera talking about the product--you&apos;re supposed to empathize with who they are, either because they&apos;re who you are, or they&apos;re who you want to be. When that trust breaks down, then the messaging is entirely lost. In fact, if that trust breaks down far enough, it itself becomes an obstacle to the sale; for years, I told people to steer well clear of the Symantec IDE just because I was so disgusted with that sales tactic.&lt;/p&gt;
&lt;p&gt;In many scenarios, a developer-type individual can go in to a sales call as a supporting character to the salesperson&apos;s meeting. This is the world of &lt;em&gt;Technical Sales&lt;/em&gt;, and in many cases is used to help flesh out the details of the product and/or provide reassurance of what the product can and cannot do, particularly if it&apos;s a deeply-technical product. So long as the salesperson/TechSales tandem is in sync with one another, having the TechSales there, keeping the conversation &amp;quot;honest&amp;quot; and being forthright about the details, creates a deeper sense of trust between the buyer and the salesperson, and enables deals where it otherwise would fall apart. And Dev Advocates can certainly take the role TechSales for that meeting--any Dev Advocate who&apos;s been in the industry for more than a half-decade has done that at least once--but it&apos;s not at the forefront of their job description, and it should never be anything more than a supporting role in the sales process.&lt;/p&gt;
&lt;p&gt;Again, if we consider the metrics, salespeople often fall under the ultimate metric: commission. And if your DevRel team falls under that metric umbrella, they&apos;re not going to be concerned with building trust in the community (and making it easier to land sales), they&apos;re going to be held accountable to going out and making sales of their own. It completely undermines their ability to build relationships, and reduces them to the transactional mindset that permeates sales organizations so deeply. And most relationships--whether professional or personal--fall apart under even the tiniest stress when reduced entirely to a transactional basis.&lt;/p&gt;
&lt;h2&gt;DevRel inside HR&lt;/h2&gt;
&lt;p&gt;Believe it or not, a (admittedly small minority) group of folks think the DevRel team belongs inside the same organization that handles recruiting. &amp;quot;If the DevRel team is about building relationships with technology communities,&amp;quot; the thinking goes, &amp;quot;Then it makes sense to think of them as an adjunct to our other department that provides resources to the humans of the company.&amp;quot;&lt;/p&gt;
&lt;p&gt;On the one hand, there is something to this argument. Frequently, the most powerful recruiting team in the company is the DevRel team--they are out and about in the community, they speak the same language as the developers the company is courting, and they have the trust of fellow developers that recruiters (sadly) lack within that crowd. It&apos;s a very strong advertisement: An attendee has just seen a Dev Advocate give an amazing talk at a conference, thinking, &amp;quot;This person is one of the Cool Kids!&amp;quot;, and when they get to the booth, they find out that Dev Advocate&apos;s company is hiring, and thinks, &amp;quot;I want to go work where the Cool Kids work!&amp;quot; Many are the stories of a prominent open-source developer being recruited by one of the FAANGs because the conversation started at a conference, with one of the Dev Advocates, who could &amp;quot;walk&amp;quot; them to the right hiring manager or recruiter.&lt;/p&gt;
&lt;p&gt;Additionally, if the DevRel team is being faithful to its charter, it is looking to connect with not only the developers outside the company, but also the developers &lt;em&gt;within&lt;/em&gt; the company. In some companies, the DevRel team takes on some of the internal developer relationship activities, such as scheduling and arranging internal conferences or meetups, or acts as the point of contact for acquiring training for an internal team. (After all, the Dev Advocates are out and about in the community, rubbing shoulders with the people writing the books and recording the videos, so they&apos;ll be best-positioned to know who the right people are if we want &amp;quot;only the best&amp;quot; for our internal training needs. And we &lt;em&gt;do&lt;/em&gt; want only the best, right?)&lt;/p&gt;
&lt;p&gt;Unfortunately, while these are both important aspects to the DevRel team, we still fall afoul of many of the same previous arguments: the metrics in HR are often entirely &amp;quot;out of whack&amp;quot; compared to those we&apos;d like to see for a DevRel team, and the HR team is a little too far removed from Engineering, Marketing, or Sales, for the DevRel team to be effective at accomplishing its other goals.&lt;/p&gt;
&lt;p&gt;Even worse, in a lot of companies, the HR team is a cost center, meaning the company is looking to keep the costs involved to a minimum. &lt;em&gt;DevRel activities require budget--conference sponsorships, conference participation, hosting for blogs--and time--for samples, tutorials, posts, videos, and so on--that are critical to the DevRel team&apos;s success&lt;/em&gt;, yet don&apos;t fit in to traditional HR targets. Over time, the DevRel team becomes less and less &amp;quot;technical&amp;quot; and more and more &amp;quot;organizational&amp;quot;, and the participants end up being &lt;em&gt;Technology Trainers&lt;/em&gt; or &lt;em&gt;Technical Recruiters&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;DevRel inside the Office of the CTO&lt;/h2&gt;
&lt;p&gt;Companies which have had sub-optimal success with the DevRel team in any of the three above locations often cast about in some consternation--where do we put a team whose amibitions and activities don&apos;t closely align with neither Engineering, nor Marketing, nor Sales? How many other departments are left?&lt;/p&gt;
&lt;p&gt;In many cases, particularly younger companies (aka &amp;quot;startups&amp;quot;, though many companies characterized as such have long left their startup days behind them), the CTO takes a personal interest in seeing a DevRel team chartered and founded. The CTO has oversight over a number things, all of them related to &amp;quot;Technology&amp;quot;, so it seems to reason out that the team should be part of the CTO&apos;s &amp;quot;pet project division&amp;quot;, often known as the &amp;quot;Office of the CTO&amp;quot; (or OCTO).&lt;/p&gt;
&lt;p&gt;And, truthfully, in the early days, the team performs well here. They have a direct line to Engineering through the CTO, and the CTO can sponsor their inclusion in activities that bring them close to Marketing and Sales; the Marketing teams often need to consult the CTO on messaging for the technology things the company is doing, and Sales will often reach out to the CTO for the Technical Sales support it needs in tough sales cycles. They can also work closely with Recruiting to help hit recruiting targets.&lt;/p&gt;
&lt;p&gt;Seems like a perfect fit!&lt;/p&gt;
&lt;p&gt;Ironically, the fact that the OCTO gives the DevRel team to be flexible and free also often undermines the team&apos;s long-term success. So long as the CTO is personally engaged in seeing the team succeed, the DevRel team can do some good things, but without the CTO&apos;s constant support, they often start to lose momentum and ground, and eventually wither away, &lt;em&gt;because the rest of the company doesn&apos;t know how to interact with them on an organizational footing.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Each department within an organization needs to know how to interact with its peer organizations, and often this is done (somewhat indirectly) through the establishment of processes and metrics. Departments hold each other indirectly (and sometimes directly) accountable through these: Marketing needed a feature, so it used an internal process to put it on Engineering&apos;s backlog, who then connected with Sales to see how the feature was received, all of this described and measured via a variety of metrics to help with decision-making. When the DevRel team is a &amp;quot;special project&amp;quot; of the CTO&apos;s, those processes and metrics have a tendency to be short-circuited, in the interests of making the CTO happy, and the rest of the company never quite gets into a rhythm of where and how DevRel fits in.&lt;/p&gt;
&lt;p&gt;Then--as inevitably happens--when the CTO no longer is putting the DevRel team on their &amp;quot;short list&amp;quot; of personal projects, either because the team has been around long enough that it feels like they should be able to survive &amp;quot;on their own&amp;quot;, or because the CTO has moved on and a new CTO is now prioritizing other things, the DevRel team has lost their sponsor and suddenly they have a short window in which to figure out where and how they fit into the organizational mix.&lt;/p&gt;
&lt;h2&gt;DevRel goes... where, then?&lt;/h2&gt;
&lt;p&gt;The DevRel organization&apos;s goals are not the same as Engineering&apos;s goals, nor are they aligned perfectly with Marketing&apos;s or Sales&apos;. It isn&apos;t unusual for organizations to &amp;quot;break out&amp;quot; of one or another this way--a long time ago, Marketing and Sales used to be unified into a single organization, until the realization became widespread that their goals were different. The same often happens with the Public Relations team (now often referred to as &amp;quot;Communications&amp;quot; or &amp;quot;Comms&amp;quot;), which has deep ties to Marketing, Sales, but also Legal and HR. Legal used to be buried inside of Operations. And so on. &lt;em&gt;Each top-level organization should be (needs to be) able to pursue its goals independent of the others, and the leader at the top of that organization needs to be able to meet with peers to accomplish this.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If the goal of the DevRel team isn&apos;t completely aligned with any of Engineering, Marketing, or Sales, then where in the organization does it go? The conclusion drawn here is actually not surprising, once we stop to think about it: &lt;strong&gt;&lt;em&gt;Developer Relations deserves to be its own top-level organization within the company.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Just as companies are realizing the benefits of having a &amp;quot;Chief Marketing Officer&amp;quot; and a &amp;quot;Chief Communications Officer&amp;quot; and a &amp;quot;Chief Information Security Officer&amp;quot;, a &amp;quot;Chief Developer Relations Officer&amp;quot; reporting directly to the CEO and providing the guidance and leadership to the CxO suite around the art and science of Developer Relations makes sense. Alternatively, if the &amp;quot;CDRO&amp;quot; title seems a touch pretentious, and the company lacks a CMO or CISO, then it&apos;s probably more appropriate to call it a &amp;quot;VP, Developer Relations&amp;quot;, again reporting directly to the CEO or CTO as a peer to the VP of Marketing, VP of Sales, and VP of Engineering. (Who reports to whom depends on the organization, but in general the VPs all end up sitting in the same room together anyway, so at that point it&apos;s a little moot.)&lt;/p&gt;
&lt;p&gt;This is not to say that DevRel is ever going to be at the same size as any of the others--it&apos;s hard to imagine a DevRel team that will span hundreds, much less &lt;em&gt;thousands&lt;/em&gt;, of individuals. But the same is actually true of a lot of departments within an organization. Legal, for example, is generally not going to be hundreds of people in size except in the largest of companies. PR, similarly, can be made up of a dozen folks supporting thousands or tens of thousands.&lt;/p&gt;
&lt;p&gt;The DevRel team being at a level reporting directly into the C-Suite means that now the CDRO or VP of DevRel establishes high-level goals and metric targets suitable for the team, but in conjunction with the overall goals of the company as a whole. If the company needs to make a major Marketing push because Engineering is releasing a new version, DevRel can adjust goals to provide tutorials and samples, as well as work directly with Marketing to get the Dev Advocates out into conferences and podcasts to talk about the new release and features. It can allocate some time to go with the Sales folks to help sell the new version. And so on. By allowing the DevRel team to draw its own goals and objectives--not to mention argue for its own budget and headcount alongside those teams--in direct consultation with its peers in Engineering, Sales, Marketing, HR, and the CEO and CTO, the DevRel team establishes itself as a team player with a clear mission and well-understood set of activities and metrics.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;../2022/devrel-for-all-companies.html&quot;&gt;Every company needs a DevRel team&lt;/a&gt;, and it&apos;s high time we saw the importance of the developer community as large enough to merit its own organization dedicated to interact and grow with it.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>You Want Modules, Not Microservices</title>
      <link>http://blogs.newardassociates.com/blog/2023/you-want-modules-not-microservices.html</link>
      <pubDate>Mon, 2 Jan 2023 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2023/you-want-modules-not-microservices.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Architecture is hard sometimes--people keep offering up some new idea that quickly becomes the mainstream &amp;quot;way to do it&amp;quot; without any context or nuance, and the industry, desperate to find ways to improve their architecture, snaps it up without hesitation. Microservices was the latest in the trend, and it&apos;s time we dissected the idea and got to the real root of what&apos;s going on.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2&gt;At the heart of microservices, we&apos;re told we&apos;ll find...&lt;/h2&gt;
&lt;p&gt;... Lots of Good Things (TM)!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;Scalability&amp;quot;: &amp;quot;Code can be broken into smaller parts that can be developed, tested, deployed, and updated independently.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Focus&amp;quot;: &amp;quot;... developer focuses on solving business problems and business logic.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Availability&amp;quot;: &amp;quot;back-end data must always be available for a wide range of devices... .&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Simplicity&amp;quot;: &amp;quot;provides simplified development of large scale enterprise level application.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Responsiveness&amp;quot;: &amp;quot;... enables distributed applications to scale is response to changing transaction loads... .&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Reliability&amp;quot;: &amp;quot;Ensures no single point of failure by providing replicated server groups that can continue when something breaks. Restores the running application to good condition after failures occur.&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These all sound relatively familiar, I&apos;d imagine, but the fun part about those six quotes is that two were taken from microservices literature (blog posts, papers, etc), two from twenty-years-ago EJB literature, and two from Oracle Tuxedo, which is forty-plus-years-ago technology. Can you spot which went to which?&lt;/p&gt;
&lt;p&gt;We have a tendency in this industry to re-use our hype points over and over again.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Those who cannot remember the past are condemned to repeat it.&amp;quot; --&lt;a href=&quot;https://americanart.si.edu/artwork/those-who-cannot-remember-past-are-condemned-repeat-it-george-santayana-life-reason-1905&quot;&gt;George Santanyana, The Life of Reason (1905)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With respect to the microservices hype, &lt;a href=&quot;https://www.integrella.com/expertise/microservices/&quot;&gt;one company&apos;s blog post&lt;/a&gt; offers &lt;strong&gt;10&lt;/strong&gt; reasons to charge into microservices:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;They promote big data best practices.&lt;/strong&gt; Microservices naturally fit within a data pipeline-oriented architecture, which aligns with the way big data should be collected, ingested, processed and delivered. Each step in a data pipeline handles one small task in the form of a microservice.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They are relatively easy to build and maintain.&lt;/strong&gt; Their single-purpose design means they can be built and maintained by smaller teams. Each team can be cross-functional while also specialise in a subset of the microservices in a solution.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They enable higher-quality code.&lt;/strong&gt; Modularising an overall solution into discrete components helps application development teams focus on one small part at a time. This simplifies the overall coding and testing process.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They simplify cross-team co-ordination.&lt;/strong&gt; Unlike traditional service-oriented architectures (SOAs), which typically involve heavyweight inter-process communications protocols, microservices use event-streaming technologies to enable easier integration.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They enable real-time processing.&lt;/strong&gt; At the core of a microservices architecture is a publish-subscribe framework, enabling data processing in real time to deliver immediate output and insights.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They facilitate rapid growth.&lt;/strong&gt; Microservices enable code and data reuse the modular architecture, making it easier to deploy more data-driven use cases and solutions for added business value.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They enable more outputs.&lt;/strong&gt; Data sets often are presented in different ways to different audiences; microservices simplify the way data can be extracted for various end users.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Easier to assess updates in the application life cycle.&lt;/strong&gt; Advanced analytics environments, including those for machine learning, need ways to assess existing computational models against newly created models. A-B and multivariate testing in a microservices architecture enable users to validate their updated models.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They enable scale.&lt;/strong&gt; Scalability is about more than the ability to handle more volume. It’s also about the effort involved. Microservices make it easier to identify scaling bottlenecks and then resolve those bottlenecks at a per-microservice level.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Many popular tools are available.&lt;/strong&gt; A variety of technologies in the big data world, including the open-source community, work well in a microservices architecture. Apache Hadoop, Apache Spark, NoSQL databases and many streaming analytics tools can be used for microservices. We are also proud to partner with Pivotal in this area.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let&apos;s take a second and examine each of those, but this time in light of prior art:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;They promote big data best practices.&lt;/strong&gt; &lt;a href=&quot;/patterns/behavioral/PipesAndFilters&quot;&gt;Pipes-and-filters&lt;/a&gt; architectures have been a part of the software scene since the 70s, when &lt;a href=&quot;https://en.wikipedia.org/wiki/Unix_philosophy&quot;&gt;Unixes promoted several ideas&lt;/a&gt;:
&lt;ol&gt;
&lt;li&gt;Make each program do one thing well. To do a new job, build afresh rather than complicate old programs by adding new &amp;quot;features&amp;quot;.&lt;/li&gt;
&lt;li&gt;Expect the output of every program to become the input to another, as yet unknown, program. Don&apos;t clutter output with extraneous information. Avoid stringently columnar or binary input formats. Don&apos;t insist on interactive input.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They are relatively easy to build and maintain.&lt;/strong&gt; See the Unix philosophy, above.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They enable higher-quality code.&lt;/strong&gt; If focusing on one small part at a time helps improve quality, then see the Unix philosophy, above.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They simplify cross-team co-ordination.&lt;/strong&gt; This one is interesting; it suggests that &amp;quot;service-oriented architectures (SOAs) ... typically involve heavyweight inter-process communications protocols&amp;quot;--like JSON over HTTP? Or is that taken to mean that all SOA requires SOAP, WSDL, XML Schema and the full collection of WS-* specifications? Ironically, nothing about a microservice in any way &lt;em&gt;prevents&lt;/em&gt; it from using any of those &amp;quot;heavyweight&amp;quot; protocols, and some microservices are even suggsting the use of gRPC, a binary protocol that bears closer resemblance to IIOP, from CORBA, which was the &amp;quot;heavyweight protocol&amp;quot; predecessor to... SOAP, WSDL, XML Schema, and the full collection of WS-* specifications.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They enable real-time processing.&lt;/strong&gt; Real-time processing has actually been a &amp;quot;thing&amp;quot; for quite a while, and while many such systems use a pub-sub or &amp;quot;event bus&amp;quot; model to do it, it hardly requires microservices to do it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They facilitate rapid growth.&lt;/strong&gt; &amp;quot;Reuse the modular architecture&amp;quot;--do we even have a count of how many different things have all promoted &amp;quot;reuse&amp;quot; as a selling point? Languages certainly have done it (OOP, functional languages, procedural languages), libraries, frameworks.... One day I want to see something hyped that explicitly says &amp;quot;Screw reuse. We don&apos;t care about that.&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They enable more outputs.&lt;/strong&gt; &amp;quot;Data sets often are presented in different ways to different audiences&amp;quot;--that sounds a great deal like the &lt;a href=&quot;https://www.sap.com/products/technology-platform/crystal-reports.html&quot;&gt;Crystal Reports&lt;/a&gt; home page.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Easier to assess updates in the application life cycle.&lt;/strong&gt; The need to &amp;quot;assess existing computational models against newly created models&amp;quot; for machine learning and advanced analytics environments... kinda sounds like a large pile of action words thrown together with little substance behind them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They enable scale.&lt;/strong&gt; How funny--the same was said of EJB, transactional middleware processing (a la Tuxedo), and mainframes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Many popular tools are available.&lt;/strong&gt; I don&apos;t think I have to really work hard to point out that tools have always been available for every major hype that&apos;s come through our industry--particularly after the hype has taken root for a while. Most readers won&apos;t even be old enough to remember &lt;a href=&quot;https://en.wikipedia.org/wiki/Computer-aided_software_engineering&quot;&gt;CASE tools&lt;/a&gt; but maybe they&apos;ll remember &lt;a href=&quot;https://en.wikipedia.org/wiki/List_of_Unified_Modeling_Language_tools&quot;&gt;UML&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But the discerning reader will notice that there is a pretty common theme to about half of the points above--the idea of creating and maintaining small, independent &amp;quot;chunks&amp;quot; of code and data, versioned apart from one another, using common inputs and outputs to enable a larger integration of the system. It&apos;s almost as if...&lt;/p&gt;
&lt;h2&gt;At the heart of microservices, we find...&lt;/h2&gt;
&lt;p&gt;... modules.&lt;/p&gt;
&lt;p&gt;Yup, the lowly &amp;quot;module&amp;quot;, that core concept that has been at the heart of most programming languages since the 1970s. (Even earlier, though it was harder to do with older languages that didn&apos;t incorporate the module as a first-class core concept.) Call them &amp;quot;assemblies&amp;quot; on the CLR (C#, F#, Visual Basic, ...), &amp;quot;JARs&amp;quot; or &amp;quot;packages&amp;quot; on the JVM (Java, Kotlin, Clojure, Scala, Groovy, ...), or dynamically-link libraries from your favorite operating system (DLLs on Windows, &lt;code&gt;so&lt;/code&gt;s or &lt;code&gt;a&lt;/code&gt;s on *nixes, and of course macOS has the &amp;quot;Frameworks&amp;quot; tucked away inside the /Library directories), but at a conceptual level, they&apos;re all modules. Each has a different internal format, but each serves the same basic purpose: an independently-built, -managed, -versioned, and -deployed unit of code that can be reused.&lt;/p&gt;
&lt;p&gt;Consider this working definition of a module, quoted from one of Computer Science&apos;s foundational papers:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;A well-defined segmentation of the project effort ensures system modularity. Each task forms a separate, distinct program module. At implementation time each module and its inputs and outputs are well-defined, there is no confusion in the intended interface with other system modules. At checkout time the integrity of the module is tested independently; there are few scheduling problems in synchronizing the completion of several tasks before checkout can begin. Finally, the system is maintained in modular fashion; system errors and deficiencies can be traced to specific system modules, thus limiting the scope of detailed error searching.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This comes from David Parnas&apos; seminal paper, &lt;a href=&quot;https://www.win.tue.nl/~wstomv/edu/2ip30/references/criteria_for_modularization.pdf&quot;&gt;&amp;quot;On the Criteria To Be Used in Decomposing Systems into Modules&amp;quot;&lt;/a&gt;, written in 1971--over 50 years ago at the time of this writing. The well-defined &amp;quot;separate, distinct program modules&amp;quot; covers about half of the suggested benefits of microservices, and we&apos;ve been able to do that for fifty years.&lt;/p&gt;
&lt;p&gt;So why the hullabaloo over microservices?&lt;/p&gt;
&lt;p&gt;Because microservices were really never about microservices, or services, or even distributed systems.&lt;/p&gt;
&lt;h2&gt;At the heart of microservices, we should find...&lt;/h2&gt;
&lt;p&gt;... organizational clarity.&lt;/p&gt;
&lt;p&gt;Amazon, one of the first companies to openly discuss the microservice concept, really wasn&apos;t trying to push the architectural principle as much as they were trying to push the idea of an independent development team whose blockers were few and far between. Waiting on the DBA team for schema changes? QA needs a build to test so they can find bugs? Or are we waiting on the infrastructure team to procure a server? Or the UX team to create a prototype for the presentation?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;SCHHHLLLUURRRRRRRPPPPpppp...&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;That sound you hear is the development team aggregating ownership of any and all of those dependencies that could (and frequently would) block them from moving forward. It meant that the teams were a small microcosm of the average IT team&apos;s various parts (analysis, development, design, testing, data management, deployment, administration, and more). It did mean that now teams either had to be assembled from a variety of disparate skillsets, or else we had to require the complete set of skills in each team member (the so-called &amp;quot;Full Stack Developer&amp;quot;), which meant that hiring these folks became infinitely trickier. It also meant that now the team was responsible for its own production outages, meaning the team itself now has to be given on-call responsibilities (and the commensurate payroll and legal implications that go along with that). But, when all that was navigated, it meant that each team could build their artifact independently of one another, constrained by nothing other than time and the physics of how fast fingers can fly over a keyboard.&lt;/p&gt;
&lt;p&gt;In theory, anyway.&lt;/p&gt;
&lt;h2&gt;At the heart of microservices, we often find...&lt;/h2&gt;
&lt;p&gt;... &lt;a href=&quot;https://architecturenotes.co/fallacies-of-distributed-systems/&quot;&gt;the Fallacies of Distributed Computing&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For those not familiar with them, the Fallacies were first coined by Peter Deutsch in a presentation to his peers at Sun--back in the 80s. They reappeared in the 1994 seminal paper &lt;a href=&quot;https://scholar.harvard.edu/files/waldo/files/waldo-94.pdf&quot;&gt;&amp;quot;A Note on Distributed Computing&amp;quot;&lt;/a&gt; by Ann Wolrath and Jim Waldo, and they both essentially say the same thing:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Getting distributed systems right--performance, reliability, scalability, whatever &amp;quot;right&amp;quot; means--is hard.&amp;quot; (loosely paraphrased)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When we decomposed the system into in-memory modules running on a single operating system node, the costs of passing data across process or library boundaries was pretty negligble, even fifty years ago. When passing that data across network lines, though--as most microservices do--adds five to seven orders of magnitude greater latency to the communication. That is not simply something we can &amp;quot;scale away&amp;quot; by adding more nodes to the network; that actually makes the problem worse.&lt;/p&gt;
&lt;p&gt;Yes, some of that can be made less relevant by hosting the microservices on the same machine, usually by loading them into a cluster of virtual machines running containerized images of the independent microservice. (As in, using Docker Compose or Kubernetes to host a collection of Docker containers.) Doing so, however, adds latency between the virtual machine process boundaries (because we have to move data up and down the virtual networking stack, in accordance with the rules of the seven-layer model, even if some of those layers are being entirely emulated), and still creates the reliability issue of running on a single node.&lt;/p&gt;
&lt;p&gt;What&apos;s worse, even as we start to wrestle with the Fallacies of Distributed Computing, we begin to run into a related, but separate, set of problems: &lt;a href=&quot;http://blogs.newardassociates.com/blog/2016/enterprise-computing-fallacies.html&quot;&gt;The Fallacies of Enterprise Computing&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;At the heart of microservices, we need...&lt;/h2&gt;
&lt;p&gt;... to start rethinking what we really need.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Do you need to decompose the problem into independent entities?&lt;/em&gt;&lt;/strong&gt; You can do that by embracing standalone processes hosted in Docker containers, &lt;strong&gt;or&lt;/strong&gt; you can do that by embracing standalone modules in an application server that obey a standardized API convention, &lt;strong&gt;or&lt;/strong&gt; a variety of other options. This isn&apos;t a technical problem that requires abandoning anything that&apos;s already been built--it can be done using technologies from anywhere in the last twenty years, including servlets, ASP.NET, Ruby, Python, C++, maybe even &lt;em&gt;shudder&lt;/em&gt; Perl. &lt;strong&gt;&lt;em&gt;The key is to establish that common architectural backplane with well-understood integration and communication conventions, whatever you want or need it to be.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Do you need to reduce the dependencies your development team is facing?&lt;/em&gt;&lt;/strong&gt; Then begin by looking at those dependencies and working with partners to determine which of them you can bring into the team&apos;s wheelhouse. If the organization doesn&apos;t want to officially break up the &amp;quot;skill-centric&amp;quot; ontology of its org chart (meaning you have a &amp;quot;database&amp;quot; group, a &amp;quot;infrastructure&amp;quot; group, and a &amp;quot;QA&amp;quot; group as peers to your &amp;quot;development&amp;quot; group), then work with the senior executives to at least allow for a &amp;quot;dotted-line&amp;quot; reporting structure, so there&apos;s individuals from each group that are now &amp;quot;matrixed&amp;quot; in on a single team. But, most importantly, make sure that team has a crystal-clear vision of what it is they&apos;re trying to build, and they can confidently describe the heart of their service/microservice/module to any random stranger walking by on the street. &lt;strong&gt;&lt;em&gt;The key is to give the team the direction and goal, the autonomy to accomplish it, and the clarion call to get it done.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It really boils down to these two things, which really, really, really have nothing to do with each other except tangentially.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>What I Want to Build</title>
      <link>http://blogs.newardassociates.com/blog/2023/what-i-want-to-build.html</link>
      <pubDate>Mon, 2 Jan 2023 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2023/what-i-want-to-build.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; What would you do if you could do anything? Or, if you&apos;re a developer-manager-type, what would you build? Given that we&apos;re starting 2023, I thought it a reasonable time to take a stab at putting it out there into the universe.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Part of the motivation here comes from the interview cycles I&apos;ve been through; I&apos;ve been asked the &amp;quot;What do you &lt;em&gt;really&lt;/em&gt; want to do?&amp;quot; question many times, and it&apos;s always tricky to answer in the moment. Being the developer-manager type, I thought it might be useful to answer it more easily by casting the question in the light of &lt;em&gt;what would I really want to build&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;For the record, if you&apos;re reading this because you&apos;re a recruiter (and either you found this on your own or I sent you here), this isn&apos;t necessarily what I &lt;em&gt;expect&lt;/em&gt; to build in my next job, but if any of these sound interesting, I&apos;d love to put the team together to make it happen. But if your needs are different, let&apos;s still talk--these&apos;ll keep for a while, or I&apos;ll tackle them as a side project. &lt;em&gt;shrug&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;Big Projects&lt;/h1&gt;
&lt;p&gt;Let&apos;s start with the epic-level ideas that are probably way too big for any one person to tackle.&lt;/p&gt;
&lt;p&gt;One common theme you&apos;ll find to a lot of these epics is the idea of elevating the abstraction level: Martin Odersky (creator of Scala) once commented that one of the key goals of Scala was to get programmers to worry less about the &lt;em&gt;physical&lt;/em&gt; details of programming (what&apos;s a field, what&apos;s a method, what&apos;s a reference, etc) and focus more on the &lt;em&gt;concepts&lt;/em&gt; they were trying to express. That idea has stuck with me ever since.&lt;/p&gt;
&lt;h2&gt;A platform-oriented language&lt;/h2&gt;
&lt;p&gt;We&apos;ve had object-oriented languages for decades now, and the functional/functional-object hybrids for at least a decade, and neither really &amp;quot;moved the needle&amp;quot; on programming productivity or elevating the levels of abstraction. So what I&apos;d like to spend some time doing is building a language that knows how to build code for a &lt;em&gt;platform&lt;/em&gt;; that is to say, a language that has some interesting higher-level abstractions than your typical object language:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Service-oriented primitives.&lt;/em&gt;&lt;/strong&gt; &lt;a href=&quot;https://ballerina.io&quot;&gt;Ballerina&lt;/a&gt; and &lt;a href=&quot;https://darklang.com/&quot;&gt;Dark&lt;/a&gt; each have some interesting exemplars here, allowing us to build first-class service endpoints. Theoretically any wire protocol could or should be useful here, but one of the key things I&apos;d like this language to support is the &lt;a href=&quot;https://www.restfulobjects.org/spec/1.0/about.html&quot;&gt;Restful Object&lt;/a&gt; or the &lt;a href=&quot;https://stateless.group/hal_specification.html&quot;&gt;Hypertext Application Language&lt;/a&gt; specifications, making it self-descriptive to navigate through the entities online.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Persistence.&lt;/em&gt;&lt;/strong&gt; Honestly, there&apos;s so many different tools to persist an object to a data store, and most of the time any thoughts of optimizing the storage or retrieval is just wasted mental energy. Let&apos;s just let the compiler generate the details for loading and storing entities.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Design-by-Contract primitives.&lt;/em&gt;&lt;/strong&gt; Some languages have explored the idea of language-level primitives for invariant, pre- and post-condition enforcement (C++20 is incorporating it, even), and I see no reason why it can&apos;t elevate into a first-class contract.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;State-machine implementation.&lt;/em&gt;&lt;/strong&gt; So much of our implementation work is managing state transitions within an object or family of objects, so let&apos;s elevate that to a language level and let the compiler sort out the details.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Docker container artifact output.&lt;/em&gt;&lt;/strong&gt; Forget the traditional binaries we&apos;ve been churning out--the common output format is now Docker. Just have the compiler spit that out and be done with it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Observability and manageability built-in.&lt;/em&gt;&lt;/strong&gt; Just like virtual machine runtimes put hooks in to allow for easier debugging, profiling, and management, put the necessary hooks in to the generated service code to allow syslogd or Grafana or whatever the current standard-of-choice is to observe these things.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The goal here would be to build a language (on top of one of the existing enterprise ecosystems--likely the JVM or the CLR/.NET ecosystem, though there&apos;s really no reason it couldn&apos;t be NodeJS or Python or Ruby either)--that allows us to go from &amp;quot;single source file&amp;quot; to &amp;quot;working full-stack service&amp;quot; with a single compile/assemble step. Right now, &lt;strong&gt;&lt;em&gt;building services is too hard&lt;/em&gt;&lt;/strong&gt;, requiring too many different pieces assembled using too many different configuration files and languages, and while the flexibility is great across the entire industry, for any given company, there&apos;s likely a number of decisions (&amp;quot;corporate standards&amp;quot;) that could reduce that flexibility significantly enough to allow for a language (which can always allow for exceptions if the language is designed to do so) to be able to generate most of that out of source.&lt;/p&gt;
&lt;p&gt;And man, imagine how quickly you could innovate if you had this.... Build a fully ready-to-deploy service from a single source file?&lt;/p&gt;
&lt;h2&gt;An application-oriented language&lt;/h2&gt;
&lt;p&gt;Remember the &amp;quot;good old days&amp;quot; of Visual Basic and Visual FoxPro and Paradox and a bunch of those other 4GLs, when a single developer could build a working application, database through UI, all by themselves? We&apos;ve lost that somewhere along the way, and as a result, what we call the &amp;quot;citizen developer&amp;quot; is now forced to learn Python and NoSQLs and HTML and CSS and JS and and and....&lt;/p&gt;
&lt;p&gt;Bleah. Building a user-facing app today takes &lt;em&gt;way&lt;/em&gt; too much work, because the developer building an app today has about a thousand different physical concerns to deal with before ever dealing with the logic and concept of the app itself.&lt;/p&gt;
&lt;p&gt;There&apos;s ways to build an app on modern infrastructure and standards that could simplify all of this. The &amp;quot;low-code&amp;quot; movement is trying to capture this, but they&apos;re doing it with drag-and-drop application generators that don&apos;t show you code (or very small parts of it) or that generate vast amounts of code. Give us a nice high-level language, perhaps drawing signficant inspiration from Smalltalk and Io, that work off of a simple mental model, provide significant high-level out-of-the-box &amp;quot;primitives&amp;quot; (like, forget &amp;quot;string&amp;quot;--how about &amp;quot;Name&amp;quot;, &amp;quot;SSN&amp;quot;, &amp;quot;Date&amp;quot;, &amp;quot;Age&amp;quot;, and other really common data types that we always somehow want to reduce down to &amp;quot;string&amp;quot;s or &amp;quot;int&amp;quot;s?) complete with built-in validation and rules, and let them build applications that know how to present and store themselves? Make persistence an implementation detail (but cloud-friendly so it settles naturally on top of the existing clouds), make user interface a core concern that intermingles with the low-code logic (which gets replicated across both client and server tiers), and you have a very interesting language/platform for people to build some &amp;quot;personal applications&amp;quot; that would never, ever, EVER need to scale to Google levels.&lt;/p&gt;
&lt;p&gt;Think Naked Objects meets Self meets a very reduced set of Python, over the Web and mobile devices, persisting as an implementation detail tucked away from the citizen developer (but knows how to export and/or provide an HTTP-based API for high-code access). The foundations are there, we just need to put the parts together.&lt;/p&gt;
&lt;h2&gt;An open RPG fantasy engine/app&lt;/h2&gt;
&lt;p&gt;I was a huge fan of the AD&amp;amp;D computer video games of the 90s: Pool of Radiance, Secret of the Silver Blades, and so on. It probably was helped by the fact that I owned a copy of the first Wizardry and Bards Tale that were the AD&amp;amp;D video games&apos; spiritual predecessors (which was only fair, since they both drew from the tabletop RPG as inspiration), but I hated the fact that once you&apos;d played the game, you were essentially &amp;quot;done&amp;quot; until a new game came out.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.akamai.steamstatic.com/steam/apps/1882370/ss_12950922a50a1f30c6d4c961817eb0ee9377cebe.1920x1080.jpg?t=1648566548&quot; alt=&quot;Pool of Radiance ad graphic&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Meanwhile, over the years since, games like Battle of Wesnoth changed the story--a game engine could provide the mechanics and display and so on, while scenarios could be built against an open specification, allowing for literally an infinite number of possible plays. Plus, if we&apos;re going to go &amp;quot;open&amp;quot;, let&apos;s open it up the entire way, to allow for expansion spells, skills, classes, anything we can imagine.&lt;/p&gt;
&lt;p&gt;Mechanically, the classic fantasy RPG is not all that complicated once you pull the rules out of the equation, and the rules themselves operate by some core mechanics that (I think) can be extracted into an inference-like engine that can recognize how to deal with various combination scenarios. I&apos;m thinking that the D&amp;amp;D 3.5e ruleset is the best way to go here--it&apos;s not the latest (so hopefully avoiding some of the copyright issues that might arise), and the principal critique was all the special-case scenarios in the rules that would be perfect to be captured in a game setting.&lt;/p&gt;
&lt;p&gt;Essentially, I&apos;m thinking a JavaScript engine hosted inside the game, with the user interface interacting with the engine, JavaScript because it&apos;s a popular language understood by many and therefore representing a lower barrier-to-entry for those gamer-types who want to populate the ecosystem. &amp;quot;Modules&amp;quot; (in the spirit of what we used to call the pre-canned adventures TSR used to sell) would be bundles of JavaScript files written by third parties, along with images or audio files for new monsters or scenes.&lt;/p&gt;
&lt;p&gt;The various interactive-fiction engines also hold some level of intrigue here, as this goal is in large part the same as theirs, but they focus on the interactive storytelling, not the mechanics of hack, slash, loot, level-up, repeat. Still, if I do go down the path of thinking about a custom language for this thing, the TADS, Inform7, and Dialog languages all have their appeal as models for how to build out the non-data parts of the module.&lt;/p&gt;
&lt;p&gt;The UI would be very simplistic: probably console for the v0.1, then v1 moving to the forward-facing view popularized by Wizardry and Bard&apos;s Tale, then maybe v2 shifting combats to the isomophic grid view, but probably not much further than that. The goal here would be to focus on the extensibility of the game, not trying to compete with Baldur&apos;s Gate or later.&lt;/p&gt;
&lt;p&gt;Long-term, this could even morph into some kind of multi-player thing, but frankly, if I wanted to play D&amp;amp;D with friends, I would grab the books and head down the hallway in the college dorm--today, I&apos;d just send them a Roll20 link. The video games were for when I just wanted to hack-and-slash my way through the dungeon as a loner late at night instead of doing my homework.&lt;/p&gt;
&lt;h2&gt;A database built from GC principles&lt;/h2&gt;
&lt;p&gt;With the rise of NoSQLs--by which I mean non-relational databases--as a storage concept, and the prevalence of needs to track data&apos;s usage and ownership, there&apos;s a small part of me that wonders at the power of bringing some of the mark-sweep semantics of automatic memory management into the database tier. In particular, I think it would be powerful if data could know its origins--where it came from, who owned it, who touched it last, and so on--in a way that most databases currently lack. It wouldn&apos;t likely be the most high-performance system in the world, but by this point we&apos;ve seen that performance is a relative term; we can afford to spend some additional cycles and some additional bytes on overhead if it means having necessary business functionality baked in (like being able to make audit tracking so very much easier).&lt;/p&gt;
&lt;p&gt;Some of this is derived from the &amp;quot;worlds&amp;quot; concept defined in &lt;a href=&quot;https://web.cs.ucla.edu/~todd/theses/warth_dissertation.pdf&quot;&gt;Alessandro Warth&apos;s thesis on OMeta&lt;/a&gt;: &amp;quot;We can think of a program as an agency set up to accomplish or reach one or more goals. For some goals--such as adding up numbers--there is a simple straight road in most programming languages. Other goals--such as finding the square root of a number--will require some search, but can still be homed in on very effectively. For more complex goals--such as certain kinds of parsing, problem solving, and editing in a user interface--it may not be possible for the program to simply home in on the desired result; instead, it may need to experiment with multiple alternatives, sometimes making mistakes that require retraction in order to make fresh starts.&lt;/p&gt;
&lt;p&gt;&amp;quot;For some goals of this latter kind, it might be a good idea to use backtracking, as in Prolog (it would also be a good idea to automatically undo asserts that are backtracked over, which does not happen in Prolog). For problem solving on a larger scale, it might be a better ploy to use &amp;quot;possible worlds&amp;quot;, perhaps even parallel possible worlds that can report progress to a coordination agent that is trying to make choices about best paths. If the problem terrain is really rough and tricky--a veritable &amp;quot;elephant to blind men&amp;quot;--then we might want to use the metaphor of dispatching &amp;quot;scouts&amp;quot; (or &amp;quot;scientists&amp;quot;) with walkie-talkies who can simultaneously explore different parts and intercommunicate to gradually build up a better model of the obstacles and the possible routes around them.&lt;/p&gt;
&lt;p&gt;&amp;quot;Unfortunately, the nature of state in traditional programming languages makes this &amp;quot;experimental&amp;quot; style of programming impractical. For example, because the state of a program is scattered around the computer’s memory in several kinds of data structures (e.g., arrays, objects, and activation records), it is both messy and difficult to undo the side effects of an action that has been performed by the program. Also, because there is only one &amp;quot;program state&amp;quot;, a program cannot explore multiple alternatives concurrently.&lt;/p&gt;
&lt;p&gt;&amp;quot;My approach to solving this problem was to introduce a new language construct that reifies the notion of program state as a first-class object. I call this construct a &lt;em&gt;world&lt;/em&gt;. All computation takes place inside a world, which captures all of the side effects--changes to global, local, and instance variables, arrays, etc.--that happen inside it. Worlds provide multiple views on the state of a program, and mechanisms for interacting among these views. They subsume the mechanisms of backtracking, tentative evaluation, possible worlds, undo, and many similar control and state regimes.&lt;/p&gt;
&lt;p&gt;&amp;quot;We shall see that while it is often convenient for programmers to use worlds directly, there are also cases where worlds are better suited as a kind of &amp;quot;semantic building block&amp;quot; for higher-level language constructs.&amp;quot;&lt;/p&gt;
&lt;p&gt;It got me to thinking--if worlds need to track changes and be able to backtrack, it means that state is using state to track changes to its state. Generally we just think of databases as a repository of standalone facts with little to no additional supporting metadata. But what if we start thinking about data in a database as a derivative of this &amp;quot;world&amp;quot; concept, where state knows its part of a larger state, including information about when/where/who/how it is used or from?&lt;/p&gt;
&lt;p&gt;If, for example, a data element is deleted, we could track all of the places this data touches and/or is incorporated, and that in turn could/should trigger discussions about what to happen to that state--perhaps even automatically, without requiring programmer interaction. One could argue that this is simply making use of a graph database, but I think there&apos;s a notable distinction between the &amp;quot;shape&amp;quot; of the &lt;em&gt;raw&lt;/em&gt; data (as presented to the user of the database), and the internal implementation and tracking information &lt;em&gt;metadata&lt;/em&gt; that could be used to drive these sorts of things. Much as an object in memory in Java or C# has additional information (metadata) about it that isn&apos;t visible to the Java/C# developer, yet is highly necessary to enable things like synchronization, automatic memory management, and more (type information, for example, is necessary when calculating how much space to allocate for a new object).&lt;/p&gt;
&lt;h2&gt;A persistent programming language&lt;/h2&gt;
&lt;p&gt;MUMPS has fascinated me since I first discovered it (recently), in that global variable declarations in MUMPS are, in fact, allocated space on disk.&lt;/p&gt;
&lt;p&gt;To quote Keanu: &lt;em&gt;Whoa.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;That&apos;s some interesting thought right there: I allocate a variable, and it&apos;s immediately (and silently) stored to disk. Updates write to disk. Accesses read from the disk (but could also be cached, since the compiler is the one entirely in charge and has knowledge of when the variable is written).&lt;/p&gt;
&lt;p&gt;And if the state of the program is entirely managed in terms of these persistent variables, &lt;em&gt;the entire state of the program is automatically preserved in the event of a crash.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;What if we took a traditional OO language and added this concept of &amp;quot;persistent types&amp;quot; to go along with the &amp;quot;transient types&amp;quot; we already use? (It would probably be in the form of a lexical modifier--&lt;code&gt;string name&lt;/code&gt; being a traditional transient variable, while &lt;code&gt;string^ name&lt;/code&gt; is a persistent one.) You probably wouldn&apos;t use it for all of your variables, but for your &amp;quot;domain&amp;quot; and/or &amp;quot;transactional&amp;quot; data? I think that would solve a lot of interesting problems right out the door.&lt;/p&gt;
&lt;p&gt;There&apos;d be a few things that would need to be sorted out (identity semantics being one!), but it&apos;s definitely worth playing around with further, particularly for those programs which really need to be able to pick up again after a crash and don&apos;t have heavy persistence needs on that tier (because they store their data long-term in a database on a server, for example).&lt;/p&gt;
&lt;h2&gt;A service choreography engine&lt;/h2&gt;
&lt;p&gt;Lots of people built microservices, and then found that they needed to build services that choreographed process flow through those services. The danger here, of course, is that &amp;quot;choreography&amp;quot; is yet another word for &amp;quot;chatty distributed system&amp;quot;, and a major cause for performance nightmares in your microservice fabric.&lt;/p&gt;
&lt;p&gt;Part of the problem here is that applications built out of microservices want to retain control over the steps of the choreography, yet the thought of baking them into a traditional programming language that then in turn must be tested (with mocks and fakes and such) just makes the developers groan.&lt;/p&gt;
&lt;p&gt;What if we could abstract away the details, and hoist a &amp;quot;script&amp;quot; into the service fabric to do the choreography? Testing the script would be a helluvalot easier when the service mechanics are already all tested and deployed, and ideally the script would run out in the same tier as the services--that is, in the cloud.&lt;/p&gt;
&lt;p&gt;This speaks to the idea of an &amp;quot;orchestration&amp;quot; or &amp;quot;choreographer&amp;quot; service, accepting scripts as input, making the service calls, capturing the responses, and evaluating those results to decide where to go next with calls (if any). It feels somewhat like a &amp;quot;workflow service&amp;quot;, a la Camunda, but not something that&apos;s end-user-facing; more a developer-facing service that has dynamic overtones allowing it to be more flexible than a traditional compiled service.&lt;/p&gt;
&lt;p&gt;(Frankly, this one feels a little smaller than the others, I think.)&lt;/p&gt;
&lt;h1&gt;Smaller Projects&lt;/h1&gt;
&lt;p&gt;There&apos;s some smaller projects, some of which are really no bigger than an application demo, but interesting to me nevertheless, that I have on my TODO list.&lt;/p&gt;
&lt;h2&gt;Hearts Scorer&lt;/h2&gt;
&lt;p&gt;My family plays the card game Hearts a lot--my folks taught it to me, my wife knew how to play already when we met, and I taught it to my kids--and I&apos;m always the one who handles the scoring. But math is hard--so let&apos;s build an app! Sell it on the AppStore for $0.99, just because.&lt;/p&gt;
&lt;h2&gt;Spades Scorer&lt;/h2&gt;
&lt;p&gt;Same idea, different card game. Likewise, sell it.&lt;/p&gt;
&lt;h2&gt;Tic-Tac-Toe&lt;/h2&gt;
&lt;p&gt;I&apos;ve been working on a libgdx version of TicTacToe (for mobile devices, but easily for desktop or Web too), and a Ballerina implementation of a TicTacToe REST server. Time to marry the two up, and include some AI so people who want to play single-player can do so.&lt;/p&gt;
&lt;h2&gt;&amp;quot;GSpaces&amp;quot;&lt;/h2&gt;
&lt;p&gt;A while back, academia posited this concept of &amp;quot;distributed spaces&amp;quot; or &amp;quot;tuple spaces&amp;quot; (as part of the Linda programming language), and with the rise of non-HTTP-based distribution tools (gRPC, Orleans, etc), I&apos;m curious to resurrect the idea and see how far it flies. You wouldn&apos;t replace your database with this, but for transitory state and/or state that wants/needs to live in memory across clusters, this could be an interesting tool.&lt;/p&gt;
&lt;h1&gt;And there&apos;s more....&lt;/h1&gt;
&lt;p&gt;... but most of the other ideas are just one- or two-sentence ideas floating around in my head.&lt;/p&gt;
&lt;p&gt;Somebody got a million bucks they want to throw my way so I can explore any of these? Could be fun...&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Every Company Needs a Developer Relations Team</title>
      <link>http://blogs.newardassociates.com/blog/2022/devrel-for-all-companies.html</link>
      <pubDate>Sat, 31 Dec 2022 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2022/devrel-for-all-companies.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt;: In my &lt;a href=&quot;../2022/2022-tech-predictions.html&quot;&gt;2022 Tech Predictions&lt;/a&gt;, I asserted that more companies would be building DevRel teams, and I&apos;ve repeated that in my &lt;a href=&quot;../2023/2023-tech-predictions.html&quot;&gt;2023 Tech Predictions&lt;/a&gt;. I have reasons for that; I&apos;ve been at many wildly-different companies, many of which with wildly different business models, and I&apos;ve concluded that every company (that is in any way associated with software beyond a cursory level) in the post-2000 era has need of a Developer Relations department or organization. That said, DevRel is not the same at every company, and varies with the kind of things the company does to make money.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;These are bold words, and often generate reactions ranging from quizzical to &amp;quot;are you trying to sell me something?&amp;quot;. I stand by them, though, because &lt;em&gt;every company in the post-2000 era that does something with software--whether they buy it, use it, or build it--engages with developers in some way, and therefore needs to relate to them.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If you&apos;re still willing to hear me out, let&apos;s revisit my definition of Developer Relations:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;That part of the company that engages with developers, both internal and external to the company, for the purpose of using that relationship for net gain. This can take the form of many things, but ultimately, (a) it&apos;s aimed at developers, (b) it&apos;s intended to facilitate greater positivity to one or both sides, and (c) it centers around developer activities of one form or another (that is, it could be technical, &amp;quot;human skill&amp;quot;, or process, but it kinda-sorta has to be around the world of software development).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let&apos;s also consider a simple categorization of companies, according to my own (very biased) experience and perspective:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Developer-facing product companies.&lt;/strong&gt; Your Microsofts, Googles, JetBrains, and so on. These companies make and sell products that are sold directly to developers, making them the target audience and the source of interest and income for the company. These are the ones that pioneered the Developer Relations concept, and for that reason, these are often the companies that come to mind when thinking about DevRel. &lt;a href=&quot;https://en.wikipedia.org/wiki/Developer_relations&quot;&gt;Wikipedia&lt;/a&gt; calls these &amp;quot;Developer-First&amp;quot; companies, and says they have a &amp;quot;Business-to-Developer&amp;quot; (&lt;strong&gt;B2D&lt;/strong&gt;) business model. This makes sense, although I think there&apos;s still value in thinking in terms of companies buying the developer-centric product, as opposed to developers buying it for themselves. (But maybe that&apos;s splitting hairs.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Product companies where developers &amp;quot;value-add&amp;quot; indirectly.&lt;/strong&gt; These are companies Consider, for a moment, one of my previous employers, &lt;a href=&quot;https://www.smartsheet.com/&quot;&gt;Smartsheet&lt;/a&gt;. This is a product that does not sell directly to developers--in fact, it often finds itself in categories where professional developers are explicitly not allowed or desired (e.g., &amp;quot;low code&amp;quot; tools or &amp;quot;citizen developer&amp;quot; products). Wikipedia thinks of these as &amp;quot;Developer-Plus&amp;quot; companies, and thinks of them as business-to-business (&lt;strong&gt;B2B&lt;/strong&gt;) or business-to-consumer (&lt;strong&gt;B2C&lt;/strong&gt;) models, and says &amp;quot;While the primary focus of Developer-Plus companies is to create and sell products for businesses or consumers, they also make products or services available to developers which benefit or enhance their strategy including: opening new market channels, creating new use cases, contributing to innovation strategies, or optimizing/enhancing existing products.&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Companies where integration is a key core of the business.&lt;/strong&gt; &lt;a href=&quot;https://www.rocketmortgage.com&quot;&gt;Rocket Mortgage&lt;/a&gt; would fit this definition, since much of their ability to sell mortgages (which is clearly a non-developer-facing product!) depends on their ability to integrate with the other various financial players out in the world. Consumers won&apos;t see code, they won&apos;t touch code, but the value of the product will definitely grow (or shrink) depending on developers&apos; ability to connect &amp;quot;our stuff to other peoples&apos; stuff&amp;quot; (such as banks, escrow companies, title companies, credit organizations, and so on). It could be argued that this is more &amp;quot;Developer-Plus&amp;quot;, but we&apos;re starting to stretch the definitions some here; for some companies, being able to provide integration capabilities is &amp;quot;table stakes&amp;quot; and means the difference between a partnership or sale and a waste of salespeoples&apos; time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Consulting companies.&lt;/strong&gt; This is its own category primarily because there&apos;s so many of them, and they all have the same basic goal: Sell &lt;em&gt;their&lt;/em&gt; developers to companies that either don&apos;t have developers, don&apos;t have enough developers, or don&apos;t have the right developers. The company&apos;s core business model is in putting their smart developer people to work for you, regardless of what sort of developer people you already have--either in conjunction with your smart developer people, or as a complement to your overworked developer people, or as leaders to your less-smart developer people, and so on.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each of these companies needs a DevRel team, but for different reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Developer-facing product companies.&lt;/strong&gt; Pretty clearly the DevRel team&apos;s job here is a combination of marketing,sales (technical pre-sales, actually), and engineering:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Marketing&lt;/em&gt;: Brand recognition (getting them to understand that the product exists), product-fit awareness (having enough knowledge what the product does to be able to judge if it&apos;s worth exploring for a given problem), and getting them to try the product.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Sales&lt;/em&gt;: Working with developers to get past any obstacles they may have to buying the product, such as overcoming concerns about compatibility with other products, or the product&apos;s applicability for use in various scenarios, and so on. (If you&apos;re not sure this is really a DevRel role, consider how many blog posts and/or presentations you&apos;ve seen describing how Vendor Product X works in Vendor Cloud A or with Vendor Database G.)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Engineering&lt;/em&gt;: Providing developer support if/when the product doesn&apos;t execute as expected, or there&apos;s unexpected outcomes, or unanticipated obstacles, and so on, as well as providing examples for developers to follow so that their onboarding with the product is easier.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the most part, these are pretty self-descriptive, and I doubt most developer-types reading this would disagree strongly with this characterization.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Consulting companies.&lt;/strong&gt; The consulting company needs DevRel because consulting companies that cannot convince potential clients of the consulting company&apos;s technical skills and apititude don&apos;t stay in business for very long. We are smart consultants! Your company needs us! Thus, the consulting company&apos;s DevRel team needs to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Marketing&lt;/em&gt;: For a consulting company, marketing here really means &lt;strong&gt;brand recognition&lt;/strong&gt; (&amp;quot;We are smart people! Doing smart things!&amp;quot;), so that clients will already know about the company--and how smart their people are--by the time a salesperson connects with the potential client. &lt;a href=&quot;https://www.thoughtworks.com/&quot;&gt;ThoughtWorks&lt;/a&gt;, for example, coasted for the better part of a decade on the various activities of its Principal Scientist, Martin Fowler, who brought incomparable amounts of brand recognition to the company&apos;s name and brand. After a while, others at the company began doing some of their own brand recognition efforts, but Martin clearly was the cornerstone of the company&apos;s brand efforts for quite some time.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Sales&lt;/em&gt;: Most of the time, when a consulting company is looking to sell their services to a client, the client needs to be sure of a couple of things: one, that these people are not only smart about technology, but also about the kinds of problems the client is facing; two, that these people can work well with the client&apos;s people to get the project done; and three, that the consulting company has some success under its belt, such that this feels like a &amp;quot;good bet&amp;quot;. In these situations, it helps immensely to have one of the developer-types be in the room during the conversation, to speak (as a reasonable proxy) to the skills of the consultancy and offer up some examples of when/where the consultancy was able to succeed.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Engineering&lt;/em&gt;: Coming back around to the &amp;quot;bidirectional&amp;quot; nature of DevRel, in a consulting organization the DevRel team should be talking to your consultants (and their clients) to get a sense of what sorts of problems are being found routinely at a variety of different clients, so that your consulting company as a whole can be thinking about how to gain a competitive advantage over other companies by building reusable assets that can accelerate the teams&apos; productivity across both current and future clients. (Not doing that? Maybe you should be!) At the very least, the DevRel team can be serving as an incubator for the use of new languages and platforms to that same purpose.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Recruiting&lt;/em&gt;: In many consultancies, the best source of consultants is through the same venues and activities that DevRel engages--so consultants are encouraged to do those activities as a recruiting effort.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that in most consultancies, the current DevRel activities are generally done by the consultants themselves--Principals, Software Architects, senior consultants, and so on--but very, very few consultancies actually accept that this is a role in its own right, and most senior consultants who do this work do so during their non-billable time. In fact, even though most consultancies accept that Sales and Marketing are both activities that require being outside the umbrella of &amp;quot;billable hours&amp;quot;, anything that requires technical skills means those Sales and Marketing folks have to beg time from consultants--who are in turn now caught on the horns of the &amp;quot;If I do this it&apos;s non-billable time, and my end-of-year bonus is tied directly to my billable time percentage, so either I sacrifice my bonus or I&apos;m doing it off-the-clock as a volunteer effort.&amp;quot;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;NOTE:&lt;/em&gt;&lt;/strong&gt; If you&apos;re a consultancy, stop doing this! Or, rather, consider how much more effective your company could be at finding and placing consultants if the people doing it were doing it full-time, just as your Sales and Marketing folks are. Not to mention the opportunities it gives you to rotate consultants through this team so that they get some experience doing something other than code--it helps grow the company in a variety of ways.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Product companies where developers &amp;quot;value-add&amp;quot; indirectly.&lt;/strong&gt; These companies don&apos;t sell to developers, and in many cases, aren&apos;t even in the &amp;quot;tech business&amp;quot; at all; think about Netflix or Hulu for a moment. They sell video streaming, which is obviously technology, but they don&apos;t &lt;em&gt;sell&lt;/em&gt; to developers--they have no offering that a developer or development team can purchase. Yet, Netflix is commonly considered to be one of the FAANG companies, where Hulu--whose business model is &lt;em&gt;exactly the same&lt;/em&gt;--is not. The key difference is because Netflix chose to put some effort into the OSS community. Why do this? Netflix offers an API that allows people to build &amp;quot;value-add&amp;quot; using the Netflix platform; quick challenge, without Googling, does Hulu have an API? (&lt;a href=&quot;https://flixed.io/hulu-api-for-developers/&quot;&gt;Hint&lt;/a&gt;) And hey, while we&apos;re at it, what about Ford? You know, the cars? Do they have a public API? (&lt;a href=&quot;https://developer.ford.com/&quot;&gt;Hint&lt;/a&gt;)
&lt;p&gt;If you can think of a company that&apos;s larger than a thousand people in size, there&apos;s a good (better than 50%) chance that that company has an API. Even a &lt;a href=&quot;https://rapidapi.com/blog/directory/coca-cola-enterprises/&quot;&gt;soft drink manufacturer&lt;/a&gt; has an API. Chances are strong that your executive team has been looking for ways to turn your company into a &amp;quot;tech company&amp;quot; and provide a &amp;quot;platform&amp;quot; for people to build with. (By the way, most executives have no idea what that platform should be or look like, they only know they need one. &lt;a href=&quot;mailto:ted@tedneward.com&quot;&gt;Talk to me&lt;/a&gt; if you&apos;re an executive and want to figure out what one for your company should look like and provide.) Even if you&apos;re not looking to build a public API, chances are even stronger that you&apos;re building a private one--which means you need a DevRel team.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Marketing&lt;/em&gt;: If you&apos;re doing a public API, you want developers to know that this API exists, even if they don&apos;t directly have access to it, because it creates credibility around your efforts when partners and/or paying customers want to use it. If you&apos;re doing a private API, your efforts might actually be more internally-focused, the &amp;quot;inner source&amp;quot; model, where your efforts are now more about making other people inside the company aware of the API and what it does. (One of the best reasons to inner-source? So that other teams don&apos;t waste time and effort duplicating the API!)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Sales&lt;/em&gt;: Sales is about convincing people to use your product; in an external-facing API, some technical type will likely need to sit with potential partners and customers for your paying API, answering questions and exploring challenges and/or obstacles regarding the purchase of the API. For internal APIs, there&apos;s less pressure &amp;quot;to buy&amp;quot;, but not by much--different teams will need to know that an inner-source API can do what they need, and there&apos;s likely to be just as much negotiation at work, for example over which team will add missing functionality or be responsible for added features when they need fixes and such. Having a DevReal team to take on some of that work can be invaluable.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Engineering&lt;/em&gt;: Speaking of fixes, if your public API is now a part of a financial contract, then the partner or customer has to have somebody to call in the event that something doesn&apos;t work right (or doesn&apos;t work the way they think is right). In developer product companies, they&apos;re very quick to spin up a technical support team, but for non-developer product companies, where does that tech support team sit? Right there in the DevRel team, if you ask me--particularly if the engineering effort to build out the APIs is scattered across several organizations internally.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Recruiting&lt;/em&gt;: Same story as the consulting DevRel team, really: If Ford wants to attract new developers, it helps to have some caché to do it, and that comes from being out in the world doing interesting things where developers can see them. Once again, that&apos;s the realm of a DevRel team.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Companies where integration is a key core of the business.&lt;/strong&gt; You&apos;re not Ford, you&apos;re a bank or some form of B2B business, where the company&apos;s main line of product requires integration to work or optimize. A lot more companies are in this bucket than you might imagine--airlines, for example, are always looking at various other systems they want or need to integrate with, starting with other airlines (as they share loyalty programs, for example), rental car companies, hotel chains, and other players in the travel industry. If the business is a restaurant chain, developers can make use of APIs to automate the supply chain, tying the restaurant&apos;s inventory to orders, for example.&lt;/p&gt;
&lt;p&gt;Here, the company&apos;s goals are to build developer tooling that makes it as easy as possible for other companies&apos; IT to mesh with their own, to enable the integration scenarios that every CEO dreams about. That means building the platform that has copious entry and exit points, dozens of ways for integration to occur, and a plethora of documentation for the integration partners&apos; developers to consume while working to make everything work. And the Developer Relations team will be squarely at the center of it all (working, ideally, with the integration partners&apos; DevRel teams, because their CEOs all read this article, too).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Sales and Marketing&lt;/em&gt;: This is probably something of a combined effort, in that making potential partners aware of the integration capabilities (Marketing) and convincing them to integrate (Sales) are likely to be wrapped up into the same organization within the company (called, for example, Strategic Partnerships). Here the DevRel team will be a technical voice in the conversation, offering up explanations of the company&apos;s platform and its technical capabilities, usually in meetings with technical folks from the other partners.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Engineering and Support&lt;/em&gt;: This platform needs construction, and it needs people to make sure the platform remains up and running, and both of those mean working with partners to determine their requirements, their capabilities, and providing a single point-of-contact for the partners to call in the event things aren&apos;t working &amp;quot;correctly&amp;quot; (where that term can mean &amp;quot;not according to spec&amp;quot; all the way through &amp;quot;not according to what I think should be the spec&amp;quot;). The DevRel team--relating to the developers both within their own company as well as those at their partners--is ideal for managing these relationships.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Recruiting&lt;/em&gt;: Like all companies that use software, they have a need to bring in more developers. (The demand for software is infinite, but supply of those who can provide it, finite.) DevRel reaches out into the broader world, discussing the company&apos;s platform, the company&apos;s goals, and just in general making it very clear that there&apos;s a bunch of Cool Kids Doing Cool Things (TM) at this company, and wouldn&apos;t you like to be one of them?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, keep in mind that when I talk about the role of &lt;em&gt;developer relations&lt;/em&gt;, I&apos;m not just speaking of the activities of &lt;em&gt;developer advocates&lt;/em&gt;; a modern DevRel team will have a variety of different folks on a DevRel team, and in many cases those activities will be different for the different roles on the team. DevAds will often go and speak at conferences, for example, whereas Technical Community Managers will be taking more of the social media management on themselves, while Technical Content Engineers will be focusing on content creation (such as documentation, videos, and so on), and Developer Support Engineers will be the first line of support for external developers, and so on. These roles overlap, to be sure, but it&apos;s the rare case where one person will do &lt;em&gt;everything&lt;/em&gt;. (Frankly, those cases should probably be reserved for those companies that are just getting started and need somebody to kick things off in the DevRel space--just like the startup&apos;s technical co-founder writes the code, builds the website, manages the bugs, and so on. Over time, you need to scale up and out, and that means more people.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Every company that uses software, needs Developer Relations.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2023 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2023/2023-tech-predictions.html</link>
      <pubDate>Thu, 29 Dec 2022 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2023/2023-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;It&apos;s that time of the year again, when I make predictions for the upcoming year. As has become my tradition now for nigh-on a decade, I will first go back over last years&apos; predictions, to see how well I called it (and keep me honest), then wax prophetic on what I think the new year has to offer us.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;As per previous years, I&apos;m giving myself either a &lt;strong&gt;+1&lt;/strong&gt; or a &lt;strong&gt;-1&lt;/strong&gt; based on a purely subjective and highly-biased evaluational criteria as to whether it actually happened (or in some cases at least started to happen before 31 Dec 2020 ended). If you want to skip to the new predictions, &lt;a href=&quot;#2023&quot;&gt;scroll down&lt;/a&gt; to the next major heading.&lt;/p&gt;
&lt;p&gt;By the way, as of this writing, despite multiple false starts, I&apos;m &lt;a href=&quot;https://www.linkedin.com/posts/tedneward_hey-network-although-it-feels-a-little-activity-7008974172001378305-YrpY/&quot;&gt;still looking for my next great adventure&lt;/a&gt; (ideally as an Developer Relations or Engineering leader-of-leaders), so if you find my analysis here to be interesting or intriguing--even if you disagree with it--perhaps there&apos;s a role in which I can do this kinds of strategic and executive thinking on your company&apos;s behalf? Would love to hear from you.&lt;/p&gt;
&lt;h2&gt;In 2022...&lt;/h2&gt;
&lt;p&gt;... I wrote a lot of stuff. (That always seems to happen when I do these.) So let&apos;s get to it; as I do each year, I&apos;ll include the full text of what I wrote in each bullet point first, then put the &lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; after it with whatever insights or comments seem relevant. (Arguably none of them are, but hey, it&apos;s my set of predictions, so....) As always, evidence is entirely anecdotal and from my perspective, so &lt;em&gt;caveat emptor&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The major thing that kicked off in 2022, of course, was the conflict in the Ukraine. Russia&apos;s decision to move armed troops across the Russo-Ukrainian border was really precedent-shattering on a number of fronts, and significantly shook a world order that had made the assumption that &amp;quot;major-power&amp;quot; armed conflicts were a thing of the 1900s. The &amp;quot;McDonald&apos;s Rule&amp;quot; of International Relations (&amp;quot;No two countries, each of which having a McDonald&apos;s within their borders, have ever gone to war against one another&amp;quot;), a bastion assumption of economic liberalism, has suddenly been thrown for a loop, and it leaves a lot of people wondering what to make of it. It combined with the overall economic gray doldrums that had been starting to beat its way through our consciousness to make 2022 feel pretty grim.&lt;/p&gt;
&lt;p&gt;On the tech front, the big news in the second half of the year was the collapse of first one, then many, cryptocurrencies and exchanges, and literally billions--if not trillions--of dollars of value disappeared into the ether. Whether this will end up being the precipitating event of a Great Depression (like the 1929 Stock Market Crash) or a momentary blip on the radar of history has yet to be seen. Generally, that amount of wealth just going up in smoke has some pretty negative ramifications, but it&apos;s questionable whether that &amp;quot;wealth&amp;quot; ever actually existed. To be fair, people that paid USD (or EUR or YEN or ...) for tokens have now lost their original investment, but it seems that the original investment was much smaller than many media pundits are quoting; it&apos;s much more sensationalistic to talk about the &amp;quot;trillions of dollars lost&amp;quot; by speaking of the supposed wealth of the tokens, rather than the &amp;quot;millions of dollars of investment lost&amp;quot; from those who speculated. This one will probably take a few years to sort out before we really know what its impact was.&lt;/p&gt;
&lt;p&gt;Meanwhile, among &lt;a href=&quot;../2022/2022-tech-predictions&quot;&gt;my 2022 predictions&lt;/a&gt;....&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;strong&gt;&lt;em&gt;5G rollout is going to be a lot more contentious than we expected.&amp;quot;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: -1.&lt;/strong&gt; 5G rollout generated a few more warnings, but for the most part, not much really kicked in. There may be more movement next year, but as a prediction, it definitely didn&apos;t generate much news, reaction, or practical issues.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;strong&gt;&lt;em&gt;Demand for full-stack developers will continue to leave companies high-and-dry.&amp;quot;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: +1.&lt;/strong&gt; Yup, the demand got white-hot, all the way up until recently, when the whole &amp;quot;recession&amp;quot; thing kicked in. Even now, as layoffs are taking place, some of the very companies that laid people off are still hiring. It&apos;s the weirdest economic situation I&apos;ve ever lived in, and I lived through the Stagflation and Oil Embargo of the late 70s.&lt;/p&gt;
&lt;p&gt;As to my predicted second-order effects from this one....:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;strong&gt;Work-from-home will become normalized as part of the landscape.&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: +1.&lt;/strong&gt; Yup. In fact, the &amp;quot;remote work&amp;quot; thing is now normalized in a way it wasn&apos;t before, even despite some companies (most of whom I think are trying to justify the huge investment in land and leases and office space they&apos;re still obligated to pay for) strongly trying to get people back into the office.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;Companies will start &amp;quot;growing&amp;quot; their own developer staff.&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: 0.&lt;/strong&gt; Some of the bigger companies dove into this in the start of the year, but leveled off or backed away from it as the year wore on and the Gray Clouds of Recession loomed more menacingly overhead. They haven&apos;t gotten away from it entirely--and possibly never will, if they&apos;ve got the infrastructure already set up and in place--but it&apos;s nowhere near as highly-established as I thought it would be.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;Automation tools and platforms will climb in use.&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: +1.&lt;/strong&gt; I&apos;ll give myself a point here, but let me be clear: There is &lt;em&gt;no way&lt;/em&gt; I was thinking anything along the lines of ChatGPT or OpenAI or any of that stuff. I mean... wow.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;No-code/low-code tools and platforms will surge.&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: +1.&lt;/strong&gt; Do a Google search on either &amp;quot;low-code&amp;quot; or &amp;quot;no-code&amp;quot; and then take a step back as the results flood your machine. Layoffs have hit some of the big players in this space (Airtable, for example), but it&apos;s early enough for some of them that they&apos;re just charging forward damn-the-torpedoes-style.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;Developer market will grow. Slowly.&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: +1.&lt;/strong&gt; Lots of people are posting to LinkedIN and other places about joining the tech field, and the bootcamps and self-study programs continue to grow (&lt;a href=&quot;https://www.sltrib.com/news/2022/12/12/utah-tech-layoffs-continue-yet/&quot;&gt;Pluralsight&apos;s 20% layoff&lt;/a&gt; notwithstanding).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;Job descriptions will emphasize more about skills (including human skills) and less on degrees/certifications.&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: 0.&lt;/strong&gt; Well, on the one hand, (some) companies did revise their job descriptions to be a little more &amp;quot;growth mindset&amp;quot;-focused, but the interview processes didn&apos;t exactly shorten up--if anything, as the economy started to get more bleak, interview processes stretched out. (The cynic in me wants to point out that stretching out the interview process is a great way to see if the company is going to lay off; if we don&apos;t hire them, this is one person they don&apos;t have to lay off.) If companies are putting any sort of metrics on their interview pipelines, it&apos;s not many companies doing it, and their metrics aren&apos;t reaching the folks responsible for refactoring the process, it seems.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Remote tooling vendors will look to improve.&amp;quot;&lt;/em&gt;&lt;/strong&gt; (0.6)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: +1.&lt;/strong&gt; All of them rolled out various features, and just about every IDE now has some kind of &amp;quot;remote connect&amp;quot; feature allowing developers to pair- or &amp;quot;mob&amp;quot;-program together remotely. We can argue about the efficacy or efficiency of doing so, but the tools vendors definitely saw the writing on the wall and responded.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;&apos;Older&apos; tech will start to see a surge of interest and rise in adoption.&amp;quot;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: 0.&lt;/strong&gt; It&apos;s not widespread yet, but... check it out: &lt;a href=&quot;https://thenewpaper.co/&quot;&gt;a startup around hand-curating news sent to you over text message&lt;/a&gt;. If that&apos;s not a direct appeal to &amp;quot;let&apos;s simplify all this, shall we?&amp;quot;--and a direct rejection of AI-curated social media feeds masquerading as news--I don&apos;t know what it is.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Theranos will teach us something... but we&apos;ll not be sure exactly what.&amp;quot;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: +1.&lt;/strong&gt; &lt;a href=&quot;https://www.theguardian.com/us-news/2022/nov/18/elizabeth-holmes-theranos-trial-sentencing&quot;&gt;Elizabeth Holmes got 11 years&lt;/a&gt; (appeals pending). Her partner got 13 (again, appeals pending). Clearly &amp;quot;the system&amp;quot; wanted to send a message about fraudulent claims around startups, but overall, the reaction in the startup world has been... mixed. There&apos;s still the incessant hype around Miracle Founders (I mean, how much more smoke do we need to blow up Elon&apos;s ass already?), and much is being written, even as little is being done. Hate to give myself a point for being right about no progress, but here we are.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;NFTs, crypto; corporate promotion of NFTs followed by a huge backlash/abandonment.&amp;quot;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: +1.&lt;/strong&gt; I kinda want to give myself more than one point for this one, given how the whole thing collapsed &lt;a href=&quot;https://uk.finance.yahoo.com/news/worst-crypto-scams-and-coverups-of-2022-050059988.html&quot;&gt;in spectacular fashion&lt;/a&gt;. I mean... FTX, Bitcoin, Terra, Celsius... and not just because it was speculation in the industry, mind you, but outright malfeasance and/or stupid server errors, demonstrating the lie that &amp;quot;the blockchain is forever&amp;quot;. On the one hand, yay me for getting this one right, but on the other hand... yikes. Banks and other financial firms have regulation to prevent &lt;em&gt;precisely&lt;/em&gt; these sorts of things from happening, and &amp;quot;absolutely nobody saw it coming&amp;quot; that these similar kinds of problems would appear in cryptocurrencies? People lost their entire life&apos;s savings out of this mess. It&apos;s more than a mess, it&apos;s a &lt;a href=&quot;https://www.theregister.com/2022/12/20/crypto_ponzi_scheme_cofounder_pleads/&quot;&gt;scam&lt;/a&gt;, and people not neck-deep in it are starting to realize it--&lt;a href=&quot;https://www.wired.com/story/crypto-web3-securities-ripple-sec-lawsuits/&quot;&gt;including the feds&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;More non-developer-sales companies will build Developer Relations teams.&amp;quot;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: +1.&lt;/strong&gt; DevRel is a &lt;em&gt;hot&lt;/em&gt; commodity among companies right now, even despite the layoffs. Lots of companies are looking for &amp;quot;Head of DevRel&amp;quot; candidates, signaling a desire for a &amp;quot;DevRel IC who can later build out the rest of the DevRel team (in a few years, when we&apos;re sure this DevRel thing is going to stick....)&amp;quot;.&lt;/p&gt;
&lt;p&gt;By the way, if you&apos;re curious, &lt;a href=&quot;../2022/devrel-for-all-companies.html&quot;&gt;here&apos;s why every company should have a DevRel team&lt;/a&gt;...&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Open-source backlash/flight/pressure grows.&amp;quot;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: 0.&lt;/strong&gt; There&apos;ve been a few OSS packages that went the way of the Dodo bird, but for the most part, the OSS backlash I&apos;d anticipated (both in terms of using OSS and on the part of OSS maintainers demanding more support or threatening to bail entirely) didn&apos;t really play out as strongly as I&apos;d thought it would.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;New programming languages are going to start the R&amp;amp;D cycle on languages again.&amp;quot;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: +1.&lt;/strong&gt; Hello, Carbon. Hello, Cadl. Inform7 was open-sourced (April 2022). I can feel the steam building around languages, and I don&apos;t see it going away--in fact, I think it&apos;ll get even stronger. (But at the same time, I wish the industry were a little bit more open to new players here--it&apos;s hard getting any interest in some of these.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Some company is going to be really happy they took me up on that hypothetical in the second paragraph [about hiring me].&amp;quot;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: -1.&lt;/strong&gt; :-( Yeah, we covered this already.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;In summary:&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;sixteen predictions,&lt;/li&gt;
&lt;li&gt;four 0s,&lt;/li&gt;
&lt;li&gt;and two -1s&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;... leaving me with ten +1s, or something around 60%. Above average this go-round, it seems.&lt;/p&gt;
&lt;div id=&quot;2023&quot; /&gt;
&lt;h1&gt;2023 Predictions&lt;/h1&gt;
&lt;p&gt;With that settled up, let&apos;s take a look at what I think will happen across calendar year 2023.&lt;/p&gt;
&lt;p&gt;First off, the pandemic hasn&apos;t left us, and CDC is starting to talk about masking up again. Despite desperate efforts to pretend we&apos;re clear of COVID (and related viruses), we&apos;re not, and it&apos;s going to continue to rear its head in ugly ways going forward. I don&apos;t think we&apos;re going back to mandatory stay-at-home policies, mind you, but it&apos;s going to be a couple of years of really bad winters, medically speaking. The &amp;quot;taper down&amp;quot; I talked about last year definitely seems to be in full swing (or slope, as the case may be).&lt;/p&gt;
&lt;p&gt;Secondly, even though the Ukraine conflict continues, and inflation reared its ugly head during the end of 2022, the economy doesn&apos;t look as bad as we thought it would six months ago, and I think things are going to &amp;quot;perk up&amp;quot; once we get through the holidays. 2022 sucked, but there&apos;s a lot of reasons to think 2023 won&apos;t be nearly as bad. (Of course, we thought that about 2022 compared to 2021, and about 2021 compared to 2020, so....)&lt;/p&gt;
&lt;p&gt;Specifically, though, I think 2023 will show us the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Blockchain-related losses are going to be huge tax write-offs.&lt;/em&gt;&lt;/strong&gt; &lt;a href=&quot;https://www.theguardian.com/technology/2022/dec/29/unsellable-worthless-nfts-tax-write-off&quot;&gt;It&apos;s already starting&lt;/a&gt;, and other companies will follow suit as soon as they see others doing it. In a related note...&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Blockchain-related businesses are likely to be the target of lawsuits.&lt;/em&gt;&lt;/strong&gt; (Probability 0.8) Individuals lost a ton of money in NFTs and other such schemes, and they&apos;ll likely look for lawyers to help them go after the companies that sold these worthless things--&lt;a href=&quot;https://www.cnn.com/2022/11/16/business/crypto-contagion-genesis-ftx-ctrp/index.html&quot;&gt;and the various personalities that helped sell them&lt;/a&gt;. (Note that one such lawsuit was dismissed, but the judge left it open to be re-filed with new evidence, which the plaintiffs have already declared they will do.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The fallout from the cryptocurrency nightmare is going to stain &apos;Web3&apos; for a good long time.&lt;/em&gt;&lt;/strong&gt; (Probability 0.8) The criminal trials are just beginning, more cryptocurrencies and brokerages and stores are collapsing every day, and the various governments are just starting to stir on the subject; the crypto stories are nowhere close to being over, and a lot of investors are going to want to steer &lt;em&gt;very&lt;/em&gt; clear of this whole space until things settle in. Same thing happened in the early &amp;quot;recreational cannabis&amp;quot; days--and still isn&apos;t entire clear, while the feds take their time trying to figure out where they want to sit on the issue. &amp;quot;Web3&amp;quot; is not going to be a fun place to be for a while.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Distributed systems start to embrace contract-driven development cycles.&lt;/em&gt;&lt;/strong&gt; (Probability 0.7) HTTP-based APIs have become a staple of integration and partnership now for several years, but as companies find that they need to evolve their public-facing APIs, they&apos;re running into the core problems of doing so: Namely, that partners and clients get really upset when they have to rebuild API clients from scratch to match all the parameters correctly. JSON-over-HTTP was widely chosen because it wasn&apos;t as complicated or complex as something like IIOP (the old CORBA protocol) or XML-serialization-over-SOAP, but we&apos;re now starting to feel the pain of doing something &amp;quot;simple&amp;quot; but &amp;quot;by hand&amp;quot;, as opposed to have a specification document (aka an interface definition file) that we can code-generate from. That&apos;s going to cause another half-spin on the Ferris Wheel of Technology History, and things like OpenAPI/Swagger and AsyncAPI are going to start to become much more popular and much more necessary in production-quality API consumption.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Microservices start to give way back to deliberate monoliths.&lt;/em&gt;&lt;/strong&gt; (Probability 0.6) The microservices hype train has just about run out of steam, as companies that embraced the microservice ideal saw some negative ramifications from having a distributed system spread out across 1700 different nodes exhibit less-than-stellar characteristics. As influential &lt;a href=&quot;https://www.infoq.com/articles/microservices-seven-fail/&quot;&gt;articles emerged last year&lt;/a&gt;, we also saw anecdotal evidence that microservices were less an architecture and more a fad--nobody could ever define exactly how granular a &amp;quot;microservice&amp;quot; was intended to be, for example. Given that the shine has come off (starting as far back as 2019), we&apos;re going to see some organizations start to compose multiple existing microservices together back into a single node, and new project will be less aggressive about trying to &amp;quot;microservice all the things&amp;quot;. This could in turn have some interesting implications for the single-function services (a la Azure Functions, AWS Lambdas, etc), since they were a natural tool to use when &amp;quot;microservicing&amp;quot;, since you really can&apos;t get more micro than a single function. Right? (Don&apos;t answer that--I&apos;m sure somebody out there has figured out a way to make four services out of a single function invocation.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Security companies are going to need to OSS their offerings.&lt;/em&gt;&lt;/strong&gt; (Probability 0.5) Those companies who sell security-related software or cloud offerings sell their wares based on the premise of trust--namely, that you can trust that they will keep their secrets safe, and therefore by extension your secrets. Sadly, it&apos;s becoming more and more clear that those secrets (such as &lt;a href=&quot;https://www.forbes.com/sites/daveywinder/2022/08/25/lastpass-hacked-password-manager-with-25-million-users-confirms-breach/&quot;&gt;passwords&lt;/a&gt; or &lt;a href=&quot;https://www.bleepingcomputer.com/news/security/oktas-source-code-stolen-after-github-repositories-hacked/&quot;&gt;code&lt;/a&gt;) are hard to keep safe. Therefore, these companies are going to need to OSS their stacks, slimming down the surface area of the data they need to keep secret, in order to rebuild some of that trust. (Sadly, I kinda expect that this won&apos;t happen, because too many industry executives still believe that secrets are in the code, when most security and cryptography experts say the opposite--spread the code far and wide, but keep the &lt;em&gt;keys&lt;/em&gt; secret. Considering cryptography experts have about twenty centuries&apos; worth of greater experience, I&apos;m inclined to agree with the cryptography experts, myself.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Work-From-Home (WFH) continues to normalize and become &amp;quot;just another location&amp;quot;.&lt;/em&gt;&lt;/strong&gt; (Probability 0.7) As much as companies would like to get people back into their (very expensive) offices, there&apos;s a lot of companies that did a lot of remote hiring during the white-hot labor market during the pandemic, and it would be a pretty big bait-and-switch (not to mention terrible PR!) to have promised &amp;quot;remote&amp;quot; employment back then and go back on it now. Not to say that a lot of companies won&apos;t, but doing so would be essentially a huge black mark against that company within the tech sector, and make it that much more difficult to hire technologists for the rest of the decade. As a result, while some companies are going to continue to be &amp;quot;remote-always&amp;quot; (because they most likely don&apos;t have an office lease somewhere that they need to justify, or they&apos;ve never built a corporate HQ someplace), and some companies are going to be &amp;quot;office-always&amp;quot; (because they do!), many, if not most, companies are going to simply make &amp;quot;remote&amp;quot; another location in their &amp;quot;Locations&amp;quot; dropdown on the application web form.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Somebody is going to sue over state income tax.&lt;/em&gt;&lt;/strong&gt; (Probability 0.7) One of the things that those companies who offer remote options is the fact that the legal/tax situation around remote work is murky at best. Some states have interesting laws on the books regarding employees who work within their borders, and other states have no state income tax at all. When I was at Rocket Mortgage, I discovered that there were two states in the US that Rocket simply did NOT want anybody working from, because of the byzantine tax implications it would cause us. (Don&apos;t ask me for details, I don&apos;t have them.) At some point, this is going to culminate in a legal action--against an employee, against a company, and maybe even against one or more of the state governments--because somebody didn&apos;t understand the rules, or found the rules to be prohibitive, or is facing a LOT of money lost for one reason or another. That&apos;s going to start in 2023, take many years to wind its way through the courts, and gather a lot of interesting &amp;quot;takes&amp;quot; from the business community, ending in who-knows-what kind of solution. But it&apos;ll start in 2023.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Low-code/no-code is going to accelerate further.&lt;/em&gt;&lt;/strong&gt; (Probability 0.7) With an economic contraction of any form, getting your Amazing Innovation Project(tm) funded so you can hire software developers to build it will be that much harder. You&apos;ll start looking for ways around that obstacle, and as a result, interest in low-code/no-code tools will really begin to accelerate even further. Additional prediction: In 2025, interest in integrating those low-code/no-code solutions into the larger fabric of the company&apos;s IT will skyrocket. (Personally, I think this will bleed into new language development, too, but seeing the results of that will probably take longer.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Internal tech audits will become relatively popular.&lt;/em&gt;&lt;/strong&gt; (Probability 0.4) During times like this, when we&apos;re not quite so &amp;quot;move fast and break things&amp;quot;, we have a tendency to slump in the chair and look around the room at the collateral damage that the previous &amp;quot;go-go-go&amp;quot; era caused. At a company level, that means starting to take some deep audits of what we have, and some efforts to &amp;quot;clean house&amp;quot; will result. External purchases will be paused while execs look to integrate existing things rather than building new things. Regardless of what comes out of the analysis, it starts with the IT audit, though, and as a result, it&apos;s likely to be a pretty high-priority project on everybody&apos;s road map for 2023.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Muskian-style management will be studied, cargo-culted, and lead to the failure of more than one company.&lt;/em&gt;&lt;/strong&gt; (Probability 0.6) Love him or hate him, Elon Musk has propelled himself into the center of all things &amp;quot;management academia&amp;quot; with his handling of the Twitter purchase and takeover. Personally, I think he&apos;s flailing and thrashing and in general way out of his depth, but one thing is for sure: His rampant (and some suggest ill-advised) decisions about Return-To-Office and refusal to honor certain debts (like employee severances and expenses) are being watched very carefully by other CEOs around the industry, some of whom already are signaling that they&apos;re thinking about following suit.&lt;/p&gt;
&lt;p&gt;At the &lt;em&gt;very least&lt;/em&gt;, there&apos;s going to be a book or two that will be published on all this, probably due to hit shelves somewhere at the end of the calendar year, and it will garner all sorts of reviews from established periodicals. Some will be critical of Elon&apos;s approach, some will seek to find some sort of &amp;quot;underlying meaning&amp;quot; behind his actions that we can carry away insights from, but all will be looking, pointing, whispering, and taking notes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;2023 will be the year we try to figure out what to do with all this AI stuff.&lt;/em&gt;&lt;/strong&gt; (Probability 0.8) ChatGPT and OpenAI have completely taken the media and social media world by storm, but it isn&apos;t clear yet how any of that actually &lt;em&gt;helps&lt;/em&gt;. Like most applications of AI, it will likely be a mix of human creativity and AI computing power, but &lt;em&gt;how&lt;/em&gt;? With all the image-recognition stuff that was the darling of social media, we ended up doing.... what... with it? It certainly hasn&apos;t changed anybody&apos;s life that I know. That&apos;s what we&apos;ll spend 2023 trying to figure out.&lt;/p&gt;
&lt;p&gt;Oh, and the whole &amp;quot;GitHub Co-Pilot is going to take your job, you silly programmers&amp;quot; hype? Hot air. Whipped-up hot air. With all the nutrition and substance of cotton candy. Look, CoPilot might be able to take certain things on its own hands, but (1) it&apos;s proprietary to GitHub, (2) it&apos;s built on top of open-source projects whose contents are not acknowledged, violating license, and (3) it&apos;s not going to be able to bring the creative element that humans bring. It&apos;s a legal mess, and given the deep pockets GitHub is now blooming from (that is, Microsoft), it&apos;s ripe for some major legal action before it can safely take anyone&apos;s job. (Not to mention, somebody still has to drive CoPilot.) Worst case? CoPilot elevates the abstraction level, bringing a more natural-language element to programming languages--because somebody still has to figure out which algorithms and how to &amp;quot;codify&amp;quot; business rules. (FWIW, people said programmers were obsolete with the release of Visual Basic 3 and other high-level 4GLs; how&apos;d that turn out?)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;BONUS PREDICTION: 2024 will be the year that we start putting AI into some of our apps--like using ChatGPT for chatbots--and 2025 will be the year that we start ripping it all back out because we completely got it wrong.&lt;/em&gt;&lt;/strong&gt; (We always do this. And I see no signs that we&apos;ll stop in my lifetime.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Companies will accelerate their drive to become &apos;tech companies&apos;.&lt;/em&gt;&lt;/strong&gt; (Probability 0.6) For quite a few years now, there&apos;s been a drive among a number of firms to be seen as a &amp;quot;tech company&amp;quot;, with all the perks and benefits of being one, but with many (if not most) of the companies seeking to make this transformation unsure of what that exactly means. Particularly with the projected &amp;quot;soft&amp;quot; IT market next year to start, it will be a good time to take a moment to take stock, reshape the thought process, and then jump into it, particularly because...&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Hiring will accelerate at the end of 1Q/2023.&lt;/em&gt;&lt;/strong&gt; (Probability 0.8) Even as companies are engaging in layoffs, these aren&apos;t the savage cuts that we saw back in the Dot-Bomb era (circa 2001) or the Great Recession (circa 2008) era. Both of those were about the industry figuring out that whole lines of business were suddenly seen for what they were (unprofitable--Pets.com, anyone?) and making some fundamental adjustments to our thinking. This time around feels more like a &amp;quot;correction&amp;quot;, more of a &amp;quot;We know there&apos;s something in this line of business, but we didn&apos;t quite nail it and we need to re-examine and re-allocate&amp;quot;. People I&apos;ve talked to at both Microsoft and Amazon feel like as soon as this &amp;quot;organizational refactoring&amp;quot; is finished (which shouldn&apos;t take too long after the holidays), things will start to spin back up again. Which will also mean that...&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Entry-level positions are going to be easier to come by.&lt;/em&gt;&lt;/strong&gt; (Probability 0.5) When the market gets soft like this one appears to be, companies often start looking for ways to do take smaller risk in their hiring by hiring people newer to the workforce--a la junior and associate developers (and their kin), who they can hire at half of the cost of a senior software developer, thus risking less against their budget in the event the hire doesn&apos;t work out. (It doesn&apos;t mean companies will make it any easier for those early-stage developers to get hired, though, because they&apos;ll still be trying to put candidates through seventeen rounds of interviews over a six-month period before offering...)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Platform-oriented development is going to begin making some waves.&lt;/em&gt;&lt;/strong&gt; (Probability 0.6) As companies start looking for ways to create new revenue opportunities for themselves, or at making the transition into becoming a &amp;quot;tech company&amp;quot;, they&apos;re going to start looking very hard (once again) at how to build platforms out of their business, and the software they seek to build will follow suit--in other words, developers will be asked to build platforms rather than just hooking into one.&lt;/p&gt;
&lt;p&gt;In fact, there is a reasonable chance (and maybe this is more of a 2024 thing) that libraries/frameworks/languages will emerge to make it easier to integrate two platforms together more seamlessly and easily, rather than the current crop of tools designed to consume a platform&apos;s offering.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Cloud will begin to shift.&lt;/em&gt;&lt;/strong&gt; (Probability 0.5) TikTok is now an enemy of the US state, because it appears to be a tool of the Chinese state. Russian hackers and bots are shadowy figures looking to destabilize just about anything they can in the West, or so the pundits would have us believe (and which is probably at least partly true). And massive data breaches continue to plague comapnies left and right (&lt;a href=&quot;https://firewalltimes.com/twitter-data-breach-timeline/&quot;&gt;lookin&apos; at you, Twitter....&lt;/a&gt;). Cloud is not responsible for these things, and in many cases will be a powerful tool to fight against them, but the US government is signaling that it is going to start cracking down on some aspects of how the virtual world operates--and that could mean some guidance and/or restrictions around where data gets to live and where it gets to be processed. Even before the Feds tell CEOs where to put it, though, CEOs are going to start asking themselves the same questions, and this will lead to some &amp;quot;reallocation&amp;quot; of assets in and around various clouds. It&apos;s not likely cloud usage will shrink, but &lt;em&gt;how&lt;/em&gt; we use cloud and &lt;em&gt;where&lt;/em&gt; the cloud servers that we use are located will become more important.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;BOLD TWITTER TAKE: Elon will sell Twitter (perhaps involuntarily) at the end of 2023, to another tech firm (like Microsoft or Oracle).&lt;/em&gt;&lt;/strong&gt; (Probability 0.6) The current model is unsustainable. Twitter has no source of income: advertisers are bailing, and his &amp;quot;verified checkmarks&amp;quot; income is nowhere close to what he needs to keep things going even under the new staffing levels. (And let&apos;s just leave aside the existing debts and/or expenses from the pending lawsuits that are likely to slam into him in 2023--I&apos;m sure he can get Tesla or SpaceX to cover those, no matter how illegal that may be....) Twitter&apos;s losing people in droves, there&apos;s no new signups to replace the losses, and it&apos;s now become clear that where Twitter might have had a &amp;quot;cultural monopoly&amp;quot; on the idea of &amp;quot;short-form mass-widespread posting&amp;quot; (as opposed to some of the other forms of social media), that monopoly has now been shattered as non-technical folks start to pick up on terms like &amp;quot;Mastodon&amp;quot; and &amp;quot;Post&amp;quot;. Twitter needs users, and users are very quickly learning they don&apos;t need Twitter. Without stable leadership and a massive infusion of cash, the platform will plunge in value until one of the other tech giants just shrugs and says, &amp;quot;We can pick it up out of petty cash--how can we &lt;em&gt;not&lt;/em&gt; buy it now?&amp;quot;&lt;/p&gt;
&lt;p&gt;And that&apos;s how the grand MuskTwitter experiment will end. Not with a bang, but with a pathetic whimper.&lt;/p&gt;
&lt;p&gt;Meanwhile, alternatives to Twitter will continue to sprout up, but none will actually be able to be everything Twitter was, partly because Twitter was (at the time) unique in its approach to social media, and as a result it created a &amp;quot;perfect storm&amp;quot; that led the platform to its current (well, pre-Muskian) level of success. That will be nearly impossible to recreate.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;BOLDER SOCIAL MEDIA TAKE: RSS will make a comeback.&lt;/em&gt;&lt;/strong&gt; (Probability 0.4) RSS, the protocol that make blog-aggregators work to consolidate/federate all the blogs you wanted to read into one place, will be adapted or adjusted to work with all the differnet social media sites you want to read, so that social media aggregators can now bring all the social media you want to read into a single place. And if it&apos;s not RSS, it&apos;ll be a new protocol that does basically the same thing (because our industry loves building a new protocol to do the same thing an old protocol does, only &amp;quot;better&amp;quot;). Maybe &lt;a href=&quot;https://www.w3.org/TR/activitypub/&quot;&gt;ActivityPub&lt;/a&gt; but I won&apos;t hold my breath.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Talk to you all next year... if not sooner.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Of Cost Centers, and Competitive Advantages</title>
      <link>http://blogs.newardassociates.com/blog/2022/of-cost-centers.html</link>
      <pubDate>Wed, 28 Dec 2022 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2022/of-cost-centers.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt;: The recent collapse of Southwest Airlines&apos; operations that forced them to cancel 2/3 of all of their flights across the country, which current analysis suggests was due to &amp;quot;outdated IT systems&amp;quot; (specifically their employee-scheduling system), reminded me of a conversation over dinner with some speaker-friends a few years back. Companies can be classified into two categories: Those that view IT as a &amp;quot;cost center&amp;quot;, and those that view IT as a &amp;quot;competitive advantage&amp;quot;. How do you see the difference, and if you&apos;re a part of management, how do you influence the outcome?&lt;/p&gt;
&lt;!--more--&gt;
&lt;h3&gt;Cost centers&lt;/h3&gt;
&lt;p&gt;For those unfamiliar with the terms, the official definition of term &amp;quot;cost center&amp;quot; is &amp;quot;a department or other unit within an organization to which costs may be charged for accounting purposes.&amp;quot; This is frequently the case for internal (enterprise) IT software development teams, who &amp;quot;bill&amp;quot; other departments for development of projects that those other departments are looking to have built. More importantly, these organizations often don&apos;t add directly to the company&apos;s income or profits, which then leads to some less-than-ideal implications.&lt;/p&gt;
&lt;p&gt;For example, if the Accounting department needs some custom software built to help track costs and an off-the-shelf solution doesn&apos;t work, it&apos;s pretty common for Accounting to &amp;quot;hire&amp;quot; a team from the IT department to build that software and &amp;quot;pay&amp;quot; for it out of their budget. Since this new Accounting software won&apos;t really add any new lines of income to the company, or grow an existing line of income, the only &amp;quot;measurable metric&amp;quot; for the IT department is how much it &lt;em&gt;draws away&lt;/em&gt; from the income--in other words, how much does it cost? And if more cost is bad, then the natural growth/improvement approach here is to look for ways to minimize costs.&lt;/p&gt;
&lt;p&gt;That statement is dangerous.&lt;/p&gt;
&lt;p&gt;On the surface of things, sure, it makes sense to minimize costs--if my team can get a project done faster, then we cost less and all is good. Of course, because there is no countervailing metric by which to measure the quality or effectiveness of the project, it becomes something of a runaway metric: We can cut costs by reducing the amount of work we do, or by paying more junior people less to do it, or even by removing people entirely! This approach works all the way up until Accounting complains about it, at which time we can take on a new project with them to address the issue. Our metrics look good: we cut our costs down, &lt;em&gt;and&lt;/em&gt; we got a follow-up project out of it.&lt;/p&gt;
&lt;p&gt;Internal accounting like this leads to some really screwed-up results sometimes, particularly for those companies that insist on being &amp;quot;metrics-facing&amp;quot; or &amp;quot;data-driven&amp;quot;.&lt;/p&gt;
&lt;p&gt;(Yes, I know Amazon right now is strong on using data to drive their decisions, and everybody loves them for it--and yet, &amp;quot;data-driven&amp;quot; was a thing twenty years ago, too, and it was a synonym for &amp;quot;metrics-facing&amp;quot;, and it led to the kinds of results I just described.)&lt;/p&gt;
&lt;h3&gt;Competitive advantage&lt;/h3&gt;
&lt;p&gt;If your IT department is a &amp;quot;competitive advantage&amp;quot;, it means your IT department is at the forefront of how the company is able to accomplish things that other companies can&apos;t (or can&apos;t as quickly). Rocket Mortgage, for example, was the first mortgage lender to put the mortgage application process on a website, thus opening up a whole new line of income for the company. Those of you readers who are about 30 or older probably remember a time when flying a commercial flight meant arriving at the airport, going to the airline counter, giving your name and ID, and receiving printed boarding passes before going through security. Then an airline realized that the process of verifying the ID and the name and printing the boarding pass could be done by a kiosk. Then another airline realized that it didn&apos;t really require being in the airport to do that, and boarding passes could be printed ahead of time on your own computer and printer. Then yet another airline realized that you didn&apos;t even need the paper, and the &amp;quot;airline app&amp;quot; was born, using QR codes and scanners to let you on the airplane.&lt;/p&gt;
&lt;p&gt;By the way, it should be pretty obvious that the first company to do something like this has a competitive advantage; by the time the third or fourth competitor in the same space does it, it&apos;s table stakes--it would be a significant missing feature if they &lt;em&gt;didn&apos;t&lt;/em&gt; have that feature. Imagine being the airline today that requires printed boarding passes available only at the airline counter.&lt;/p&gt;
&lt;p&gt;The point here is that these approaches and these strategies are never static--today&apos;s &amp;quot;IT as a cost center&amp;quot; company is yesterday&apos;s &amp;quot;IT is a competitive advantage&amp;quot; company, and vice versa. Consider: after building the website to start mortgage applications, what has Rocket Mortgage done to leverage IT as an advantage? Delta was the first to roll out their &amp;quot;Fly Delta&amp;quot; app, but aside from piling more features into the app (airport maps, access to in-flight entertainment options, tracking frequent-flier status, and so on), what else can the airline&apos;s IT group do to hold an advantage over their competitors? (Answer: I was recently on a Delta flight where the in-flight monnitors had Bluetooth, meaning for the first time I didn&apos;t have to use my corded Bose speakers to watch a movie. Smooth.)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.jacksonville.com/story/news/nation-world/2016/08/11/delta-computer-outage-included-small-fire-data-center/15720648007/&quot;&gt;Life wasn&apos;t always smooth for Delta&apos;s IT&lt;/a&gt;. They&apos;ve clearly made a strong effort to redress that, and use IT as a differentiating factor from their competitors.&lt;/p&gt;
&lt;p&gt;Take careful note that being a &amp;quot;competitive advantage&amp;quot; company doesn&apos;t always mean not having legacy systems--Delta still uses some of the some infrastructure that all the airlines share, and always will. Lots of banks still use the COBOL-based mainframes to exchange electronic records that maintain the accounts between them. This hasn&apos;t stopped Chase from having apps that allow you to deposit checks using your mobile phone&apos;s camera, however.&lt;/p&gt;
&lt;h3&gt;Knowing the difference&lt;/h3&gt;
&lt;p&gt;The &lt;em&gt;real&lt;/em&gt; key is, where are your IT projects coming from, and where are they going? If your project is customer-facing, there&apos;s a strong chance it&apos;s going to be in &amp;quot;competitive advantage&amp;quot; territory... but not always. If a project is to replace a legacy system whose functionality growth has stagnated, that can in turn unlock some new features and/or speed of execution that would be impossible to achieve with the legacy system. And not all internal-facing projects are &amp;quot;cost center&amp;quot; candidates; building a platform that allows the company to more quickly and easily integrate with their supply chain, for example, can help speed the delivery of product to customers, and/or open up new sales opportunities or options or products.&lt;/p&gt;
&lt;p&gt;The bigger question is, as it so often is in business, &lt;strong&gt;&lt;em&gt;what is the company&apos;s strategy around this?&lt;/em&gt;&lt;/strong&gt; If the project aligns with the company&apos;s overall strategy, then it is likely to be a competitive advantage project. If it doesn&apos;t, it&apos;s probably falling into the &amp;quot;cost center&amp;quot; bucket.&lt;/p&gt;
&lt;p&gt;Ironically, just about anything can be a competitive advantage within a company. Those companies that really go above and beyond to take care of their employees often see a significant competitive advantage from doing so. Those that invest into their infrastructure often see it pay off when the investment creates resiliency that their competitors lack, and allow them to keep going when something disastrous strikes. For many years, for example, the key competitive advantage McDonald&apos;s had (and arguably still does) was the heavy degree of investment into their supply chain, which helps them isolate against supply-chain shocks. (Which I think, in late 2022, we can all better appreciate the need to consider.)&lt;/p&gt;
&lt;h3&gt;Implications&lt;/h3&gt;
&lt;p&gt;Southwest pretty clearly considered its IT to be a &amp;quot;cost center&amp;quot;, which doesn&apos;t surprise me in the slightest, given both the fact that they&apos;ve not really used IT as a competitive advantage anywhere in their execution. (Ironically, Southwest used to be one of those companies that invested heavily into their employees, and still might, but that&apos;s a different discussion for a different day.)&lt;/p&gt;
&lt;p&gt;Note that the people running Southwest are not stupid--if somebody had come to them a year ago and said, &amp;quot;You are going to have to cancel 2/3 of your entire flight catalog for several days if you don&apos;t fix this scheduling system&amp;quot;, they would have immediately made that project a top priority. But that&apos;s still a cost-center mentality, because they would be comparing the cost of that project against the cost of those cancellations (which has a pretty clear winner). But in the absence of something to compare the cost of that project against, a cost center mentality says &amp;quot;let&apos;s not incur the cost&amp;quot; and postpones it or duct-tapes it or addresses only the most critical flaws. Which, then, leads us to a system that is only marginally able to resist a system-wide shock.&lt;/p&gt;
&lt;p&gt;Like the &amp;quot;Blizzard of 2022&amp;quot;. Or the &amp;quot;Pandemic of 2020&amp;quot;. Or the &amp;quot;Server Fire of 2016&amp;quot;. Or ....&lt;/p&gt;
&lt;h3&gt;Speculations&lt;/h3&gt;
&lt;p&gt;Note that one of the reasons companies often don&apos;t engage in exercises of IT competitive advantage is that it can be so damn &lt;em&gt;expensive&lt;/em&gt; to do so. Given that any non-trivial software project can take a team of five or more upwards of nine to twelve months before something tangible is able to be rolled out for people (customers or otherwise) to start using, you&apos;re looking at a pretty large bet on something that--if truly innovative--has no guarantees of actually yielding anything more than a yawn (or worse, a new legacy system that has to be maintained).&lt;/p&gt;
&lt;p&gt;If you&apos;re an IT manager or organization head, then, your goal is to find ways to enable IT teams to be able to get something up to a usable state as quickly as possible--the traditional &amp;quot;Lean MVP&amp;quot;--so that the business can find out if this is something that will &amp;quot;move the needle&amp;quot; for the company or not. Part of that means putting some infrastructure in place to enable that fast development--what we now refer to as a &amp;quot;platform&amp;quot;. Build your platform to allow for people to innovate on it, and they will.&lt;/p&gt;
&lt;p&gt;And the next thing you know, suddenly, your IT team is in the &amp;quot;competitive advantage&amp;quot; side of the ledger.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Hello Cadl</title>
      <link>http://blogs.newardassociates.com/blog/2022/hello-cadl.html</link>
      <pubDate>Thu, 15 Dec 2022 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2022/hello-cadl.html</guid>
      	<description>
	&lt;p&gt;This one just crossed my feed today: &lt;a href=&quot;https://github.com/microsoft/cadl&quot;&gt;Cadl&lt;/a&gt;, &amp;quot;... a language for describing cloud service APIs and generating other API description languages, client and service code, documentation, and other assets.&amp;quot;&lt;/p&gt;
&lt;p&gt;In other words, you write this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import &amp;quot;@cadl-lang/rest&amp;quot;;

using Cadl.Http;

@server(&amp;quot;https://example.com&amp;quot;, &amp;quot;Single server endpoint&amp;quot;)
@route(&amp;quot;/example&amp;quot;)
namespace Example {
  @get
  @route(&amp;quot;/message&amp;quot;)
  op getMessage(): string;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... and when you &amp;quot;compile&amp;quot; it, you get an OpenAPI (or gRPC, or some other service-oriented protocol) specification out the other end. From there, it seems, you use other tools to go from OpenAPI to one of the service client or implementation languages (C#, Java, Python, Ruby, whatever suits your fancy), so long as there&apos;s an OpenAPI code generator for it.&lt;/p&gt;
&lt;p&gt;First take: this seems so much less feature-rich than something like &lt;a href=&quot;https://ballerina.io/&quot;&gt;Ballerina&lt;/a&gt;, but I suppose it will appeal to those who prefer to get all their Azure-related tooling from Microsoft and/or prefer their stack to be entirely JS-based. (Cadl seems to be a product of TypeScript.)&lt;/p&gt;
&lt;p&gt;Will plan on investigating this more, soon.&lt;/p&gt;
&lt;p&gt;(Cross-posted to my &lt;a href=&quot;https://dev.to/tedneward/cadl-a-new-idl-5b1e&quot;&gt;Dev.to account&lt;/a&gt;, mostly as an exercise to see which one gathers traffic.)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Speaking Tips: Mistakes happen; get over it</title>
      <link>http://blogs.newardassociates.com/blog/2022/mistakes-happen-get-over-it.html</link>
      <pubDate>Thu, 5 May 2022 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2022/mistakes-happen-get-over-it.html</guid>
      	<description>
	&lt;p&gt;I can&apos;t say how many times I&apos;ve talked to new speakers who watch speakers and are &lt;em&gt;amazed&lt;/em&gt; at how effortless their flawless presentations seem to go. Folks, part of the reason they go that smoothly is because they&apos;re practiced, but part of it is also that the speaker is often ready for the mistake to happen.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;A long time ago, when I was but a wee speaker learning the Art of the Technical Talk from the DevelopMentor Grand Master of Speakers (&lt;a href=&quot;https://www.linkedin.com/in/ron-sumida-06a3824/&quot;&gt;Ron Sumida&lt;/a&gt;), one of the things he told me was that &amp;quot;Everything that happens in that room, happens because you intended it that way.&amp;quot; If a demo fails, you intended it that way, because you wanted to give the room a chance to see the failure, and then you intended to show them how to recover from it. If a slide is in the wrong order, it&apos;s because you wanted to get that point across before moving on to a different point. If water starts pouring out of the ceiling....&lt;/p&gt;
&lt;p&gt;Yeah, that really happened to me once. While teaching a DevelopMentor open-enrollment class at the corporate office down in LA, one day I&apos;m in the middle of class, just turned around to start doing a demo when water starts pouring out of the ceiling--literally &lt;em&gt;through&lt;/em&gt; one of the ceiling tiles--like somebody had just turned on a faucet right above us.&lt;/p&gt;
&lt;p&gt;That was &lt;em&gt;not&lt;/em&gt; intended.&lt;/p&gt;
&lt;p&gt;I ran out of the room, grabbed one of the fisherman-buckets in the lobby in which we kept snacks, dumped out the snacks, ran back to the room, and put it under the pouring water. Not a perfect solution, but it allowed me to deal with the problem temporarily, then get the class back on track. This time, to the soothing sounds of water rushing by.&lt;/p&gt;
&lt;p&gt;Another time, I was doing a talk at Devoxx (back when it was still called &amp;quot;Javapolis&amp;quot;) in Antwerp, and it was not going well. It was supposed to be a talk on the various ways that Microsoft Office and JavaEE (then called J2EE) could work togther (and you&apos;d be surprised at how many different ways they could--it was pretty seamless), and just about every demo was bombing for one reason or another. I&apos;d even carefully put all the demo code into a VMWare VM, so that it would be isolated from any other changes or environment updates on my laptop, but just one demo after another wasn&apos;t working. And it was odd--certain files were truncated in weird positions. Finally, in a fit of exasperation, I said, &amp;quot;OK, folks, let&apos;s try one more demo, and then if that doesn&apos;t work, I&apos;m just going to surrender my laptop to the Demo Gods and go the rest of the way without demos.&amp;quot;&lt;/p&gt;
&lt;p&gt;And that&apos;s when the VM blue-screened in front of everybody.&lt;/p&gt;
&lt;p&gt;Did I mention that Javapolis/Devoxx is held in a movie theater? You have &lt;strong&gt;never&lt;/strong&gt; seen a blue screen of death until you&apos;ve seen it on the big screen.&lt;/p&gt;
&lt;p&gt;Fully expecting to get hammered in evals, I was surprised when I heard that I was actually doing quite well. I ran across one of the attendees from that talk later in the conference, and I flat-out asked him, &amp;quot;What did you think of my talk?&amp;quot;&lt;/p&gt;
&lt;p&gt;&amp;quot;Oh, I loved it, I thought it was great!&amp;quot;&lt;/p&gt;
&lt;p&gt;I was flabbergasted. &amp;quot;If you don&apos;t mind me asking, why? Why did you think it was great? Every single demo bombed!&amp;quot;&lt;/p&gt;
&lt;p&gt;&amp;quot;Oh, but you never let it stop you. I believe you when you say the demo is supposed to work, so when it didn&apos;t, and you just kept going, it was great!&amp;quot;&lt;/p&gt;
&lt;p&gt;I don&apos;t know if that attendee could see the shaft of enlightenment settle from the clouds above (Javapolis was still a smoking event back then, and there was always a thick haze of cigarette smoke near the ceiling in the hall), but in that moment, I truly understood Ron&apos;s precept.&lt;/p&gt;
&lt;p&gt;It&apos;s not that you intended the demo to bomb, or the water to start pouring out of the ceiling.&lt;/p&gt;
&lt;p&gt;It&apos;s that this is your room, and &lt;strong&gt;&lt;em&gt;you are in full control of this presentation&lt;/em&gt;&lt;/strong&gt;. It&apos;s really about your confidence in your knowledge, your skills, and your talk coming through: &amp;quot;I am fully ready to deal with whatever may come, and I will guarantee you that nothing will derail us from me taking you on this journey with me.&amp;quot;&lt;/p&gt;
&lt;p&gt;Not even a tornado warning, drunk co-presenter, or gastrointestinal difficulties. (All of which have happened to me, by the way.)&lt;/p&gt;
&lt;p&gt;Everybody who has ever attended a tech talk has seen a demo bomb. Your demo failing is not anything new to them. It&apos;s really not. (What, you think you&apos;re special, that your demo is somehow better or more amazing than anybody else&apos;s demo? It&apos;s just a demo, fercryinoutloud!) And your demo is not the centerpoint of your talk, and it will fail in ways you could never have predicted. And that&apos;s OK.&lt;/p&gt;
&lt;p&gt;But what if your demo is the &lt;em&gt;one thing&lt;/em&gt; they were hoping to see? Hardly likely, but let&apos;s even assume that it is: You think those attendees whose career hangs on seeing your demo working aren&apos;t able to come up to you later and ask, &amp;quot;Do you mind if we try that demo again, I&apos;d love to see it working&amp;quot; and sit with you at a table working through it if they cared that much? (Ironically, the only time that&apos;s happened to me is after that very same Javapolis presentation, which was when we discovered that my VM&apos;s virtual disk had corrupted. Fortunately I had a copy of the VM on another external hard drive, so it was easy to spin that one up and show the demo off as it was meant to be seen. They went away happy, and I went away educated.)&lt;/p&gt;
&lt;p&gt;The key thing is, if you do live code demos, you need to be comfortable with two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Be ready to debug on the fly.&lt;/strong&gt; You will forget a semicolon, you will misspell the name of the method you need to apply, you will forget that the file you&apos;re trying to load is one directory up or down from where you&apos;re looking to load it from, you will make mistakes. Most of them will be simple, stupid, and fixable. And frankly, there&apos;s value in showing attendees how to debug the very same kinds of mistakes that they&apos;re going to make when they get home and try to repeat your demo. But you have to be comfortable debugging on the fly. Even then....&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be willing to abandon the demo.&lt;/strong&gt; Sometimes, it&apos;s just not going to happen. It&apos;s more subtle than you thought, it&apos;s trickier than you thought, or worse yet the version of the library you&apos;re using silently upgraded without you realizing it, and now they&apos;re looking for a differently-named method or the file is in a different place. Sometimes, it&apos;s just going to take more time than you&apos;ve got to debug.&lt;br /&gt;
And in that moment, you have a choice--stay focused on the room, abandon the demo (my usual choice of words is, &amp;quot;Do you believe me that this is &lt;em&gt;supposed&lt;/em&gt; to work?&amp;quot; which usually draws a chuckle or two), and move on with your talk. Or, you can stay focused on YOU, and your need to get this demo to work, and abandon the rest of the talk.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Remember, the audience is here to hear a story. They don&apos;t need your demo to hear the story. The demo is there to help them visualize and see the story play out in front of their eyes--but it&apos;s not the story as a whole, and if they have to use their imagination a little, that&apos;s not a terrible thing.&lt;/p&gt;
&lt;p&gt;Mistakes will happen. Get over it. Fast.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PostScript.&lt;/strong&gt; If you really don&apos;t want to deal with failing demos, try the &amp;quot;Milli-Vanilli&amp;quot; pattern from &lt;em&gt;Presentation Patterns&lt;/em&gt;: record a video of the demo on your machine, and embed the video in your presentation and play it during your talk. That way you can talk about what you&apos;re doing in the video while it&apos;s playing, and you don&apos;t have to try and split your brain coding and talking at the same time. Of course, never discount the possibility that the video could fail during your talk... at which point you look at the audience and say, &amp;quot;Do you believe me when I tell you that this video was &lt;em&gt;supposed&lt;/em&gt; to work...?&amp;quot;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Founding of Solidify/US</title>
      <link>http://blogs.newardassociates.com/blog/2022/solidfyus.html</link>
      <pubDate>Fri, 29 Apr 2022 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2022/solidfyus.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt;: &lt;a href=&quot;https://solidify.dev/&quot;&gt;Solidify&lt;/a&gt;, a Sweden-headquarted consulting company, is creating a US division, and they&apos;ve asked me to build it out. Hence, I am announcing the foundation of Solidify/US, a software development consulting company with deep expertise in DevOps (AzureDevOps and GitHub) and a focus on helping companies maximize their software development efforts.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;&lt;strong&gt;EDIT: 15 December 2022&lt;/strong&gt; Sadly, it was a short one. With the dark clouds of the global economic slowdown on the horizon, as well as the uncertain clouds of war hovering over Ukraine, the folks at Solidify decided that it was a little too risky to take the chance on starting a business here in the US. Thus, I continue my search for my next new adventure.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;It&apos;s been an interesting road since Rocket Mortgage and I parted ways back in October 2021. I&apos;ve interviewed with a number of companies, some big and some small, some product-focused and some consulting, and kept finding something missing in each. In many cases, they chose not to move forward with the process, and a few of those genuinely stung--I could see some potential in those. It&apos;s hard, going through the interview cycle, particularly at the more senior executive levels of roles I was trying to reach for. Some companies were name-recognizable, others were companies nobody (including myself) had ever heard of. CTO roles, VP roles, a few Director roles, and every once in a while a recruiter tried to talk me into being an individual-contributor-Architect again or an IC Developer Advocate. A quarter of them, I turned away; the rest, either it wasn&apos;t a great fit (culturally or financially), or they chose to go a different way.&lt;/p&gt;
&lt;p&gt;Some rejection was expected--hell, more than one of them was a long-shot &amp;quot;what the hell&amp;quot; kind of exercise--but it begins to wear down on you after time.&lt;/p&gt;
&lt;p&gt;Then, around the Feb/Mar timeframe, I connected with these guys out of Sweden who were asking if I had any interest in joining up with them to do some consulting, particularly around DevOps and GitHub. In particular, they said, they were long-time Microsoft partners, with a great relationship with the Microsoft Sweden field office, and wanted to explore the idea of opening an office in the US to better serve customers (and hopefully break into the much bigger market!) here.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Huh.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;See, I&apos;d done the consulting company founder thing before, with iTrellis, and while I thoroughly enjoyed my time doing it, I had reached the conclusion that I didn&apos;t really want to join into another consulting company again unless it was at a pretty senior level, where I could make use of (and follow through on) a number of the things I had learned about organization design from my time at RM. Other consulting companies had talked about &amp;quot;maybe someday&amp;quot; being able to indulge me in taking ownership of things like onboarding, mentoring, and other talent development kinds of activities, but for now, could I put in some billable hours? Several small groups and I spoke, but couldn&apos;t find the senior-level fit (usually financially). Some larger consulting groups were interested, but didn&apos;t hire in anybody above a senior consultant level--I&apos;d have to &amp;quot;prove my worth&amp;quot; and internally promote to get to the levels I was interested in.&lt;/p&gt;
&lt;p&gt;Solidify was different--they were asking me to essentially own the US side of things, with their backing and support, and with the idea that if things go well, Solidify/US and Solidify/Europe would be mutually self-supporting partners. Obviously for the first engagement or two, I&apos;d probably need to be at least a little billable, but as soon as was reasonable, I&apos;d be looking to grow the business rather than &amp;quot;doing the work&amp;quot;.&lt;/p&gt;
&lt;p&gt;It quickly became apparent that if I did this, it&apos;d be like spinning up a consulting company from scratch, but with the resources and connections of an established group to help with the bootstrapping and smooth over some of the rough patches.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Huh.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As it turns out, some of my friends and speaker circuit colleagues are neck-deep in GitHub activities, working specifically to help grow the GitHub community--the very same space in which I&apos;d be looking to create connections and find clients. In other words, I&apos;d get a chance to work closely with some folks that I deeply respect, admire, and enjoy. While partnering with a CEO and CTO in Sweden who are both quite delightful people to talk to, I&apos;m discovering. It doesn&apos;t hurt either that Magnus and Mathias and I are of the same mind on a number of important points--like billable-hours targets not being 110%, like an emphasis on growing juniors into mid-level and seniors, like putting company time and resources behind ongoing training and development, like engaging with developer communities and speaking at developer conferences....&lt;/p&gt;
&lt;p&gt;And, as I thought about it all, to top it all off, now is a really interesting time to be a software developer: AI/ML is often a key centerpiece of many IT strategies yet it&apos;s still cordoned off from the general software development pipeline, budget, and strategy; data engineering is often now expected to be a full partner in the development of software yet nowhere does it appear on a DevOps roadmap; DevOps itself is struggling to figure out how to incorporate other silos (like Product or Support, to the left and the right of the DevOps space on the timeline) into the mix even as InfoSec keeps popping its head up every so often to point out when another company got hacked; all this in a time when &amp;quot;low-code&amp;quot;/&amp;quot;no-code&amp;quot; tools keep capturing the interest of &amp;quot;the C suite&amp;quot; and upper-echelon executives even as companies look to hire more and more &amp;quot;full stack&amp;quot; developers who apparently need to know everything about everything....&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Huh!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Is there really any way I say no to this?&lt;/p&gt;
&lt;p&gt;Fast-forward to now, and here we are: Solidify/US is in the process of being built out--we&apos;re meeting with prospective clients, signing agreements (through Europe at the moment, until Solidify/US has its paperwork ducks in a row), and before too long, I&apos;ll be out looking for new clients and new consultants.&lt;/p&gt;
&lt;p&gt;If you&apos;ve an interest in consulting, with an eye towards DevOps (but frankly, I don&apos;t see that as the limit to what we do) and an emphasis on the GitHub ecosystem and the Azure platform, you might want to drop me a note &lt;a href=&quot;mailto:ted.neward@solidify.dev&quot;&gt;over email&lt;/a&gt; or &lt;a href=&quot;https://www.linkedin.com/in/tedneward&quot;&gt;on LinkedIn&lt;/a&gt; sometime in Q3 or Q4 of this year.&lt;/p&gt;
&lt;p&gt;If your company is struggling to try and make sense of all these new forces in software development, and you could use with a partner to help you sort out what matters vs what&apos;s hype, and how any of these forces affect your current plans and pipelines... well, &lt;a href=&quot;mailto:ted.neward@solidify.dev&quot;&gt;I&apos;d love to talk to you&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Should be an interesting journey.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Why the Bug Tracker</title>
      <link>http://blogs.newardassociates.com/blog/2022/why-the-bug-tracker.html</link>
      <pubDate>Sat, 26 Feb 2022 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2022/why-the-bug-tracker.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt;: Allen Holub is a smart, experienced developer whose seen a lot of things in his time. But his take on the bug tracker--that it &amp;quot;is a symptom of a deeper problem--insufficient focus on quality&amp;quot; misses the mark badly on a number of fronts, even as he is slightly right about it.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;First, &lt;a href=&quot;https://twitter.com/allenholub/status/1496326760719216643&quot;&gt;the tweet&lt;/a&gt; reads:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I do wonder why anyone thinks that it’s a good idea to not just fix a bug the moment you become aware of it. Bug-tracking systems have always struck me as weird. Don’t track them; fix them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then, &lt;a href=&quot;https://holub.com/bugs/&quot;&gt;the post&lt;/a&gt; goes on in greater detail. Let&apos;s take some of this apart.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You do not need a bug tracking system. In fact, a bug tracking system is a symptom of a deeper problem--insufficient focus on quality.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&apos;s a bold opening, and certainly one designed to catch peoples&apos; attention. This is what comes from being a professional content creator, and I&apos;m just as guilty of it at times.&lt;/p&gt;
&lt;p&gt;Look, I get where he&apos;s coming from: I&apos;ve worked on teams (particularly back in the early days when I was doing C++ on some large projects), where the bug tracking database seems to only ever get larger and more complicated and certain bugs just never get fixed and nobody ever seems to care. I remember looking through bug databases at employers and marveling at reports that were from over a year ago, and the features they referred to didn&apos;t even exist anymore--or were so deeply different that the bug just didn&apos;t matter anymore. It was a HUGE source of noise for me as a developer.&lt;/p&gt;
&lt;p&gt;But...&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In general, I fix bugs the moment they appear—not in a drop-everything sense, but as soon as I can get to it—usually within a few hours, but sometimes in a day or two when I’m done with the current story. Of course, if I’m working in the code when I notice a bug, I just fix it right then. The software I write has no known bugs in it as a consequence (and yes, I never don’t use TDD and I always add real tests as I work—these are two different things). I can trust the code as I’m working, and I can verify that I haven’t broken anything as I work by running the tests every few minutes. Takes all the pressure off and radically improves development speed.&lt;/p&gt;
&lt;p&gt;I don’t use a bug tracker because I don’t need to. There are no bugs to track.&lt;/p&gt;
&lt;p&gt;I know that people who haven’t tried it will be skeptical that writing a bunch of tests increases your speed, but programming has never been about the speed at which you type. Time spent typing a test is nothing when compared to overall development time, which is mostly thinking. Having the tests in place eliminates all the staring-at-the-code-wondering-if-it-will-work time and lets you focus on the problem you’re solving rather than whether the code works or not.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These three paragraphs are essentially a time-honored argument that &amp;quot;TDD and tests mean your code is better quality&amp;quot;. It&apos;s an old argument. It&apos;s an argument that has some truth to it. However, the fact that Allen &amp;quot;doesn&apos;t need to&amp;quot; use a bug tracker because &amp;quot;there are no bugs to track&amp;quot; makes it pretty clear that he&apos;s never worked on a project that is sufficient size and scope that it&apos;s more than just him working on the project. &lt;em&gt;(Full disclosure, I&apos;ve never worked with Allen, and I&apos;m not aware of his current work status or his work history--this is all analysis, not fact.)&lt;/em&gt; He&apos;s never stepped into a project that existed before he was able to bring his TDD discipline (and it is a discipline, folks, it requires a tremendous amount of willpower to do successfully) to bear.&lt;/p&gt;
&lt;p&gt;Frankly, it&apos;s the argument of somebody who&apos;s essentially saying, &amp;quot;I&apos;m better than all you idiots who can&apos;t see the clearly-superior way of working&amp;quot; and while it kinda fits in with his irascible &amp;quot;grumpy elder statesman&amp;quot; persona, it&apos;s not a great way to win friends and influence people.&lt;/p&gt;
&lt;p&gt;Part of Allen&apos;s assumption here, too, is that nobody who&apos;s &lt;em&gt;not&lt;/em&gt; a programmer will ever find a bug, and I don&apos;t know that he&apos;s &lt;em&gt;that&lt;/em&gt; arrogant to assert that. That means that if the bug is to be fixed, there must be some place where people who are not programers can let the programmers know that &amp;quot;the bug exists, and these were the conditions in which we saw the bug (to the best of our memory anyway)&amp;quot;. They aren&apos;t in a position to fix them.&lt;/p&gt;
&lt;p&gt;Additionally, Allen seems to assert that he has complete discretion over how he is going to spend his time; he gets to decide whether he works on the bug or a feature next. As much as we&apos;d like to assume that programmers will always prioritize what is in the business&apos; best interest when prioritizing their work, we already know that&apos;s &lt;a href=&quot;https://blog.codinghorror.com/gold-plating/&quot;&gt;not always the case&lt;/a&gt;. And, in all fairness to programmers, they may not have the necessary context to choose between getting feature A out the door as a higher priority than fixing bug B, particularly if bug B only occurs sporadically and to a small audience, and feature A will win a million-dollar deal. And, to the programmer&apos;s chagrin, &lt;strong&gt;&lt;em&gt;that is a perfectly reasonable decision to make.&lt;/em&gt;&lt;/strong&gt; Programmers don&apos;t like it, particularly those who value their craftsmanship, but when you value your craftsmanship over business value, you&apos;re already on shaky ground.&lt;/p&gt;
&lt;p&gt;Lastly, bug trackers serve as a means of information transfer--on a large project, I may not have the knowledge of the code in which the bug occurs, and for me to come up to speed on that area of the code well enough to be able to diagnose the problem and create a useful fix... that could take orders of magnitude longer than if I just note the problem and let somebody who has knowledge of that code attack it.&lt;/p&gt;
&lt;p&gt;(Side note: How many of us have worked with people who&apos;ve spent so much time in all parts of the system so that we can just describe the problem and they can go &amp;quot;Hmm.... yup, I know where it is, here&apos;s how you fix it&amp;quot;? One of my best friends was that guy on a team we were on twenty-five years ago. I&apos;ve seen it at client engagements since then, too. And you know what happens? Everybody comes to that guy for every bug, and soon nobody bothers trying to learn the system. Let that person help drive the fix, but don&apos;t let them do the fix.)&lt;/p&gt;
&lt;p&gt;The power of the bug tracker is also well beyond the moment the bug is discovered and its fix. Bug trackers can also provide a database and history, documenting what the problem was and how we fixed it, so that future iterations of teams can do searches through the database to find common scenarios and see if there&apos;s a larger problem that could be fixed, either cutting down the time required to diagnose a bug, or potentially finding a solution further upstream that prevents a whole class of bugs.&lt;/p&gt;
&lt;p&gt;(I am well aware that not many teams use a bug database that way. That doesn&apos;t mean it&apos;s not a powerful tool for those teams who do.)&lt;/p&gt;
&lt;p&gt;But the next paragraph starts opening up some interesting avenues.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you have so many bugs that you need to track them, it seems to me that you have serious problems in the way you do development. Fix that first. You can start by throwing away every bug report older than a month. If it’s important, it will come back. Then distribute the bugs out to the teams. In other than a very small organization, the teams will need to work out some way to fairly route bug reports. Throwing dice works pretty well. Assign a number to each team. Throw the dice. You can round robin, too. The team can fix it whenever it’s convenient, but there should be an upper limit on that—a few days, maybe. If your stories are properly sized, that means you can finish the current story before you move to the bug fix. If you’re interrupting people, you’re doing it wrong. A bug is rarely a crisis.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&apos;s a throwaway line, but &amp;quot;throwing away every bug report older than a month&amp;quot; hides a much more interesting take that could&apos;ve been much more valuable: &lt;strong&gt;&lt;em&gt;what is the time a bug spent in a bug tracker before it is closed?&lt;/em&gt;&lt;/strong&gt; If a team has a bug tracker with bugs in it that stretch back by more than a month, then clearly those bugs have been deprioritized, and they should be moved into some kind of state indicating that; some teams call that a &amp;quot;Won&apos;t Fix&amp;quot; (and please by all that&apos;s holy include a reason for it so people can get the full history as to why that decisions was made). A team can and should set up some kind of review board or process (or discipline, it doesn&apos;t have to be all that formal, if the team is disciplined enough to follow through) for bugs in the tracker.&lt;/p&gt;
&lt;p&gt;See, here&apos;s the thing that I think Allen has accidentally stumbled upon: &lt;strong&gt;&lt;em&gt;The distance between the bug&apos;s discovery and it&apos;s resolution is a useful signal.&lt;/em&gt;&lt;/strong&gt; If it takes your team less than a day to fix a bug, you&apos;re in a great place. If it takes your team less than a day to resolve that a bug will never be fixed, you&apos;re also in a great place, because now you won&apos;t waste time looking at it every single time you go into the bug database. If it takes you weeks, or months, to figure out what you&apos;re going to fix, however, you&apos;re in the same conceptual place as those teams that spent weeks or months gathering requirements.&lt;/p&gt;
&lt;p&gt;Once again, &amp;quot;being agile&amp;quot; means identifying your source of feedback, and tightening up the loop of feedback-to-action.&lt;/p&gt;
&lt;p&gt;And that has nothing to do with a bug database.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Book review: Supercharge Your Applications with GraalVM</title>
      <link>http://blogs.newardassociates.com/blog/2022/review-graalvmbook.html</link>
      <pubDate>Wed, 23 Feb 2022 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2022/review-graalvmbook.html</guid>
      	<description>
	&lt;p&gt;A while back, Packt Publishing asked me to do a review of the book &lt;a href=&quot;https://www.packtpub.com/product/supercharge-your-applications-with-graalvm/9781800564909&quot;&gt;&amp;quot;Supercharge Your Applications with GraalVM&amp;quot;&lt;/a&gt;, and while I wrote it up, I never pushed it to the blog. tl;dr, it&apos;s a decent book--a good intro to GraalVM, with some interesting tidbits in there, but not deep enough for the expert. (Full disclosure: Packt sent me a copy of the book in exchange for a review.)&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;For those Java developers who’ve never heard of or never explored &lt;a href=&quot;https://www.graalvm.org/&quot;&gt;GraalVM&lt;/a&gt;, the latest virtual machine technology project courtesy of Oracle Labs, it may be unclear why the world needs another virtual machine--after all, HotSpot did wonders for most Java applications when it came out in JDK 1.2 (circa 2000), and the caretakers of the JVM have been tinkering and making significant changes to the performance ever since. Garbage collectors, bytecode translation, you name it, they’ve tinkered with it. So the average Java developer could be forgiven if they were to see GraalVM, and think, &amp;quot;Yeah, whatever.&amp;quot;&lt;/p&gt;
&lt;p&gt;A B Vijay Kumar’s book, &lt;strong&gt;&lt;em&gt;Supercharge Your Applications with GraalVM&lt;/em&gt;&lt;/strong&gt;, will go to great lengths to dissuade Java developers of that naïve notion. While the book itself could use with a bit better &amp;quot;overarching story&amp;quot;, explaining how the different features of GraalVM tie together and present a coherent whole, it’s not like the GraalVM documentation does a much better job of that; instead, the various features are laid out, and it’s left to the reader (or user of GraalVM) to figure out where and how each significant piece of the platform &amp;quot;fits&amp;quot;.&lt;/p&gt;
&lt;p&gt;The first criticism I might have of the book is that it doesn’t always seem to consistently know who its audience is. Chapters 1 and 2 go over some of the core basics of the JVM; Chapter 1 covers the C1 and C2 bytecode compilers, for example, which for any student of the JVM is pretty redundant. Chapter 2, though, introduces JITWatch and the &lt;code&gt;+XX:PrintCompilation&lt;/code&gt; flag, which is generally something reserved for the serious VM explorer. While I suppose it’s possible one could go from &amp;quot;lightweight intro&amp;quot; to &amp;quot;serious player&amp;quot; in a fairly fast manner, doing so in two book chapters seems like a leap.&lt;/p&gt;
&lt;p&gt;Chapter 3 begins the serious exploration of GraalVM itself, getting into the architecture of the system. It’s also the first hint the reader gets that GraalVM is more than &amp;quot;just&amp;quot; an upgraded JVM; in fact, it’s fair to suggest that GraalVM may very well be the last virtual machine anyone would ever need to write, thanks to its &amp;quot;Polyglot&amp;quot; support: GraalVM can run not only Java bytecode, but Python, R, Ruby, even C/C++ and Web Assembly (WASM) code. This support, known as &amp;quot;Truffle&amp;quot;, is what gives GraalVM the ability to do ahead-of-time (AOT) native compilation of Java applications, which is what most of the Java industry conference speakers focus on, particularly since that native AOT compilation is what will make microservices spin up faster. However, that’s merely the surface of the subject.&lt;/p&gt;
&lt;p&gt;Chapter 4 then dives into getting GraalVM installed and hooking up the various performance monitoring tools (like VisualVM); this chapter felt a little out-of-place to me, since I would’ve expected to see it earlier--or later--in the conversation based on the previous chapter. He also introduces another tool, the Idea Graph Visual izer, which analyzes how Graal JIT-compiles code. This doesn’t exactly feel in line with the &amp;quot;getting started&amp;quot; vibe from the earlier parts of the chapter, though the utility of the tool is pretty much self-evident. It does require Kumar dive into some compiler theory 101 kinds of topics (intermediate representations, static-single-assignment (SSA) form, and so on), which means now in one chapter we are getting started, seeing a new tool exploring the JIT compiler, and learning some core ideas of compilation, all in one span of text. It feels a little rushed at times, a little too compact, and a little out of order.&lt;/p&gt;
&lt;p&gt;Chapter 5 then dives into a tutorial on building native images and running them with profile-guided optimization (PGO). This was really the first part of the book where one could get &amp;quot;hands on&amp;quot; with what was being taught, and I felt it needed to come sooner, probably right after getting GraalVM installed. These two chapters (4 and 5) were the most &amp;quot;muddled&amp;quot; in my mind, where it felt like the author was jumping around between some topics without a clear path in mind or a clear rationale for why we needed to read about &amp;quot;A&amp;quot; before we read about &amp;quot;B&amp;quot;. In all fairness, though, that may be my own biases and prejudices coming to the fore--I’ve spent enough time writing books and teaching workshops that I pay careful attention to that &amp;quot;journey&amp;quot; the reader or student will take through the material.&lt;/p&gt;
&lt;p&gt;Chapters 6 through 9 explore the polyglot nature of GraalVM, introducing the Truffle framework in greater depth, then exploring how to run different language-based code on top of the runtime. GraalVM can execute not only Java bytecode, but also NodeJS, Python, Ruby, or R (from their respective sources) and WebAssembly and C/C++ (through the use of the LLVM toolchain, which is a native compilation framework that many languages use to generate native code). To my mind, this is where the GraalVM story is the most interesting, and the author provides some simple examples, but I would’ve preferred a little more depth around each of the different languages and some of the integration challenges that arise.&lt;/p&gt;
&lt;p&gt;Finally, in Chapter 10, Kumar gets to what most people will think is the real &lt;em&gt;raison d’être&lt;/em&gt; of GraalVM: microservices. Accordingly, the chapter opens with a brief introduction of microservices which I found entirely unnecessary (does anybody not know what those are by now?) and then proceeds to build out an example of an application built out of microservices. The author then takes one of the services and builds it out using a variety of different microservice frameworks (Spring Boot, Micronaut, Quarkus). Frankly, I found this chapter pretty gratuitous, as if the publisher insisted that the book couldn’t be published unless it had microservices somewhere in it--it just feels that much out of place compared to the rest of the material. Still, for a lot of readers who are looking for answers to their day-job needs, it’s a reasonable demonstration of how GraalVM could be applied to a microservice-based architecture.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;In summation:&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
For the virtual machine expert or aficionado, parts of the book will seem redundant, but for those who’ve never really spelunked below the surface of the Java (or Groovy or Scala or Kotlin or...) code they write, the book will offer just enough background to the subject to feel comfortable reading other resources, or enough to take what Kumar says through the rest of the book on faith. While Kumar’s writing is pretty clear and straightforward, the outline through the material is less so, and it feels like the book would’ve benefited strongly from a firm editorial hand to create more of a &amp;quot;journey&amp;quot; through the GraalVM landscape. Still, the words-to-concepts ratio means the material is dense enough to keep the reader from being bored or flipping through the pages too quickly, and that’s a plus. Additionally, it’s a useful guide for those who aren’t comfortable going directly to the documentation to learn how to use GraalVM.&lt;/p&gt;
&lt;p&gt;If you’ve never heard of GraalVM or heard only rumors and want a hearty introduction into all the things GraalVM offers, this is a good book with which to get started, though I wouldn’t expect it to be one used over and over again once read cover-to-cover.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Overall verdict: 4 stars out of 5&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Digital footprint updates</title>
      <link>http://blogs.newardassociates.com/blog/2022/digital-footprint-updates.html</link>
      <pubDate>Tue, 22 Feb 2022 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2022/digital-footprint-updates.html</guid>
      	<description>
	&lt;p&gt;As I&apos;ve mentioned on LinkedIn, I&apos;ve been &lt;em&gt;sans&lt;/em&gt; FTE employment since just before the holidays last year, and I&apos;m using the time to do some re-shuffling of some of my &amp;quot;digital footprint&amp;quot; on the Internet. Let me explain a bit about what&apos;s going on here, mostly so that if you&apos;re consuming an RSS feed for one, and you&apos;re not getting what you expect, you may want to flip over to the other. (Or both!)&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;For starters, I&apos;ve come to realize that I want two, separate &amp;quot;representations&amp;quot; of myself on the Internet for public consumption, one professional, the other personal.&lt;/p&gt;
&lt;p&gt;The professional persona will be here, on newardassociates.com, in which I talk pretty much about what everybody expects me to talk about (if you don&apos;t know me personally): programming languages, platforms, virtual machines, management, and so on. Think of &lt;a href=&quot;http://www.newardassociates.com&quot;&gt;www.newardassociates.com&lt;/a&gt; as the pair to my LinkedIn account. That means there will be two top-level domains:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.newardassociates.com&quot;&gt;www&lt;/a&gt;: The professional website and &amp;quot;starting point&amp;quot; for anybody looking to view services, articles, presentations, and so on.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://blogs.newardassociates.com&quot;&gt;blogs&lt;/a&gt;: This is where a lot of my blog articles will end up living, and at some point I may redirect some of the links at blogs.tedneward.com over to here permanently, just to encourage professional readers to come here. The plan is to wire this up with &lt;a href=&quot;http://ifttt.com&quot;&gt;IFTTT&lt;/a&gt; to pick up on a new blog post and post it to LinkedIn, in fact.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The personal persona, tedneward.com, will be a bit more free-form, and wide-ranging. I may talk about technology, but I will also feel more free to host other non-professional things, such as D&amp;amp;D, fiction I feel like posting, maybe some photos, and who knows what else. That means there&apos;s going to be a couple of different domains there, as well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.tedneward.com&quot;&gt;www&lt;/a&gt;: The starting point.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://research.tedneward.com&quot;&gt;research&lt;/a&gt;: My &amp;quot;research garden&amp;quot; of links and notes for a whole bunch of things, including personal, professional, and anything else that seems interesting to me. Feel free to wander around in there if you like, but keep in mind that you&apos;re wandering around in a digital version of my study, so if the mess doesn&apos;t make sense...&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://blogs.tedneward.com&quot;&gt;blogs&lt;/a&gt;: This has historically been where I kept my professional blog (since 2005!), so I&apos;ll keep those links alive (some or most of them, anyway--some are just way too outdated to think anybody will care), but future posts will be all over the map. This one will wire up with &lt;a href=&quot;http://ifttt.com&quot;&gt;IFTTT&lt;/a&gt; to announce new posts to Twitter, since Twitter is where I&apos;m more comfortable showing off multiple sides of myself as an individual, rather than just branding as an &amp;quot;industry professional&amp;quot;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The key? I&apos;m doing all of this using static site generators, Markdown, GitHub, GitHub Actions, and hosting them in Azure. This way, I can either use the GitHub web-editor to create a new post online directly (and have it auto-posted to the site within minutes), or queue it up by writing locally and shipping when I push to main. Automating all of this has been a thorn in my side for quite a while, but I wanted a reason to learn GitHub Actions, and while I could&apos;ve done some or all of this using a variety of other platforms, I&apos;ve been meaning to spend a little time with Azure anyway, so here we go. (And no, I didn&apos;t consider running one on Azure, one on AWS, one on Digital Ocean... because life is too short and I&apos;d rather find a different forcing function for each of those cloud providers.)&lt;/p&gt;
&lt;p&gt;If you&apos;re still reading, thanks for staying with, and hopefully this will reduce the barrier-to-blog that&apos;s kept me from writing more in the last few years. (It&apos;s kinda not, but let&apos;s pretend that&apos;s what it was and let me slide, OK?)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2022 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2022/2022-tech-predictions.html</link>
      <pubDate>Sun, 23 Jan 2022 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2022/2022-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;It&apos;s that time of the year again, when I make predictions for the upcoming year. As has become my tradition now for nigh-on a decade, I will first go back over last years&apos; predictions, to see how well I called it (and keep me honest), then wax prophetic on what I think the new year has to offer us.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;As per previous years, I&apos;m giving myself either a &lt;strong&gt;+1&lt;/strong&gt; or a &lt;strong&gt;-1&lt;/strong&gt; based on a purely subjective and highly-biased evaluational criteria as to whether it actually happened (or in some cases at least started to happen before 31 Dec 2020 ended).&lt;/p&gt;
&lt;p&gt;By the way, as of this writing, I&apos;m &lt;a href=&quot;https://www.linkedin.com/posts/tedneward_hey-all-job-search-update-short-version-activity-6889005174992596992-kShH&quot;&gt;still looking for my next great adventure&lt;/a&gt; (ideally as an engineering leader-of-leaders), so if you find my analysis here to be interesting or intriguing--even if you disagree with it--perhaps there&apos;s a role in which I can do this kinds of strategic and executive thinking on your company&apos;s behalf? Would love to hear from you.&lt;/p&gt;
&lt;h2&gt;In 2021...&lt;/h2&gt;
&lt;p&gt;... I wrote a lot of stuff. (That always seems to happen when I do these.) Let&apos;s start. I&apos;ll include the full text of what I wrote in each bullet point first, then put the &lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; after it with whatever insights or comments seem relevant. (Arguably none of them are, but hey, it&apos;s my set of predictions, so....)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We began the new year with chaos and tragedy, at least here in the United States. The Capitol Insurrection of 2021, fueled by blatantly-false claims of election fraud and whipped into a frenzy by a narcissist whose continued civic freedom depends on being &amp;quot;untouchable&amp;quot; by legal recourse, meant that a lot of us had things far, far more important than technology trends to worry about. It&apos;s been a rough two months since then, as well, as we struggle to balance hopes for vaccines and coordinated federal response to this damnable virus against the mess that the year-plus of deliberate neglect from the previous US Adminstration created. It was hard on everyone, and in a lot of ways we all just want to &amp;quot;get back to normal&amp;quot; for whatever definition of &amp;quot;normal&amp;quot; you care to use. Unfortunately, I don&apos;t think we&apos;re anywhere close to &amp;quot;normal&amp;quot; yet, though the massive rollout of vaccination programs will help, but I&apos;ll get to that in a second.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Well... yeah. I didn&apos;t &lt;em&gt;want&lt;/em&gt; to be right about that last part about not being close to normal, but sadly, it held up. 2022 started much as 2021 did, adding in vaccines but also deep hysteria and distrust from the anti-vaxx crowd whipped up by right-wing agitators. (I honestly never thought I&apos;d write those words in a sentence about the United States of America. I really didn&apos;t.)&lt;/p&gt;
&lt;p&gt;Thing is, it&apos;s becoming more and more apparent that the &amp;quot;normal&amp;quot; we all knew in 2019 is probably not coming back. Frankly, we should be used to this--the &amp;quot;normal&amp;quot; we all knew in the first half of 2001 never came back, either. I remember a time when you could escort your friends and family to the boarding gate, or meet them there when they stepped off the plane. I remember a time before 20 years of armed conflict in multiple nations in the Middle East. I remember a time when you could bring your own water onto an airplane. I didn&apos;t care for the TSA, I don&apos;t think it actually makes us any safer, but it&apos;s now a part of the fabric of our traveling life, and it&apos;s pretty clear that it&apos;s never going away. Sadly, I think the same will be true of many of the things we&apos;ve come to embrace (by necessity) from this pandemic (and it &lt;em&gt;kills&lt;/em&gt; me that the crowd that insisted we had to make all these changes in 2001 in the name of public safety is now telling us that all these changes in the name of public safety is government overreach).&lt;/p&gt;
&lt;p&gt;Interesting thing, though: Not all these changes were &lt;em&gt;bad&lt;/em&gt;. Some will have ramifications and ripple through the next decade or more, and the results might actually be things we come to embrace and enjoy. More to come.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Conferences will begin to pick up in September.&lt;/em&gt;&lt;/strong&gt; (Probability: 0.5) This is an important one to me, personally, because I miss going places and hanging out with friends and talking technology and trends and stuff. My thinking is that the vaccinations will reach a popular &amp;quot;critical mass&amp;quot; somewhere in June--which won&apos;t be yet &amp;quot;herd immunity&amp;quot; but enough so that everyone can know somebody personally who&apos;s been vaccinated and &amp;quot;nothing bad happened&amp;quot;--which would then mean that conferences will scramble to put something together as quickly as they can, but will still need a few momths&apos; lead time. Other countries, who have been more aggressive to fight the virus, will be open sooner, but the US will lag, because we&apos;d rather let people die while arguing &amp;quot;freedoms&amp;quot; than take the pragmatic route of eliminating the virus and &lt;em&gt;then&lt;/em&gt; do the debates.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: 0&lt;/strong&gt; &lt;em&gt;sigh&lt;/em&gt; Vaccines rolled out, but depending on where you lived in the US, you may or may not have been surrounded by a statistical majority (&amp;gt; 50%) of people who actually took them. Despite that, several conferences braved the wilds and were, in fact, held in person (lookin&apos; at you, KCDC), apparently successfully. (KCDC, at least, seemed to go off successfully, and even more improbably, I heard zero cases of COVID infection stemming from the conference. Woohoo! Win!) -1 for the assumption that it would be more widespread, but +1 for the fact that some did, and did so effectively.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Remote (anything) is going to be a huge focus.&lt;/em&gt;&lt;/strong&gt; (0.7) In 2020, we had to learn how to survive without driving anywhere or stepping inside other buildings. UberEats, DoorDash, GrubHub, all these &amp;quot;remote dining&amp;quot; experiences surged to the forefront of our mobile devices&apos; home screens. Retailers figured out how to do &amp;quot;remote shopping&amp;quot;, enabling curbside or in-store pickups. Amazon, of course, saw a huge surge in use, but a surprising number of retailers took &lt;em&gt;huge&lt;/em&gt; leaps to control their own remote distribution channel. Those that didn&apos;t will quickly start to figure it out on their own--and Amazon may actually lose some market share as a result, as for years the principal thing Amazon did was provide that remote distribution channel. Before, when that was just one of several options, it wasn&apos;t important enough to retailers to figure out--when it became their &lt;em&gt;only&lt;/em&gt; option, though, they moved fast and slapped enough together to make it all work. In 2021, they&apos;ll start to tune, improve, and perfect those channels, and Amazon will really need to start aggressively fighting against those new channels.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: +1&lt;/strong&gt; To be fair, this was an easy call: Grocery stores now do curbside delivery, every restaurant that wants to do any kind of business has an account with one of those (UberEats, DoorDash, GrubHub, or some of the others less well-known), and streaming services continue to do a ton of business. Office work continues to remain entirely remote, which means most of your &amp;quot;office visits&amp;quot; (doctor, lawyer, financial, etc) continue to be entirely remote when/where they can, and frankly there&apos;s no signs of this slowing down any time soon. Amazon hasn&apos;t seemed to start &amp;quot;aggressively fighting against&amp;quot; those new channels yet, at least not with any new services, but they&apos;re definitely being much more aggressive in commercials, I think to try and reassure the public (and reaffirm) to shop there instead. Given how much Amazon analyzes numbers, I have a feeling that either the drain to their accounts isn&apos;t yet significant enough (perhaps there&apos;s less overlap than I thought), or they&apos;re preparing a major campaign for 2022. We will have to see.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Amazon will get the Congressional eyeball.&lt;/em&gt;&lt;/strong&gt; (0.5) Bezos already took a hit to his brand with the revelations of his infidelity to his wife, and Amazon&apos;s most recent union-busting efforts just added to the bad PR. Amazon will start to get more and more scrutiny as different companies start looking for reasons to pull their goods out of the Amazonian warehouses and do the distribution themselves--and that will cause Amazon to get a little desperate lest its profit margins come down too far... and that in turn will trigger some undesirable behavior, followed by calls for inquiry and oversight.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: -1&lt;/strong&gt; Nope. Lot sof &amp;quot;Big Tech&amp;quot; did, but to no real end, and with little actual movement. Amazon seems to have weathered the union-busting stories pretty well, and Bezos&apos; infidelity sort of petered out as a story. (Which, to be honest, I like--his relationship with his wife is really his and hers to deal with, and not ours to judge.) Overall, no reasons to pull out of Amazon warehouses, no losses to the profit margins, no calls for inquiry, no calls for oversight. Probably the most complete &amp;quot;whiff&amp;quot; of the year.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Bitcoin and other cryptocurrencies start drawing fire from unlikely places.&lt;/em&gt;&lt;/strong&gt; (0.4) &lt;a href=&quot;https://www.bbc.com/news/technology-56012952&quot;&gt;&amp;quot;Bitcoin consumes &apos;more electricity than Argentina&apos;&lt;/a&gt;, while just a year prior, it was &lt;a href=&quot;https://www.bbc.com/news/technology-48853230&quot;&gt;Switzerland&lt;/a&gt;. And its carbon footprint is &lt;a href=&quot;https://www.cnbc.com/2021/02/05/bitcoin-btc-surge-renews-worries-about-its-massive-carbon-footprint.html&quot;&gt;comparable to that of New Zealand&lt;/a&gt;. Whatever your thoughts about the viability of Bitcoin and other digitial currencies, the act of mining it is not only consuming ridiculous amounts of resources, that consumption is triggering wider ecological woes, and that&apos;s going to draw fire from a lot of different corners of the landscape--particularly because for so many people, it&apos;s just a weird geek-fan-whatever thing that doesn&apos;t have any impact on the wider world. Sooner or later, some country is going to take a hard-line stance against it, and that will start the dominoes in a negative direction.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: +1&lt;/strong&gt; Oh, my, the backlash is building. Of course, I in no way predicted the creation of NFTs, which drew a lot of the ire and focus around the whole growing collection of blockchain-based Ponzi schemes. We haven&apos;t seen many nations taking formal steps, but &lt;a href=&quot;https://www.investopedia.com/articles/forex/041515/countries-where-bitcoin-legal-illegal.asp&quot;&gt;a few are&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;&apos;AI&apos; and &apos;machine learning&apos; are going to run into major backlash.&lt;/em&gt;&lt;/strong&gt; (0.6) Amazon ran into ethical issues with its use of machine-learned models for interviewing and hiring, because they didn&apos;t do the right amount of validation and verification of their models before putting them into production. Not a lot of companies are going to have the patience or AI-savvy to do that, either, and as a result, media backlash will start turning the shine of AI and machine learning into glare. By years&apos; end, we may even see Congressional inquiry into the subject(s), under the umbrella of widespread investigation into &amp;quot;Big Tech&amp;quot;.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: -1&lt;/strong&gt; You know, I was surprised we didn&apos;t see more. I mean, like &lt;em&gt;really&lt;/em&gt; surprised. There&apos;s a growing movement around better ethical governance of AI, but for the most part, the Congressional interest in &amp;quot;Big Tech&amp;quot; isn&apos;t really motivated or driven by AI or ML. That said, lots of groups--particularly those who represent or advocate for underprivileged/underrepresented groups--are coming out more vocally against the use of AI without oversight or analysis, and that&apos;s good, even if I don&apos;t consider it to be the backlash I&apos;d thought was going to kick in.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Any tech company that wants to compete will need to enable WFH on demand.&lt;/em&gt;&lt;/strong&gt; (0.8) Look, this past year made it pretty obvious that anybody in the technology space can do their job from anyplace in the country--if not the world. Couple that with a continued insatiable demand for tech talent, and you are quickly setting up the model for a buyers&apos; market when it comes to finding a job. &amp;quot;Hmm. You say your company needs me in the office, but this other company over there doesn&apos;t need that. Why should I work for you and add wear and tear to the streets, my car, and my nerves?&amp;quot; Not to mention that when you can work-from-home, you can realistically work-from-anywhere, including your parents&apos; place while the kids are out building snowmen with grandma and grandpa. Some companies will fight &lt;em&gt;hard&lt;/em&gt; to bring people back to the office, but they&apos;re going to be fighting an uphill battle, and may well lose out on some prime tech talent if they can&apos;t figure out how to be flexible. On that same note, if a company cannot or will not embrace a culture of &amp;quot;remote first&amp;quot; to allow those in the building and those outside the building to work on the same, level, playing field, that company will find itself scooping up candidates from the bottom half of the talent pool.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: +1&lt;/strong&gt; I feel kinda bad about giving myself credit here, because it really was there and obvious for all the world to see. Companies (Microsoft, Amazon, Google) have all tried to bring employees back to the office, but becaues of a combination of both COVID variants and worker resistance, have all but abandoned those plans thus far. I&apos;ll be curious to read the historical analysis on this in years to come, but I posit that companies&apos; attempts to bring people back to the office is part of what touched off the &amp;quot;Great Resignation&amp;quot; and led to the mad shuffle of employment across the industry.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Several voting systems to &amp;quot;secure the vote&amp;quot; will come out in the next two years.&lt;/em&gt;&lt;/strong&gt; (0.7) You don&apos;t have to believe Trump&apos;s wild-eyed and clearly-debunked claims about election fraud to know that people are sensitive on the subject of voting. To the technology space, particularly the startup space, that just screams &amp;quot;I&apos;m a market that demands disruption! Disrupt me!&amp;quot; and the VCs will happily toss billions of dollars at companies that promise to let you &amp;quot;vote from your smartphone&amp;quot; securely and safely. Most of these will crash and burn and take those billions down with them, but a few might make it out of beta and maybe even find some adoption in a few of the smaller states (Rhode Island would be my first target). Personally, I don&apos;t think there&apos;s a damn thing wrong with the system we have at the moment--but as with many things in the startup world, it&apos;s not about fact, it&apos;s about perception.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: -1&lt;/strong&gt; Well, I suppose I have another year to go before I have to call the result on this one, but for the most part we seem pretty content to just let things go as they are. If anything, one half of the political electorate seems to prefer the idea of restricting who gets to vote and how easily, rather than trying to secure better the systems of how we vote. It will be interesting to see how this continues over the next year, going into the mid-term elections, but right now it looks very much like the conservatives of the country are quite content to keep in place the same system they deeply distrusted over the last year--and, I suspect, leave them the opportunity to cry foul if and when their candidate(s) loses again next year.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Social media spinoffs will proliferate.&lt;/em&gt;&lt;/strong&gt; (0.6) Parler was just the beginning--now that we&apos;ve proven beyond the shadow of a doubt that we really can&apos;t get along together on a single social media platform, many groups will start flocking to social media platforms of their own choice, further polarizing the conversations there. It will have nothing to do with technology or security--it will have everything to do with humans&apos; basic desire to be among people &amp;quot;just like me&amp;quot;. Ironically, Facebook and Instagram will be losing their stranglehold grip on the social media world just as they start feeling the ire of Congressional gaze, which will further their downward trend. These new platforms will have some space in which to grow and draw eyeballs--and unfortunately allow people to stew inside echo chambers even more.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: 0&lt;/strong&gt; There&apos;ve been a few that have gotten under way, but they&apos;ve really not seen a lot of uptick, it seems. We as a group are perhaps too deeply addicted to our habits of Facebook and Twitter to consider moving our social profile to a newcomer. That said, though, they&apos;re still out there, and drawing some attention, and it&apos;s important to remember that Rome (and Facebook) wasn&apos;t built in a day (or year), either.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Languages and platforms will march on, and no one will really care.&lt;/em&gt;&lt;/strong&gt; (0.8) Anybody know what version of Java is the latest? C#? JavaScript? Fact is, most of the popular languages in use are in the tapering-off point of the &amp;quot;value gained per new feature&amp;quot; curve, and most of us have stopped paying attention to the feature list of new releases. Sure, you may have some pet feature of C# you&apos;re waiting to see make it into the long-term-support (LTS) release, so your company can move to adopt that version of the language, but for the most part, whether that happens this year or next, it really makes little difference to your ship schedule. For the most part, now, knowing the latest features in these languages is about proving your knowledge and alpha-geek-ness, not about using them to solve actual business problems.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: +1&lt;/strong&gt; Java&apos;s at 18, C# is at 9 or 10 or something, and who even knows what ECMAScript 2021 looks like.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;A collegiate and university education backlash is about to begin.&lt;/em&gt;&lt;/strong&gt; (0.7) When the pandemic hit, all the schools went into lockdown, including the collegiate and university campuses that had for so many years told us that the thousands of dollars students spend there was for the &amp;quot;college experience&amp;quot;. When the &amp;quot;college experience&amp;quot; consists of Zoom calls from your home from professors who often couldn&apos;t figure out how to use Zoom for the first half of the semester, delivering substandard content compared to courses from Udemy or Khan Academy, and exposing professorial misconduct (like the &lt;a href=&quot;https://www.nydailynews.com/news/national/ny-oxnard-professor-admin-leave-video-berates-hearing-impaired-student-20210224-g63xws2lzveyznwvituuvrozle-story.html&quot;&gt;professor who chastised a hard-of-hearing student for &apos;not paying attention&apos; during remote classes&lt;/a&gt;) for all the world to see, it&apos;s really, really hard to understand why anyone would pay thousands of dollars per semsester for that privilege. Given how coding bootcamps can provide much of the tactical skills (but not the larger conceptual understanding--they&apos;re trade schools, not universities, and let&apos;s keep that clear) that employers are looking for in junior developers, why would I spend $50k to get that diploma from UC Riverside or Iowa State in four years? Colleges and universities are going to have to scramble to figure out how to keep from just doing &amp;quot;business as usual&amp;quot;, if they want to avoid a striking loss of registration numbers that will only get worse as the pandemic continues.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: 0&lt;/strong&gt; The backlash around remote education definitely shifted to the elementary and high schools, but thus far universities and colleges aren&apos;t feeling the sting--yet. Anecdotally, I talk with college students, and they&apos;re asking these same questions, though, and thus far the universities and colleges haven&apos;t really put together any kind of message that addresses it, so the backlash may be starting quietly. Expecting to see any sort of tangible or measurable result in a single calendar year might have been a little aggressive; this one may take a decade to play out. For now, I&apos;m still seeing people talk about it, but a lot of the energy is caught up in online-vs-in-person debates. Students and faculty simultaneously (a) don&apos;t want to expose themselves to COVID, and (b) don&apos;t want to spend their college experience online.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Resilience and failover will be the focus in the Ops-minded world.&lt;/em&gt;&lt;/strong&gt; (0.7) The huge loads on servers from people staying at home and using digital channels caught a lot of companies by surprise, and they suffered outages as their predictive load models failed them utterly. In 2021, these companies will put a bunch of engineering into making sure they can handle the load, just in time to see the load start to draw back down as people start getting out of their homes more. Once the pandemic eases up enough to allow us to leave the house and dine safely anywhere in town, we won&apos;t see that high-water mark of server load again for some time--but companies, like generals, love to prepare to fight the last war, and they will put a large investment of time, money, and thought into systems that can scale in time for the next pandemic (a hundred years from now).&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result: +1&lt;/strong&gt; It definitely was the focus during my time at Rocket Mortgage, and from watching some of the articles and periodicals around the DevOps space, resiliency and failover were definitely hot-button topics. Some of that could easily be confirmation bias, though, and honestly I was expecting more, so I&apos;m marking it a zero, Dude.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In summary:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;eleven predictions,&lt;/li&gt;
&lt;li&gt;three 0s,&lt;/li&gt;
&lt;li&gt;and three -1s&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;... leaving me with five +1s, just a shade under 50%. Not bad, and about my average, it seems.&lt;/p&gt;
&lt;h1&gt;2022 Predictions&lt;/h1&gt;
&lt;p&gt;With that settled up, let&apos;s take a look at what I think will happen across calendar year 2022.&lt;/p&gt;
&lt;p&gt;Overall, it&apos;s going to be &amp;quot;more of the same&amp;quot; with respect to the pandemic. Thanks to the intransigence of some selfish and closed-minded people, the COVID virus has plenty of people in whom it can mutate and incubate before spawing a new variant, and that will mean that COVID will, likely, remain a fact of our lives for quite some time to come. Hopefully we can get enough of a grip on it that it becomes more &amp;quot;comfortable&amp;quot; for us as a society, a la influenza, but COVID for the moment still represents a major threat to the lives and health of too many folks. For now, all indications are that there won&apos;t be a &amp;quot;cliff&amp;quot; that will indicate the end of the pandemic and a return to normal life; we will likely &amp;quot;taper down&amp;quot; slowly, masks and vaccine cards and boosters (and all the arguments that come with all of those) being a part of our lives for probably a half-decade to come.&lt;/p&gt;
&lt;p&gt;Specifically, though, I think 2022 will show us the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;5G rollout is going to be a lot more contentious than we expected.&lt;/em&gt;&lt;/strong&gt; (Probability 0.6) 5G rollout two years ago wasn&apos;t a sure thing, but then it was because of crackpot theories about how it would affect brainwaves or somesuch nonsense. Now, the &lt;a href=&quot;https://www.bbc.com/news/business-60042178&quot;&gt;FAA has concerns&lt;/a&gt;, and that&apos;s a helluva lot more serious. It&apos;s pretty likely that the technical issues will be addressed, but this could very well turn into the next conspiracy-theorist farmground, which in turn will create barriers and obstacles.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Demand for full-stack developers will continue to leave companies high-and-dry.&lt;/em&gt;&lt;/strong&gt; (0.8) If this isn&apos;t alreday self-evident to you, you&apos;re clearly not in a position of trying to hire engineers these days. Big Tech companies are throwing ever-greater compensation numbers at people, driving the equilibrium price for developers up, and that&apos;s before we even consider the ever-increasing numbers of tech jobs that are outpacing the numbers of people who can fill them. If a company is expecting to grow their developer staff significantly, trying to hire &amp;quot;full-stack&amp;quot; is going to run into significant hurdles, particularly if they aren&apos;t willing to move fast, take a few risks, &lt;em&gt;and&lt;/em&gt; pay handsomely.&lt;/p&gt;
&lt;p&gt;This is going to have some interesting second-order effects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Work-from-home will become normalized as part of the landscape.&lt;/strong&gt; (0.8) Talk to that one friend you have that&apos;s a classic Keynesian economist, and they&apos;ll tell you that when supply is tight and demand is high, in addition to a high equilibrium price, the market starts to see &amp;quot;complementary&amp;quot; and &amp;quot;supplementary&amp;quot; effects kicking in. In this case, those high-demand engineers are going to get their pick of the perks, and one that many of them seem to value highly is the flexibility to work from home. That in turn will create (or enhance) pressure to let everybody on the team to work remotely--or else find that you need to hire replacements to adjust for the attrition of people leaving for places who can, still, work from home.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Companies will start &amp;quot;growing&amp;quot; their own developer staff.&lt;/strong&gt; (0.6) It&apos;s not something that every company can do, but those that can are going to start thinking, &amp;quot;If I can&apos;t buy the people I need, then I&apos;ll have to grow them.&amp;quot; Rocket Mortgage was ahead of the game on this one, having put a program in place a few years ago already that was, for all intents and purposes, a developer bootcamp for people wishing ot make a mid-career change. Not all companies will have the resources of the nation&apos;s #1 mortgage lender, but other approaches are available: partner with existing bootcamps, join a few companies together to sponsor one, hire a bunch of juniors and apprentice them to others within the company, or even do something a little more informal like a mentoring program or internal book club or something. Whatever it is, though, those companies that start thinking aggressively about growing their next generation of developers are going to see it pay off; if you take a junior or a recent bootcamp grad and invest in them, their gratitude and loyalty will more than pay off.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Automation tools and platforms will climb in use.&lt;/strong&gt; (0.7) The more work we can pull off the senior full-stack developer, the more work they can get done that can&apos;t be automated. As a result, managers and execs are going to start looking for tools and platforms that can automate all the things--well beyond the whole &amp;quot;DevOps&amp;quot; suite of things. Workflows, processes, emails, the whole enchilda, it&apos;s all going to be &amp;quot;on the table&amp;quot; for anyone or anything that can cut the developer load down. This would be a good year to have an automation startup going.&lt;/p&gt;
&lt;p&gt;By the way, corollary to this: Tools to automate the use of online services--and the rampant abuse and fraud using those tools--will also climb through the roof. If you offer a website or an API (and who doesn&apos;t?!?), spend some time in 2022 figuring out how people can abuse your system. (If your answer is a confident, &amp;quot;They can&apos;t!&amp;quot;, you didn&apos;t think hard enough. If your answer is a confident, &amp;quot;They wouldn&apos;t!&amp;quot; then your business is clearly not diverse or interesting enough.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;No-code/low-code tools and platforms will surge.&lt;/strong&gt; (0.7) Same song, different verse: low supply plus high demand equals high equilibrium price for that good/service, and supplementary (replacement) options will begin to become more attractive. For the developer ecosystem, that&apos;s low-code/no-code tools and platforms. I expect there will be a ton of chaos and movement in this space, and probably by 2023 or 2024 these platforms will start to diversify as their various features commodotize. But that&apos;ll take a while--for now, we&apos;re just going to see a sharp rise in the use of these tools, mostly by companies that have never considered themselves &amp;quot;tech&amp;quot; companies. (And if you&apos;re a consulting provider to these sorts of firms, you might want to think about how to tap into this world--and not just by selling services on top of somebody else&apos;s low-code/no-code platform, because those vendors are going to be pushing the barrier-to-entry for use of their platform as low as they can reasonably get it--which means now you&apos;re just selling labor, not expertise.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Developer market will grow. Slowly.&lt;/strong&gt; (0.7) The other thing that a high equilibrium price does? Attract more players to it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Job descriptions will emphasize more about skills (including human skills) and less on degrees/certifications.&lt;/strong&gt; (0.8) One interesting corollary to the tight-labor-market perspective is that companies who are finding it hard to hire are going to start paying closer attention to their job descriptions and tune them more effectively to attract talent. Five years ago, &amp;quot;5 years Java&amp;quot; wouldn&apos;t have been really a great match against a senior C# development position; today, that&apos;ll totally work, if the candidate is down to learn C#. So let&apos;s not call it &amp;quot;5 years Java&amp;quot;, let&apos;s call it &amp;quot;Comfortable with an O-O enterprise language&amp;quot;.&lt;/p&gt;
&lt;p&gt;The &amp;quot;laundry list&amp;quot; of &amp;quot;X years in Y technology&amp;quot; are going to start giving way to &amp;quot;(Feeling) in (category)&amp;quot; kinds of descriptors, like &amp;quot;Comfortable in object-oriented languages&amp;quot; or &amp;quot;Conversant with Web front-end development&amp;quot;. Companies might have been able to let their ATS (applicant tracking system) pick and choose which resumes to view back when the supply was higher and they didn&apos;t have as many people they needed to hire; that&apos;s gone for now.&lt;/p&gt;
&lt;p&gt;Smart companies are also going to zoom in on their interview pipelines and look for ways to trim costs (elapsed time and person-hours being two metrics I&apos;d examine), as well as look at the overall efficiency of their interview pipeline (# of candidates against # of hires) to make sure their recruiting team is giving them the biggest bang-for-recruiting-buck.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Remote tooling vendors will look to improve.&lt;/em&gt;&lt;/strong&gt; (0.6) Teams, Zoom, WebEx, they all have one thing in common: We routinely lament the fact that &amp;quot;they all suck&amp;quot;. (Anecdotally, which one you think sucks the most appears to be directly proportional to the amount of time you use it.) The fact that we can do this sort of virtual meeting &lt;em&gt;at all&lt;/em&gt; is a pretty amazing thing (on the same order of, &lt;a href=&quot;https://www.youtube.com/watch?v=oTcAWN5R5-I&quot;&gt;&amp;quot;It&apos;s a chair, &lt;em&gt;in the sky&lt;/em&gt;!&amp;quot;&lt;/a&gt;, if you ask me), but there&apos;s still some things that the meeting tools don&apos;t really handle well (shared whiteboarding/doodling, for example, which is really important to technical conversations). The various players are now well-established--so long as we have hybrid WFA/WFO in place, these tools will be a part of our lives--so now they need to start figuring out how to differentiate from one another. (Which will commodotize over time, and arguably already has, but that&apos;s another analysis for another day.)&lt;/p&gt;
&lt;p&gt;As a corollary to this, look for lots of other tools to figure out how to embed/incorporate remote aspects into their workflow. Visual Studio Code started this, and I imagine the other IDE vendors are hard at work figuring out how to duplicate that feature or something similar to it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Older&amp;quot; tech will start to see a surge of interest and rise in adoption.&lt;/em&gt;&lt;/strong&gt; (0.6) This isn&apos;t a knock on the &amp;quot;older generation&amp;quot;, per se, (particularly because I&apos;m on the cusp of being a part of it), but the rise of complexity around all these tools and platforms and applications is just getting to the point that it&apos;s becoming a mess to keep track of anything. Case in point: How many streaming services are there? How many of us have different streaming services that go to particular devices and aren&apos;t available on other devices? (Or they could, IF we spent the time to configure something correctly. Maybe.) There&apos;s only so much complexity people can handle in their lives, and they&apos;re going to start looking for ways to claw some of that cognitive budget back by simplifying by going back to simpler tools. Case in point: I &lt;em&gt;really&lt;/em&gt; prefer straight POTS (plain old telephone service) calls these days over video meetings.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Theranos will teach us something... but we&apos;ll not be sure exactly what.&lt;/em&gt;&lt;/strong&gt; (0.5) The story of Theranos may have sent some ripples through the Silicon Valley around overhyped technology and throwing huge amounts of cash into hot startups, but the lessons to be learned from the whole thing are less clear. Don&apos;t invest in wild promises? Dude, that&apos;s what the VC funds are &lt;em&gt;built&lt;/em&gt; to do. Don&apos;t fall for first-time founders&apos; claims of what they can make happen? The VC funds are often made up of money from first-time founders who are convinced their success has everything to do with their &amp;quot;methodology&amp;quot; and little-to-nothing to do with luck. Theranos represents everything that&apos;s wrong with the startup community... but we aren&apos;t sure what that means. Much will be written, little will be done, and we&apos;ll be having this conversation again in a few years around a different startup, because the Valley would rather lose billions than learn a lesson.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;NFTs, crypto; corporate promotion of NFTs followed by a huge backlash/abandonment.&lt;/em&gt;&lt;/strong&gt; (0.6) In the words of several of my schoolmates growing up, &amp;quot;ERmigawd, how GRODY&amp;quot;. Blockchain/crypto-based tech systems aren&apos;t even trying to make sense anymore, they&apos;re just throwing big words at investment funds and relying on the opacity of the words to convince people they&apos;re the next hot investment. NFTs are just the latest in the Ponzi pyramid--you get to own a certificate that declares nothing more than the fact that you own a certificate. (No, you don&apos;t own the image, or the original, you literally just own the certificate; see &lt;a href=&quot;https://news.ycombinator.com/item?id=29290841&quot;&gt;&amp;quot;NFTs are like those old &apos;star registry&apos; scams&amp;quot;&lt;/a&gt; for an apt example and corresponding debate.) Big companies--Twitter, for example--are starting to get into the NFT thing, but let&apos;s be honest, many of them have money to burn, and throwing a billion USD into this, against a 1% chance of it actually being something beyond just a huge pit into which you toss money, is actually a reasonable move. But average folks buying the NFTs are going to figure out the scam fairly quick, and those celebrity buyers even quicker, and that&apos;s going to create a backlash and a hue-and-cry for regulation, and people will scurry out of them almost as fast as they scurried into them.&lt;/p&gt;
&lt;p&gt;Or not--some of those star registries are still operating to this day, so... &lt;em&gt;shrug&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;More non-developer-sales companies will build Developer Relations teams.&lt;/em&gt;&lt;/strong&gt; (0.7) This is one of my happier predictions, in that it&apos;s one of my predictions that would make me happy if it comes true. :-) Developer Relations used to be &amp;quot;technical sales&amp;quot; to developers, something that Microsoft and Google and Amazon and other companies-who-sell-tech-to-development-departments would create and support, in order to have folks who knew how to talk to their principal customers--developers--about the things companies wanted to sell. But over the past decade, the definition of &amp;quot;developer relations&amp;quot; is shifting, becoming less sales/marketing-to-developers, and more &amp;quot;connecting technologists--both internal and external to the company--to their corresponding communities&amp;quot;. I&apos;ve personally been a part of this twice, building DevRel teams for two companies whose principal customer base aren&apos;t developers. It takes time, and it takes dedication, but let&apos;s be clear: If your company has an API, you clearly expect developers to use it, and if you expect developers to use your API, you need a team to meet them on their turf and be there when they have questions and triage their bug reports and provide samples and so on and so on and so on. All of that falls under the general heading of &amp;quot;developer relations&amp;quot;, and if you don&apos;t have one of those teams, you may as well shut down any expectations of people outside your company using your API.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Open-source backlash/flight/pressure grows.&lt;/em&gt;&lt;/strong&gt; (0.7) One of the sadder things we witnessed in 2021 was the log4j security vulnerability debacle. I call it a debacle not because I blame the log4j team for having that feature in the library (although, honestly, I have long believed that diagnostic logs are way over-engineered for the problem they need to solve), but because companies&apos; worst tendencies around open-source software came to full flower and fruition, and made it very clear that the FOSS ecosystem is inherently unsustainable in its current form.&lt;/p&gt;
&lt;p&gt;The current ecosystem is built, realistically, on a Communist economic model: &amp;quot;From each (developer willing to volunteer their time and energy), according to their ability, to each (open-source project), according to its needs.&amp;quot; In theory, the system works wonderfully well; in practice, it has no answer to actors who are willing to &amp;quot;coast&amp;quot; on the backs of the effort of those willing to volunteer their time and energy. When a given community is small, and social pressures can be used to ensure fair distribution of effort, this model can work. (Think families, or startups, or even apartment co-operatives.) When the community grows large enough that we aren&apos;t faced with the disapproving stares of our peers for coasting.... And here we are.&lt;/p&gt;
&lt;p&gt;Open-source project maintainers, particularly those projects that aren&apos;t the most amazing/sexy thing of the year, do tremendous amounts of work, and get zero recognition when they get it right, and all the media focus and scorn when they get it wrong. That isn&apos;t going to change any time soon, and the contributors will slowly drain off, creating more pressure on the remaining contributors, until something kicks in to start replenishing the pool. (My bet is companies will eventually face up to the fact that they depend on these FOSS projects like other companies do their supply chain, and start investing in it, but it&apos;ll take a while, and even then there will still be that temptation to coast.)&lt;/p&gt;
&lt;p&gt;All of this is going to create greater instability in this community, and cause some serious soul-searching amongst the people upon whose backs it&apos;s built.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;strong&gt;&lt;em&gt;New programming languages are going to start the R&amp;amp;D cycle on languages again.&lt;/em&gt;&lt;/strong&gt; (0.6) They may be &amp;quot;service-oriented&amp;quot;, they may be something else, but languages like &lt;a href=&quot;http://ballerina.io&quot;&gt;Ballerina&lt;/a&gt;, &lt;a href=&quot;https://www.jolie-lang.org/&quot;&gt;Jolie&lt;/a&gt;, and &lt;a href=&quot;https://darklang.com/&quot;&gt;Dark&lt;/a&gt; are basically suggesting that there&apos;s a new level of abstraction to be sought as a linguistic first-class citizen. Frankly, if you&apos;ve been doing any sort of service development (micro- or otherwise), you&apos;ve felt the costs and pain (in terms of complexity and the number of moving parts you have to track) of doing so. Cloud vendors are trying to suggest that &amp;quot;serverless&amp;quot; is the way to go, but in a lot of ways it just trades the complexity off to other ares of the app; a new paradigm is what&apos;s needed, to bring the complexities back down to human-manageable levels.&amp;quot;&lt;/p&gt;
&lt;p&gt;I wrote that for the 2020 Predictions, and I still believe it to be true. Ballerina is starting to build its hype, but more importantly we&apos;re starting to see people exploring languages as ways of approaching low-code/no-code kinds of development. I think this is only going to increase as the year(s) move on.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Some company is going to be really happy they took me up on that hypothetical in the second paragraph.&lt;/em&gt;&lt;/strong&gt; (0.8) The one about contacting me about figuring out a leadership role within the company. I build some strong teams that can do some really interesting things....&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Talk to you all next year... if not sooner.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2021 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2021/2021-tech-predictions.html</link>
      <pubDate>Thu, 25 Feb 2021 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2021/2021-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;It&apos;s that time of the year again, when I make predictions for the upcoming year. As has become my tradition now for nigh-on a decade, I will first go back over last years&apos; predictions, to see how well I called it (and keep me honest), then wax prophetic on what I think the new year has to offer us.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;As per previous years, I&apos;m giving myself either a &lt;strong&gt;+1&lt;/strong&gt; or a &lt;strong&gt;-1&lt;/strong&gt; based on a purely subjective and highly-biased evaluational criteria as to whether it actually happened (or in some cases at least started to happen before 31 Dec 2020 ended).&lt;/p&gt;
&lt;h2&gt;In 2020...&lt;/h2&gt;
&lt;p&gt;... I wrote a lot of stuff. (That always seems to happen when I do these.) Let&apos;s start. I&apos;ll include the full text of what I wrote in each bullet point first, then put the &lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; after it with whatever insights or comments seem relevant. (Arguably none of them are, but hey, it&apos;s my set of predictions, so....)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;2020 is the start of a new decade, and that usually means predictors and prophets and tech pundits and other folks who think they know a bunch of stuff try to convince you that this is the start of something entirely new. (It&apos;s those kinds of folks who predicted flying cars and hoverboards, by the way.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let&apos;s call out the really obvious thing NOBODY predicted: pandemic. COVID-19. Lockdown. Remote work for everybody. Absolutely &lt;strong&gt;&lt;em&gt;nobody&lt;/em&gt;&lt;/strong&gt; had that on their predictions BINGO card, and to pretend even remotely otherwise is disingenuous to say the least. This past year has been simultaneously the longest of our modern lives, and the most alone most of us have ever felt together. So many things just got wiped out by the necessary health-preservation tactics (masks, lockdown, etc) that the pandemic required.&lt;/p&gt;
&lt;p&gt;So, with that out of the way, let&apos;s begin.&lt;/p&gt;
&lt;p&gt;I wrote....&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;strong&gt;&lt;em&gt;Everybody is going to go ga-ga over 5G, and it won&apos;t make a whit of difference.&lt;/em&gt;&lt;/strong&gt; (0.6) Apparently, we have to go learn the Eight Fallacies of Distributed Computing all over again, again. On top of which, 5G is rumored to play havoc with &lt;a href=&quot;https://www.aip.org/fyi/2019/noaa-warns-5g-spectrum-interference-presents-major-threat-weather-forecasts&quot;&gt;weather prediction&lt;/a&gt;, so don&apos;t expect this one to go through with the ease of the 3G or 4G upgrades. I suspect that this is going to face some major backlash, probably in 2021 or 2022, particularly if it gets deployed widely in 2020.&amp;quot; &lt;strong&gt;Result: 0&lt;/strong&gt; Um... yeah, we want ga-ga, but not in a good way; somehow, 5G was tagged by the various conspiracy-theorist-peddling QAnon&apos;ers as being tied to all sorts of negative and nasty things, for reasons I cannot even begin to fathom. Mobile companies still tout it, but any sort of excitement--or discussion--we might have had about it got drowned in the demands for additional bandwidth as we all went remote, and then the inane conspiracy discussions. (Really? Bill Gates is going to use the vaccine to implant chips in your blood that will enable you to be controlled by 5G? Not even the wackiest sci-fi author would dare try to make this up.) I kinda got the &amp;quot;ga-ga&amp;quot; part right, but everything else was wrong. 0 points.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;strong&gt;&lt;em&gt;Quantum computing will be the next major hype machine.&lt;/em&gt;&lt;/strong&gt; (0.6) From the &amp;quot;our blockchain cannot possibly be defeated by any crypto-cracking tool known to man,&amp;quot; we whiplash over to, &amp;quot;our quantum computing platform can crack any modern cryptography in seconds&amp;quot; without missing a beat. Quantum will be the Huge New Thing, and everybody will want to take a crack at the quintillions or whatever of CPU cycles that quantum computing represents... and like most of these kinds of hype waves, really, quantum computing will be useful in a small set of niche verticals, and useless to everybody else.&amp;quot; &lt;strong&gt;Result: 0&lt;/strong&gt; In the face of the pandemic, anything that wasn&apos;t about remote work or communication got brutally shoved off to the side. Quantum computing might be the darling of the hype in 2021, but it certainly wasn&apos;t in 2020.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;strong&gt;&lt;em&gt;Data privacy is going to start to separate from the larger &amp;quot;security&amp;quot; set of issues.&lt;/em&gt;&lt;/strong&gt; (0.5) Companies are having to take &amp;quot;security&amp;quot; seriously, but there&apos;s &amp;quot;serious&amp;quot; and then there&apos;s &amp;quot;if we don&apos;t do this we can&apos;t do business anymore&amp;quot; serious. Data privacy will fall into that latter category, given the legal penalties that will face violators of GDPR and the new California laws. This means that tools and products (likely databases and its related ilk) will start advertising and promoting their &amp;quot;privacy-by-design&amp;quot; kinds of features, as a way of making it &amp;quot;easy&amp;quot; to implement privacy in your enterprise, big or small. But they won&apos;t want to be held liable in the event of a general hack, so they&apos;ll very carefully and clearly outline differences between &amp;quot;privacy&amp;quot; and the larger field of &amp;quot;security&amp;quot;.&amp;quot; &lt;strong&gt;Result: +1&lt;/strong&gt; At this point, any company that isn&apos;t making deep inroads into trying to corral their data and control where it goes and who has access to it is the subject of investigation, and even Congress is starting to slide its Sauron-esque eye over the &amp;quot;Big Tech&amp;quot; companies. This is not a comfortable place for many companies to be, and its only going to get worse in 2021.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;strong&gt;&lt;em&gt;Kubernetes all the things... to whatever comes next.&lt;/em&gt;&lt;/strong&gt; (0.4) Kubernetes has pretty much locked up the container world, which means that we will now start to see what peple are suggesting we need to do &lt;em&gt;after&lt;/em&gt; Kubernetes, because the stack has to keep growing deeper, or else vendors have to start competing with something in the middle of the stack, which means having to get into a feature war or fight for standardization somehow, neither of which are proven routes to success.&amp;quot; &lt;strong&gt;Result: +1&lt;/strong&gt; Kubernetes has won, for whatever that means, in the War for Container Management. Now.... what next? Lots of companies are standardizing on Kubernetes, still, and we&apos;re starting to see some inroads into the next big thing, but again, so much of this was derailed by a simple need to adjust to an entirely-work-from-home work shift that anything else beyond that was just postponed or buried.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;strong&gt;&lt;em&gt;The demand for &amp;quot;full-stack&amp;quot; developer unicorns will reach its peak.&lt;/em&gt;&lt;/strong&gt; (0.7) Anybody who&apos;s watching the job sites and LinkedIn listings can see that everybody wants a developer who knows a major enteprise language (Java, C#, etc), Docker, Kubernetes, SQL and NoSQL skills, JavaScript (preferably knowing Angular, React, or Vue, and possibly all three), HTML, CSS, XML, JSON, one of the major cloud platforms (AWS, Azure, or GCP, certificates from certification authorities in each of those preferred), and sometimes even more beyond that. Folks, that&apos;s not a developer, that&apos;s an entire IT department (thank you, Twitter meme), and at a certain point that bubble is going to burst. But not this year.&amp;quot; &lt;strong&gt;Result: +1&lt;/strong&gt; It&apos;s definitely peaking, if it hasn&apos;t already, as witnessed by the success of some companies (&lt;em&gt;cough&lt;/em&gt; Netflix &lt;em&gt;cough&lt;/em&gt;) that won&apos;t hire anybody &lt;em&gt;but&lt;/em&gt; full-stack developers, and senior developers at that. But the community has started to wise up to the idea that this is looking for needles in haystacks, and that you can actually get further with a full-stack &lt;em&gt;team&lt;/em&gt; than a team of full-stacks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;strong&gt;&lt;em&gt;New programming languages are going to start the R&amp;amp;D cycle on languages again.&lt;/em&gt;&lt;/strong&gt; (0.6) They may be &amp;quot;service-oriented&amp;quot;, they may be something else, but languages like &lt;a href=&quot;http://ballerina.io&quot;&gt;Ballerina&lt;/a&gt;, &lt;a href=&quot;https://www.jolie-lang.org/&quot;&gt;Jolie&lt;/a&gt;, and &lt;a href=&quot;https://darklang.com/&quot;&gt;Dark&lt;/a&gt; are basically suggesting that there&apos;s a new level of abstraction to be sought as a linguistic first-class citizen. Frankly, if you&apos;ve been doing any sort of service development (micro- or otherwise), you&apos;ve felt the costs and pain (in terms of complexity and the number of moving parts you have to track) of doing so. Cloud vendors are trying to suggest that &amp;quot;serverless&amp;quot; is the way to go, but in a lot of ways it just trades the complexity off to other ares of the app; a new paradigm is what&apos;s needed, to bring the complexities back down to human-manageable levels.&amp;quot; &lt;strong&gt;Result: 0&lt;/strong&gt; Dark went under, but Ballerina and Jolie are still building some interest and momentum, and other new languages also look like they&apos;re getting ready to start stepping into the light. The era of object dominance is coming to a close, probably by the end of this decade.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;strong&gt;&lt;em&gt;Automation will take an even stronger seat at the conceptual table.&lt;/em&gt;&lt;/strong&gt; (0.7) &amp;quot;If I can&apos;t find developers to do these things I need to get done,&amp;quot; fumes the CEO, &amp;quot;I&apos;ll go out and find some tools that can do all that stuff without requiring them!&amp;quot; Automation, particularly that enabled by low-code or no-code tools, will begin to skyrocket as a desirable target, even though this will mean that non-developers will start doing developer-ish things, and before long, will run afoul of the same basic problems that always strike when non-developers start doing developer-ish things. (Truthfully, this is related to the programming languages issue; companies need better &amp;quot;technical agility&amp;quot; out of their IT departments, and right now, nothing is providing that. They will look for anything, no matter how outlandish or outrageous, to provide that, and in 2020 that pressure will really make itself felt.)&amp;quot; &lt;strong&gt;Result: +1&lt;/strong&gt; The whole &amp;quot;low-code&amp;quot; and &amp;quot;no-code&amp;quot; space is really beginning to make its presence felt, as IT departments are beginning to figure out how to use them within their larger enterprise fabric.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;strong&gt;&lt;em&gt;Ted will write another one of these in a year.&lt;/em&gt;&lt;/strong&gt; (0.99; it should be a 1.0, but there’s always the chance that the whole country will undergo some kind of apocalypse, thanks to the orange buffoon who sits in the White House, that would keep me from writing this.)&amp;quot; &lt;strong&gt;Result: -1&lt;/strong&gt; Actually, I&apos;m going to give myself a -1 on this, because it&apos;s now the end of February before I got around to writing. Part of that is due to taking on a new role inside Quicken Loans in March of 2020, one which has completely absorbed every scrap of free time and attention I had. Additionally, a lot of the &amp;quot;writing time&amp;quot; I normally use was denied me--time on airplanes and in hotels. We&apos;ll see how 2021 goes, I suppose.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;2021 Predictions&lt;/h1&gt;
&lt;p&gt;We began the new year with chaos and tragedy, at least here in the United States. The Capitol Insurrection of 2021, fueled by blatantly-false claims of election fraud and whipped into a frenzy by a narcissist whose continued civic freedom depends on being &amp;quot;untouchable&amp;quot; by legal recourse, meant that a lot of us had things far, far more important than technology trends to worry about. It&apos;s been a rough two months since then, as well, as we struggle to balance hopes for vaccines and coordinated federal response to this damnable virus against the mess that the year-plus of deliberate neglect from the previous US Adminstration created. It was hard on everyone, and in a lot of ways we all just want to &amp;quot;get back to normal&amp;quot; for whatever definition of &amp;quot;normal&amp;quot; you care to use. Unfortunately, I don&apos;t think we&apos;re anywhere close to &amp;quot;normal&amp;quot; yet, though the massive rollout of vaccination programs will help, but I&apos;ll get to that in a second. For now, let&apos;s look at some predictions for 2021.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Conferences will begin to pick up in September.&lt;/em&gt;&lt;/strong&gt; (Probability: 0.5) This is an important one to me, personally, because I miss going places and hanging out with friends and talking technology and trends and stuff. My thinking is that the vaccinations will reach a popular &amp;quot;critical mass&amp;quot; somewhere in June--which won&apos;t be yet &amp;quot;herd immunity&amp;quot; but enough so that everyone can know somebody personally who&apos;s been vaccinated and &amp;quot;nothing bad happened&amp;quot;--which would then mean that conferences will scramble to put something together as quickly as they can, but will still need a few momths&apos; lead time. Other countries, who have been more aggressive to fight the virus, will be open sooner, but the US will lag, because we&apos;d rather let people die while arguing &amp;quot;freedoms&amp;quot; than take the pragmatic route of eliminating the virus and &lt;em&gt;then&lt;/em&gt; do the debates.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Remote (anything) is going to be a huge focus.&lt;/em&gt;&lt;/strong&gt; (0.7) In 2020, we had to learn how to survive without driving anywhere or stepping inside other buildings. UberEats, DoorDash, GrubHub, all these &amp;quot;remote dining&amp;quot; experiences surged to the forefront of our mobile devices&apos; home screens. Retailers figured out how to do &amp;quot;remote shopping&amp;quot;, enabling curbside or in-store pickups. Amazon, of course, saw a huge surge in use, but a surprising number of retailers took &lt;em&gt;huge&lt;/em&gt; leaps to control their own remote distribution channel. Those that didn&apos;t will quickly start to figure it out on their own--and Amazon may actually lose some market share as a result, as for years the principal thing Amazon did was provide that remote distribution channel. Before, when that was just one of several options, it wasn&apos;t important enough to retailers to figure out--when it became their &lt;em&gt;only&lt;/em&gt; option, though, they moved fast and slapped enough together to make it all work. In 2021, they&apos;ll start to tune, improve, and perfect those channels, and Amazon will really need to start aggressively fighting against those new channels.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Amazon will get the Congressional eyeball.&lt;/em&gt;&lt;/strong&gt; (0.5) Bezos already took a hit to his brand with the revelations of his infidelity to his wife, and Amazon&apos;s most recent union-busting efforts just added to the bad PR. Amazon will start to get more and more scrutiny as different companies start looking for reasons to pull their goods out of the Amazonian warehouses and do the distribution themselves--and that will cause Amazon to get a little desperate lest its profit margins come down too far... and that in turn will trigger some undesirable behavior, followed by calls for inquiry and oversight.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Bitcoin and other cryptocurrencies start drawing fire from unlikely places.&lt;/em&gt;&lt;/strong&gt; (0.4) &lt;a href=&quot;https://www.bbc.com/news/technology-56012952&quot;&gt;&amp;quot;Bitcoin consumes &apos;more electricity than Argentina&apos;&lt;/a&gt;, while just a year prior, it was &lt;a href=&quot;https://www.bbc.com/news/technology-48853230&quot;&gt;Switzerland&lt;/a&gt;. And its carbon footprint is &lt;a href=&quot;https://www.cnbc.com/2021/02/05/bitcoin-btc-surge-renews-worries-about-its-massive-carbon-footprint.html&quot;&gt;comparable to that of New Zealand&lt;/a&gt;. Whatever your thoughts about the viability of Bitcoin and other digitial currencies, the act of mining it is not only consuming ridiculous amounts of resources, that consumption is triggering wider ecological woes, and that&apos;s going to draw fire from a lot of different corners of the landscape--particularly because for so many people, it&apos;s just a weird geek-fan-whatever thing that doesn&apos;t have any impact on the wider world. Sooner or later, some country is going to take a hard-line stance against it, and that will start the dominoes in a negative direction.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&apos;AI&apos; and &apos;machine learning&apos; are going to run into major backlash.&lt;/em&gt;&lt;/strong&gt; (0.6) Amazon ran into ethical issues with its use of machine-learned models for interviewing and hiring, because they didn&apos;t do the right amount of validation and verification of their models before putting them into production. Not a lot of companies are going to have the patience or AI-savvy to do that, either, and as a result, media backlash will start turning the shine of AI and machine learning into glare. By years&apos; end, we may even see Congressional inquiry into the subject(s), under the umbrella of widespread investigation into &amp;quot;Big Tech&amp;quot;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Any tech company that wants to compete will need to enable WFH on demand.&lt;/em&gt;&lt;/strong&gt; (0.8) Look, this past year made it pretty obvious that anybody in the technology space can do their job from anyplace in the country--if not the world. Couple that with a continued insatiable demand for tech talent, and you are quickly setting up the model for a buyers&apos; market when it comes to finding a job. &amp;quot;Hmm. You say your company needs me in the office, but this other company over there doesn&apos;t need that. Why should I work for you and add wear and tear to the streets, my car, and my nerves?&amp;quot; Not to mention that when you can work-from-home, you can realistically work-from-anywhere, including your parents&apos; place while the kids are out building snowmen with grandma and grandpa. Some companies will fight &lt;em&gt;hard&lt;/em&gt; to bring people back to the office, but they&apos;re going to be fighting an uphill battle, and may well lose out on some prime tech talent if they can&apos;t figure out how to be flexible. On that same note, if a company cannot or will not embrace a culture of &amp;quot;remote first&amp;quot; to allow those in the building and those outside the building to work on the same, level, playing field, that company will find itself scooping up candidates from the bottom half of the talent pool.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Several voting systems to &amp;quot;secure the vote&amp;quot; will come out in the next two years.&lt;/em&gt;&lt;/strong&gt; (0.7) You don&apos;t have to believe Trump&apos;s wild-eyed and clearly-debunked claims about election fraud to know that people are sensitive on the subject of voting. To the technology space, particularly the startup space, that just screams &amp;quot;I&apos;m a market that demands disruption! Disrupt me!&amp;quot; and the VCs will happily toss billions of dollars at companies that promise to let you &amp;quot;vote from your smartphone&amp;quot; securely and safely. Most of these will crash and burn and take those billions down with them, but a few might make it out of beta and maybe even find some adoption in a few of the smaller states (Rhode Island would be my first target). Personally, I don&apos;t think there&apos;s a damn thing wrong with the system we have at the moment--but as with many things in the startup world, it&apos;s not about fact, it&apos;s about perception.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Social media spinoffs will proliferate.&lt;/em&gt;&lt;/strong&gt; (0.6) Parler was just the beginning--now that we&apos;ve proven beyond the shadow of a doubt that we really can&apos;t get along together on a single social media platform, many groups will start flocking to social media platforms of their own choice, further polarizing the conversations there. It will have nothing to do with technology or security--it will have everything to do with humans&apos; basic desire to be among people &amp;quot;just like me&amp;quot;. Ironically, Facebook and Instagram will be losing their stranglehold grip on the social media world just as they start feeling the ire of Congressional gaze, which will further their downward trend. These new platforms will have some space in which to grow and draw eyeballs--and unfortunately allow people to stew inside echo chambers even more.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Languages and platforms will march on, and no one will really care.&lt;/em&gt;&lt;/strong&gt; (0.8) Anybody know what version of Java is the latest? C#? JavaScript? Fact is, most of the popular languages in use are in the tapering-off point of the &amp;quot;value gained per new feature&amp;quot; curve, and most of us have stopped paying attention to the feature list of new releases. Sure, you may have some pet feature of C# you&apos;re waiting to see make it into the long-term-support (LTS) release, so your company can move to adopt that version of the language, but for the most part, whether that happens this year or next, it really makes little difference to your ship schedule. For the most part, now, knowing the latest features in these languages is about proving your knowledge and alpha-geek-ness, not about using them to solve actual business problems.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;A collegiate and university education backlash is about to begin.&lt;/em&gt;&lt;/strong&gt; (0.7) When the pandemic hit, all the schools went into lockdown, including the collegiate and university campuses that had for so many years told us that the thousands of dollars students spend there was for the &amp;quot;college experience&amp;quot;. When the &amp;quot;college experience&amp;quot; consists of Zoom calls from your home from professors who often couldn&apos;t figure out how to use Zoom for the first half of the semester, delivering substandard content compared to courses from Udemy or Khan Academy, and exposing professorial misconduct (like the &lt;a href=&quot;https://www.nydailynews.com/news/national/ny-oxnard-professor-admin-leave-video-berates-hearing-impaired-student-20210224-g63xws2lzveyznwvituuvrozle-story.html&quot;&gt;professor who chastised a hard-of-hearing student for &apos;not paying attention&apos; during remote classes&lt;/a&gt;) for all the world to see, it&apos;s really, really hard to understand why anyone would pay thousands of dollars per semsester for that privilege. Given how coding bootcamps can provide much of the tactical skills (but not the larger conceptual understanding--they&apos;re trade schools, not universities, and let&apos;s keep that clear) that employers are looking for in junior developers, why would I spend $50k to get that diploma from UC Riverside or Iowa State in four years? Colleges and universities are going to have to scramble to figure out how to keep from just doing &amp;quot;business as usual&amp;quot;, if they want to avoid a striking loss of registration numbers that will only get worse as the pandemic continues.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Resilience and failover will be the focus in the Ops-minded world.&lt;/em&gt;&lt;/strong&gt; (0.7) The huge loads on servers from people staying at home and using digital channels caught a lot of companies by surprise, and they suffered outages as their predictive load models failed them utterly. In 2021, these companies will put a bunch of engineering into making sure they can handle the load, just in time to see the load start to draw back down as people start getting out of their homes more. Once the pandemic eases up enough to allow us to leave the house and dine safely anywhere in town, we won&apos;t see that high-water mark of server load again for some time--but companies, like generals, love to prepare to fight the last war, and they will put a large investment of time, money, and thought into systems that can scale in time for the next pandemic (a hundred years from now).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There&apos;s probably a few more I could toss off, but I think that&apos;s probably enough to engender some discussion and guarantee a few sharp rocks half-heartedly tossed my way. Love to hear your thoughts in the Disqus comments at the bottom of the blog, and I wish all of you a safe and speedy recovery from the pandemic in which we find ourselves; mask up, wash up, and stick with the science, so that in time, we can all go back to living our best lives similarly to how we did it in 2019.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2020 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2020/2020-tech-predictions.html</link>
      <pubDate>Thu, 16 Jan 2020 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2020/2020-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;It&apos;s that time of the year again, when I make predictions for the upcoming year. As has become my tradition now for nigh-on a decade, I will first go back over last years&apos; predictions, to see how well I called it (and keep me honest), then wax prophetic on what I think the new year has to offer us.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;As per previous years, I&apos;m giving myself either a &lt;strong&gt;+1&lt;/strong&gt; or a &lt;strong&gt;-1&lt;/strong&gt; based on a purely subjective and highly-biased evaluational criteria as to whether it actually happened (or in some cases at least started to happen before 31 Dec 2019 ended).&lt;/p&gt;
&lt;h2&gt;In 2019...&lt;/h2&gt;
&lt;p&gt;... I wrote a lot of stuff. (That always seems to happen when I do these.) Let&apos;s start. I&apos;ll include the full&lt;br /&gt;
text of what I wrote in each bullet point first, then put the &lt;strong&gt;&lt;em&gt;Result&lt;/em&gt;&lt;/strong&gt; after it with whatever insights or&lt;br /&gt;
comments seem relevant. (Arguably none of them are, but hey, it&apos;s my set of predictions, so....)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Blockchain might actually start being understood.&lt;/em&gt;&lt;/strong&gt; (Probability 0.4) Blockchain itself is not going away—if anything, companies seem to be putting more resources into it, not less—which suggests that enough people are seeing something of value buried deep (very deep) inside the hype. It may not be clear yet what it is, but that message is going to start trickling and filtering out and a few people might actually start to clue in on how best to use it. &lt;strong&gt;&lt;em&gt;Result: 0&lt;/em&gt;&lt;/strong&gt; Honestly, I&apos;m not sure how to score this one. On the one hand, we are starting to see &lt;a href=&quot;https://neo.org/&quot;&gt;some companies&lt;/a&gt; coming out with tooling and platforms that are centered around blockchains, which lends itself by definition to allowing the technology to be better understood. On the other hand, though, can anybody really, actually, describe what the hell it is? Rather than make the strong case for either point, I&apos;m just going to call this a zero and move on.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;AI and ML will begin to start separating... a little.&lt;/em&gt;&lt;/strong&gt; (0.6) There’s lots of things that fall under the umbrella term “artificial intelligence”, and machine learning is only one of them. As we get more experience with ML in practical usage, we’ll start to see that the different branches of AI are useful for different things, and we’ll begin to use those terms a little more carefully. Look for “natural language” and “expert systems” and “machine learning” to start getting used independently, rather than the catch-all “AI”. &lt;strong&gt;&lt;em&gt;Result: -1&lt;/em&gt;&lt;/strong&gt; I just can&apos;t give myself a point here. There&apos;s a few places that are starting to discern between some of the terms, but for the most part, &amp;quot;AI&amp;quot; and &amp;quot;ML&amp;quot; are still entirely synonymous, and that is just confusing the hell out of everybody.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;AI will start to move out of the startup and into the enterprise.&lt;/em&gt;&lt;/strong&gt; (0.7) Lots of people have kicked their AI startup off, and lots of big companies have started AI initiatives within their own companies, and they’re all finding… this stuff is hard. And what’s worse, the kind of skills required to do “AI” (whichever flavor you care to name) are rare, and those departments simply will resist scaling to the rest of the company. What usually happens after that first wave of interest, however, is that a small group of companies start to figure out how to apply AI to more mundane and practical purposes inside the big companies’ IT space, and that’s where the serious money lives. Sure, there’s going to be some flashy bits about robots and image recognition and stuff, but the real money is waiting to be made in machine learning being used to discover patterns in the data that up until this point mostly got discovered by accident. Look for a few companies to start selling AI not as a raw technology, but as part of a toolchain that a company can buy to do “something else”. &lt;strong&gt;&lt;em&gt;Result: +1&lt;/em&gt;&lt;/strong&gt; Oh, yeah, it&apos;s happening. It&apos;s hard to point to examples, but just about everybody I know in the space is talking about how they&apos;re using AI inside of a large enterprise, in many cases by virtue of the large enterprise having bought into one of the fourteen-million different AI startups. Bunch of it will probably fail, miserably, but that&apos;s really never stopped anything on the enterprise hype curve, and frankly, is all part of the cycle.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Amazon gets hauled in front of the DOJ.&lt;/em&gt;&lt;/strong&gt; (0.8) If it doesn’t happen this year, it’ll happen in 2020. Jeff Bezos has been doing a great job of staying out of the limelight when it comes to the ugly whispers of “monopoly”, but good Lord, folks, Amazon is clearly making no secret of the fact that it wants to take over the entire retail experience—and when you couple that with the fact that Amazon is now opening brick-and-mortar stores, there’s not a huge leap from “Company using its monopoly power to drive competitors out of business by taking losses on sales” to “Amazon founder Jeff Bezos was in Washington DC today to sit in front of a Congressional inquiry…“. Particularly when Amazon just bought Whole Foods, a non-technology company if ever there was one. &lt;strong&gt;&lt;em&gt;Result: -1&lt;/em&gt;&lt;/strong&gt; Oh, but not for lack of trying---Trumpie has been doing everything short of putting Bezos in front of a Congressional impeachment trial to try and shoot the guy down, and it somewhat surprises me that putting them in front of a monoply accusation hasn&apos;t occurred to any of his followers yet. Either way, though, it didn&apos;t happen, so no point for me.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Facebook undergoes some kind of radical transformation.&lt;/em&gt;&lt;/strong&gt; (0.8) Zuckerberg is on the ropes, whether he realizes it or not. People are quitting the app in droves. Milennials aren’t taking it up. Every single day, various political groups scream about Facebook’s censorship of their particular pet issue, and the shine has come off of Sheryl Sandberg’s star. Facebook’s various other branded platforms, notably Instagram, are also starting to come under fire as people begin to openly question exactly how much influence these “social media influencers” have on them—or should. Congress may or may not get involved here, but either way, what was once pretty much a lock on a market has shown some serious cracks, and I suspect several competitors will start sharpening their knives, including several startups that may or may not already exist. Zuck will need to show some determined leadership and strike off in a bold direction, or the calls will come for his head faster than they did for any of IBM’s CEOs in the 90s. &lt;strong&gt;&lt;em&gt;Result: -1&lt;/em&gt;&lt;/strong&gt; No, Facebook seems bound and determined to just keep on keepin&apos; on, as they say, and it&apos;s likely going to hurt them in a big way. Zuck seems completely bound to the idea that if they just make a few tweaks here and there, they can just keep on being who they are, when in fact, who they are is by very definition a vehicle for bad mojo. Look, in a lot of ways the social media world is following the same arc as early journalism (check out &lt;a href=&quot;https://www.britannica.com/topic/yellow-journalism&quot;&gt;&amp;quot;yellow journalism&amp;quot;&lt;/a&gt; and see if you recognize anything), before some of the core laws and rules and conventions governing it came into being. Although, honestly, given the current political climate, we may be losing those rules and laws and conventions before too long, too.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Google will look to capitalize on Facebook’s struggles... and fail miserably.&lt;/em&gt;&lt;/strong&gt; (0.8; 0.6) This is another two-fer. Right now, deep in the heart of Menlo Park, a Google executive is putting the finishing touches on a presentation to the Alphabet board around building yet another social media network app, complete with numbers about how many GMail users want to see a union of their email and social media profiles, and how that could drive additional AdWords revenue, and…. And the people to whom that presentation is shown will nod sagely, approve the effort, and…. Google will announce the beta of yet another Google social media app that will somehow be different than all the other social media Google-branded apps, because this time, it will be different… somehow…. And yet, it won’t, and it won’t, and somewhere in 2023 Google will kill it because this time, it’s replacement will be different…. &lt;strong&gt;&lt;em&gt;Result: -1&lt;/em&gt;&lt;/strong&gt; Google has, remarkably, stayed just as clear of the social media space as it ever has, which is to say they didn&apos;t throw a new social media product into the fray, and frankly, that surprises the hell out of me.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Microsoft will, too.&lt;/em&gt;&lt;/strong&gt; (0.6) Unfortunately, here in Seattle, a Microsoft exec is putting the finishing touches on almost exactly the same presentation. With any luck, Satya will toss the whole idea out the window before the presentation is even finished, but... &lt;strong&gt;&lt;em&gt;Result: -1&lt;/em&gt;&lt;/strong&gt; And I&apos;ve almost never been happier to be wrong. Satya, you did good on this one. (Of course, Microsoft probably put all that effort into Teams, so maybe this one is a wash?)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Uber is going to struggle even more.&lt;/em&gt;&lt;/strong&gt; (0.8) Uber was once the darling of the Silicon Valley and Wall Street—now, it’s having a hard time getting the time of day from either group. This past year was not kind to them (a net loss of close to US$3 billion, if we leave out one-time investments), and people have figured out that Lyft and other Uber-competitors are just as convenient, but without the soul-selling that using Uber brings to mind. Uber Eats might be a saving grace here, but again, lots of competitors, and those competitors don’t have the “Uber” logo that is increasingly turning from balloon to boat anchor around their branding. &lt;strong&gt;&lt;em&gt;Result: +1&lt;/em&gt;&lt;/strong&gt; Oh, my, yes. They&apos;re not alone, to be sure, in that Lyft and several other ride-sharing firms are expressing equal kinds of difficulties. And the whole wider collection of &amp;quot;unicorn companies&amp;quot; that were basing themselves off the idea that people would want to partake in the entirely ungoverned, uncontrolled, unmonitored, and employee-unfriendly &amp;quot;gig economy&amp;quot; (or &amp;quot;side hustle&amp;quot; if you prefer) are facing some problems. Most of which stem from the fact that these companies aren&apos;t &amp;quot;disrupting&amp;quot; anything, they&apos;re just trying to reinvent an already-existing thing by calling themselves something different and trying to eke out a profit on the narrow margins that they can find by not having to pay government oversight costs. That was, is, and never will be, sustainable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;AWS (and Azure) will only continue to add services.&lt;/em&gt;&lt;/strong&gt; (0.9) There’s no end in sight! AWS already has ten database services, but is there another angle to data storage that needs to be in the cloud? Go create it! Brand it! Sell it! Turn it into a thing that Bezos can show off at re:Invent 2019! There’s no end in sight! &lt;strong&gt;&lt;em&gt;Result: +1&lt;/em&gt;&lt;/strong&gt; Of course they did.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Calls of “enough already!” will begin to echo in the clouds.&lt;/em&gt;&lt;/strong&gt; (0.9) It’s becoming far more than anyone can keep up with. AWS, Azure, Google, all of them have way too many services for anybody to reasonably keep track of, and as a result, we will start to see a new industry of “cloud advisors” begin to form—--speakers, online courses, and the like—--simply geared to guide people through the choices of which of Amazon’s dozen or so data services you might actually need to use. &lt;strong&gt;&lt;em&gt;Result: 0&lt;/em&gt;&lt;/strong&gt; It&apos;s starting to happen, but quietly and in dark corners. Hence, I can&apos;t really cop a point for it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;C# 8.0 will ship in Visual Studio 2019.&lt;/em&gt;&lt;/strong&gt; (0.9) This one’s a gimme, but I’m never one to take a free point or two. &lt;strong&gt;&lt;em&gt;Result: +1&lt;/em&gt;&lt;/strong&gt; April 2, 2019, baby. Or late September, take your pick.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Java12 will ship.&lt;/em&gt;&lt;/strong&gt; (0.9) Oracle has announced that they want to move to a six-month release cadence, so given that Java11 shipped in September of 2018, it would make sense that Java12 will follow in March of 2019. One thing that needs saying, though: it’s not clear what features would actually ship in Java12, particularly since some of the proposed features could take a year or two to ensure that they meet the high quality bar that a language and platform as widely-used as Java requires. (Note that the same thing is true of C# and .NET, but Microsoft hedges their bets some by doing major releases as part of the two-year release cadence of Visual Studio; Oracle lacks that “ship vehicle” channel, since they don’t really own a widely-used IDE—--and no, sorry, NetBeans doesn’t count there.) &lt;strong&gt;&lt;em&gt;Result: +1&lt;/em&gt;&lt;/strong&gt; March 19, 2019, baby. Oracle has been almost nefarious in making their six-month ship cycle for Java, and whether that&apos;s a good thing or a bad thing has yet to be determined. I think the bigger question, though, is whether or not anybody actually &lt;em&gt;cares&lt;/em&gt; about Java&apos;s ship dates anymore. I mean, I used to look at each upcoming ship date with a certain amount of excitement and attention, but now... And more to the point, there&apos;s no &amp;quot;Here&apos;s what&apos;s in Java 12&amp;quot; presentations happening at conferences much anymore, which leads me to wonder if anybody actually cares.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Android ships... Q-something.&lt;/em&gt;&lt;/strong&gt; (0.8) Android definitely seems on a 1-year release cadence, but hell if I can think of a dessert that starts with “Q”. Fossbytes suggests names like “quarabiya” or “quince”, but only one of the names is actually found inside the US (“quesito”, from Puerto Rico), and all of Android’s previous code-names have been US-centric names (with one exception, the “Petit Four” release, 1.1, which was also before they started using the alphabetical order, too). OK, OK, I know, “Eclair” is technically French, but it’s widely-known and -recognized in the US, so it counts. So Android has to come up with a “Q”-based dessert that is widely-known in the US and won’t be impossible to pronounce…. or they just skip it and go to “R”. Either way, I don’t envy the person who has to make that decision. &lt;strong&gt;&lt;em&gt;Result: -1&lt;/em&gt;&lt;/strong&gt; They gave up. THEY GAVE UP. They got to &amp;quot;Q&amp;quot;, and rather than even try to shoehorn something in place, they bailed entirely and just called it &amp;quot;Android 10&amp;quot;. I mean, they should&apos;ve done this from the beginning, so this is wildly overdue, but damn, man, I wanted to see what they would come up with for &amp;quot;Q&amp;quot;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;iOS 13 is skipped, and 14 ships.&lt;/em&gt;&lt;/strong&gt; (0.4) Hey, nobody in the Western world likes the number “13”, and Apple is not one to try to convince them otherwise. Look for Apple to pull another marketing shift and try to call iOS 13 “X3” or something, just to avoid the superstitious’ wrath. &lt;strong&gt;&lt;em&gt;Result: -1&lt;/em&gt;&lt;/strong&gt; 2019 was not a good year for Ted trying to predict marketing moves. Not only did Android move to numbering, but iOS decided to stick with numbering and just ship iOS 13. &lt;em&gt;sigh&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Security is going to quietly become a must-have skill.&lt;/em&gt;&lt;/strong&gt; (0.6) The public is tired of the bleeding. Companies are tired of the scrutiny and managing PR fallout. Developers are tired of the second- guessing and accusations. Everybody is tired of security holes biting them in the ass. Slowly, quietly, companies are going to start demanding their developers be held accountable somehow—either in interviews or in internal code reviews or in any other form they can actually use—to make sure code doesn’t get compromised. It’s become clear that the hackers are only getting more and more organized, including state-level backing, and that “thoughts and prayers” are not effective as a security strategy any more than they are as a gun strategy. &lt;strong&gt;&lt;em&gt;Result: +1&lt;/em&gt;&lt;/strong&gt; Let&apos;s be clear, if your company isn&apos;t starting to take security seriously (particularly in the face of GDPR and its ilk), then you&apos;re really just begging to be hacked and owned and bankrupted. We haven&apos;t quiet yet reached the point where we have &lt;em&gt;answers&lt;/em&gt; to the problems that plague us, though, and that&apos;s where the problem lies---too much expertise is required to secure bespoke applications, and right now the best answers are &amp;quot;outsource your authentication strategy&amp;quot; (to places like Auth0 or Okta), which doesn&apos;t take us very far.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;More security legislation like GDPR will come.&lt;/em&gt;&lt;/strong&gt; (0.7) For the same reason as the previous one, governments will start laying down regulations about data privacy and use, and many of those laws will be contradictory to one another, if not to itself. (Even GDPR has a few edge-case flaws inside of it.) What’s worse, because it will be new legislation, and the penalties will be stiff enough to merit actually doing something about it, lots of companies will find it impossible to understand what to do, obtain help from “experts”, and choose to take the most conservative route that will only make end-users’ lives harder—much like what happened with GDPR. (You think accepting the privacy-policy-to-use-cookies messages are bad now—just wait. This is only getting started.) &lt;strong&gt;&lt;em&gt;Result: +1&lt;/em&gt;&lt;/strong&gt; Hello, California. Should&apos;ve known you&apos;d be the first. Chances are good you won&apos;t be the last, since now this forces anybody doing business anywhere in the US to have to bring themselves up to California&apos;s standards... or refuse to do business in the largest domestic economy in the country. Expect a few more states to foloow suit, and then it&apos;ll just be waiting for the rest of the bowling pins to come down. Except for Mississippi---that place is just too bass-ackwards to care. (Seriously, &lt;a href=&quot;https://www.clarionledger.com/story/news/2020/01/16/man-sentenced-12-years-cell-phone-ms-jail-didnt-confiscate/4488906002/&quot;&gt;twelve years for a cellphone&lt;/a&gt;? That is some fucked-up shit right there, and I don&apos;t mind swearing that strongly about it.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Developers start finding their voice on ethics.&lt;/em&gt;&lt;/strong&gt; (0.7) It started with Microsoft and Google, but it won’t end there—more and more developers are finding that they have a certain amount of power at their fingertips, and that unlike a number of their non-technical colleagues, if they threaten to abandon work on a project, their employers will listen to them. (So long as the demand for developers exceeds the supply, this will continue to hold true.) While there will always be some numbers of developers who will not care what they work on—so long as the checks cash—a similar percentage of developers are growing more and more aware that what they do could be used for less-than-innocent purposes… and will start to become an active voice. Look for a few more attempts (successful or otherwise) at coordinated walkouts by developers and other IT staff over easily-identifiable egregiously-unethical uses of some technology or other. &lt;strong&gt;&lt;em&gt;Result: +1&lt;/em&gt;&lt;/strong&gt; Oh, my, yes. It&apos;s happening. Google, Microsoft, other companies are finding that their developers have a voice and are growing more willing to use it. Of course, this also means that companies are starting to find ways to try and shut that voice down, which is setting up for some very interesting employer/labor fights to come.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Developers are going to start a backlash against coding-school graduates.&lt;/em&gt;&lt;/strong&gt; (0.5) This is one I hope I’m wrong about… but I’m guessing I won’t be. Here’s the thinking: More and more, “coding” is being seen as the next-great-way-to-get-out-of-poverty by millions of people who have little to no idea what “coding” means. They are, however, putting thousands of dollars onto credit cards and loans in an effort to learn “coding”, so that they, too, can get at this untold paradise of billions of dollars that we technology-types have been enjoying for the past two decades. But, as any average economist will tell you, the equilibrium point depends on the intersection of supply and demand—and so long as the demand for software was high, and supply of those who could deliver it relatively low, then the price (the equilibrium point) would stay high. Floods of new developers threatens to increase the supply—shifting the supply curve to the right—and bring down the equilibrium (price) point. Salaries will fall. Developers’ power relative to the rest of the company will fall with it. And developers are analytical enough to know this, see through how the rest of that story ends, and look to take steps to solidify their “hold” that they’ve enjoyed for so long. (For the record, I believe this has already been happening for several years now—why else would we as an industry be so concerned with discerning between the true “craftsmen” and the casual practitioner of code?) Look for more and more tech-minded folks to start openly resisting the idea of hiring and mentoring junior developers as they start to figure out (or guess) that their position and high income will be threatened if they don’t. &lt;strong&gt;&lt;em&gt;Result: +1&lt;/em&gt;&lt;/strong&gt; Ironically, though, the backlash is coming not from the people who would &lt;em&gt;hire&lt;/em&gt; coding-school graduates, but other coding-school graduates and/or their allies, who are rallying against &lt;a href=&quot;https://www.theintelligencer.net/news/top-headlines/2019/05/lawsuit-filed-against-nonprofit-mined-mines-in-w-va/&quot;&gt;predatory practices&lt;/a&gt; on the part of said coding schools. Some of them (like the linked story) were clearly never going to fulfill on their promises, but other schools that are genuinely trying to be a force for good will likely get tarred with the same brush.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2020 Predictions&lt;/h2&gt;
&lt;p&gt;2020 is the start of a new decade, and that usually means predictors and prophets and tech pundits and other&lt;br /&gt;
folks who think they know a bunch of stuff try to convince you that this is the start of something entirely&lt;br /&gt;
new. (It&apos;s those kinds of folks who predicted flying cars and hoverboards, by the way.)&lt;/p&gt;
&lt;p&gt;Before we get too deep into this, though, I saw an interesting Twitter meme that went something like this: In&lt;br /&gt;
the movie &amp;quot;Back to the Future&amp;quot;, Marty McFly journeys into the past by 30 years, from 1985 to 1955. If Marty were&lt;br /&gt;
to make that journey today, he&apos;d journey back to... 1990.&lt;/p&gt;
&lt;p&gt;Shall we talk about what this wondrous new year is going to bring?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Everybody is going to go ga-ga over 5G, and it won&apos;t make a whit of difference.&lt;/em&gt;&lt;/strong&gt; (0.6) Apparently, we have to go learn the Eight Fallacies of Distributed Computing all over again, again. On top of which, 5G is rumored to play havoc with &lt;a href=&quot;https://www.aip.org/fyi/2019/noaa-warns-5g-spectrum-interference-presents-major-threat-weather-forecasts&quot;&gt;weather prediction&lt;/a&gt;, so don&apos;t expect this one to go through with the ease of the 3G or 4G upgrades. I suspect that this is going to face some major backlash, probably in 2021 or 2022, particularly if it gets deployed widely in 2020.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Quantum computing will be the next major hype machine.&lt;/em&gt;&lt;/strong&gt; (0.6) From the &amp;quot;our blockchain cannot possibly be defeated by any crypto-cracking tool known to man,&amp;quot; we whiplash over to, &amp;quot;our quantum computing platform can crack any modern cryptography in seconds&amp;quot; without missing a beat. Quantum will be the Huge New Thing, and everybody will want to take a crack at the quintillions or whatever of CPU cycles that quantum computing represents... and like most of these kinds of hype waves, really, quantum computing will be useful in a small set of niche verticals, and useless to everybody else.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Data privacy is going to start to separate from the larger &amp;quot;security&amp;quot; set of issues.&lt;/em&gt;&lt;/strong&gt; (0.5) Companies are having to take &amp;quot;security&amp;quot; seriously, but there&apos;s &amp;quot;serious&amp;quot; and then there&apos;s &amp;quot;if we don&apos;t do this we can&apos;t do business anymore&amp;quot; serious. Data privacy will fall into that latter category, given the legal penalties that will face violators of GDPR and the new California laws. THis means that tools and products (likely databases and its related ilk) will start advertising and promoting their &amp;quot;privacy-by-design&amp;quot; kinds of features, as a way of making it &amp;quot;easy&amp;quot; to implement privacy in your enterprise, big or small. But they won&apos;t want to be held liable in the event of a general hack, so they&apos;ll very carefully and clearly outline differences between &amp;quot;privacy&amp;quot; and the larger field of &amp;quot;security&amp;quot;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Kubernetes all the things... to whatever comes next.&lt;/em&gt;&lt;/strong&gt; (0.4) Kubernetes has pretty much locked up the container world, which means that we will now start to see what peple are suggesting we need to do &lt;em&gt;after&lt;/em&gt; Kubernetes, because the stack has to keep growing deeper, or else vendors have to start competing with something in the middle of the stack, which means having to get into a feature war or fight for standardization somehow, neither of which are proven routes to success.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The demand for &amp;quot;full-stack&amp;quot; developer unicorns will reach its peak.&lt;/em&gt;&lt;/strong&gt; (0.7) Anybody who&apos;s watching the job sites and LinkedIn listings can see that everybody wants a developer who knows a major enteprise language (Java, C#, etc), Docker, Kubernetes, SQL and NoSQL skills, JavaScript (preferably knowing Angular, React, or Vue, and possibly all three), HTML, CSS, XML, JSON, one of the major cloud platforms (AWS, Azure, or GCP, certificates from certification authorities in each of those preferred), and sometimes even more beyond that. Folks, that&apos;s not a developer, that&apos;s an entire IT department (thank you, Twitter meme), and at a certain point that bubble is going to burst. But not this year.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;New programming languages are going to start the R&amp;amp;D cycle on languages again.&lt;/em&gt;&lt;/strong&gt; (0.6) They may be &amp;quot;service-oriented&amp;quot;, they may be something else, but languages like &lt;a href=&quot;http://ballerina.io&quot;&gt;Ballerina&lt;/a&gt;, &lt;a href=&quot;https://www.jolie-lang.org/&quot;&gt;Jolie&lt;/a&gt;, and &lt;a href=&quot;https://darklang.com/&quot;&gt;Dark&lt;/a&gt; are basically suggesting that there&apos;s a new level of abstraction to be sought as a linguistic first-class citizen. Frankly, if you&apos;ve been doing any sort of service development (micro- or otherwise), you&apos;ve felt the costs and pain (in terms of complexity and the number of moving parts you have to track) of doing so. Cloud vendors are trying to suggest that &amp;quot;serverless&amp;quot; is the way to go, but in a lot of ways it just trades the complexity off to other ares of the app; a new paradigm is what&apos;s needed, to bring the complexities back down to human-manageable levels.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Automation will take an even stronger seat at the conceptual table.&lt;/em&gt;&lt;/strong&gt; (0.7) &amp;quot;If I can&apos;t find developers to do these things I need to get done,&amp;quot; fumes the CEO, &amp;quot;I&apos;ll go out and find some tools that can do all that stuff without requiring them!&amp;quot; Automation, particularly that enabled by low-code or no-code tools, will begin to skyrocket as a desirable target, even though this will mean that non-developers will start doing developer-ish things, and before long, will run afoul of the same basic problems that always strike when non-developers start doing developer-ish things. (Truthfully, this is related to the programming languages issue; companies need better &amp;quot;technical agility&amp;quot; out of their IT departments, and right now, nothing is providing that. They will look for anything, no matter how outlandish or outrageous, to provide that, and in 2020 that pressure will really make itself felt.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lastly, one more:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Ted will write another one of these in a year.&lt;/em&gt;&lt;/strong&gt; (0.99; it should be a 1.0, but there’s always the chance that the whole country will undergo some kind of apocalypse, thanks to the orange buffoon who sits in the White House, that would keep me from writing this.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Despite my best intentions, I totally abandoned the blog in 2019. With the shutdown of MSDN Magazine, and my choice to withdraw from the back-page editorials in CODE Magazine, with no drawdown in my interest in writing and no clear outlet by which to publish it, the blog should see some better love in the year to come. But... I still won&apos;t give that a 1.0 probability.&lt;/p&gt;
&lt;p&gt;I will, however, state that this last point---the one about businesses needing to find better technical agility in their IT and technology departments---is one that I&apos;m very, very interested in, and I now work &lt;a href=&quot;https://www.quickenloans.com/&quot;&gt;someplace&lt;/a&gt; that has the resources and interest in solving some of those problems, at least internally (but hopefully in an FOSS manner). We could always use a few more talented engineers, if you&apos;re of a mind...&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2019 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2019/2019-tech-predictions.html</link>
      <pubDate>Tue, 1 Jan 2019 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2019/2019-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;It&apos;s that time of year again... well, actually, a few days late, but I&apos;ve been busy, I swear. As has become my tradition now for nigh-on a decade, I will first go back over last years’ predictions, to see how well I called it (and keep me honest), then wax prophetic on what I think the new year has to offer us.&lt;/p&gt;
&lt;p&gt;As per previous years, I’m giving myself either a +1 or a -1 based on a purely subjective and highly-biased evaluational criteria as to whether it actually happened (or in some cases at least started to happen before 31 Dec 2018 ended). And, to be fair, while I only posted the 2018 predictions a few days ago (I hadn&apos;t realized it, but my CI system for the blog was down, which goes to show you, it helps to verify your CI system every so often), I actually wrote it a year ago, so it&apos;s still legit.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2&gt;In 2018...&lt;/h2&gt;
&lt;p&gt;At the start of 2018, I wrote, &amp;quot;Oh, my, it&apos;s been something of a roller-coaster for all of us, to be sure. ...  [T]he tech industry has seen a huge element of chaos and uncertainty thanks to a whole slew of factors, some related and some not.&amp;quot; And although I didn&apos;t know it at the time, that was going to be well true of 2018, as well, thanks in no small part to the huge privacy and access scandals that have rocked Facebook and other companies to their very core. Let&apos;s go back and see what I predicted, though, and see where I came out in the face of all that...&lt;/p&gt;
&lt;p&gt;In 2018, I wrote...&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;... that &lt;strong&gt;SPECTRE and MELTDOWN are going to ripple through the hardware in a big way.&lt;/strong&gt;&lt;br /&gt;
I&apos;m sorry, spectre-who? Meltdown-what? The two hardware-based &amp;quot;side channel&amp;quot; attacks made a big splash at the time, but after that, there really wasn&apos;t a whole lot of response or concern beyond &amp;quot;Wait, you mean my CPUs aren&apos;t going to go as fast anymore...?&amp;quot; To be fair, though, much of that lack of concern was (I think) rooted in the more fundamental concerns around, &amp;quot;Wait, Facebook sold my data to whom, again?&amp;quot; or the much more bluntly-wielded, &amp;quot;Wait, &lt;a href=&quot;https://www.bloomberg.com/news/features/2018-10-04/the-big-hack-how-china-used-a-tiny-chip-to-infiltrate-america-s-top-companies&quot;&gt;China has slipped what additional chip onto our motherboards&lt;/a&gt;...?&amp;quot; I might have called the idea that there would be a ripple, but I got the reason way wrong. Score: 0. I get no point, but lose no point.&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;Apple will still not ship anything new.&lt;/strong&gt; Let&apos;s look at &lt;a href=&quot;https://thenextweb.com/apple/2018/10/30/everything-apple-hardware-event-october-2018/&quot;&gt;the record&lt;/a&gt;: They revamped the MacBook Air, they revamped the Mac Mini, they revamped the iPad Pro, and they.... yeah, that was it. Score: +1 for me.&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;Tech unicorns are going to feel a lot more pressure.&lt;/strong&gt; The Uber thing definitely started having some level of impact, but to be clear, it was by far more the recorded visual  of &lt;a href=&quot;https://www.youtube.com/watch?v=Lw1xWh-z-nA&quot;&gt;Mark Zuckerberg staring into the headlights of a Congressional inquiry&lt;/a&gt; that really rattled a few peoples&apos; heads, and made a number of folks in the tech sector begin (alas, only &amp;quot;begin&amp;quot;) to realize that some of the stuff they are playing with is actually fire that can burn them, not just fire to drive passions or whatever. Just when GitHub got acquired by Microsoft, Airbnb started feeling heat from various lawsuits, and suddenly, the whole &amp;quot;tech unicorn&amp;quot; thing became less of a mark of success than a brand that companies were not quite so keen to burn onto their own flesh. Uber even began running commercials from their new CEO to try and reassure people that Uber wasn&apos;t made up of immoral monsters... even as they still tried to make profits off the backs of the &amp;quot;side hustle&amp;quot; and the &amp;quot;gig economy&amp;quot;, which are code-words for &amp;quot;let&apos;s not treat people like actual employees&amp;quot;. Score: +1.&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;Voice-controlled interface design is going to go out of control.&lt;/strong&gt; Not yet. I was probably a few years premature with this one, but more importantly, the fascination with the voice-control doesn&apos;t seem to be expanding much---yes, companies and developers are beginning to explore what more we can do with voice, but so far, it doesn&apos;t really seem to be taking root in the populated world beyond shopping and simple home automation. Score: -1.&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;The Javascript SPA Wars will rage on, with new players entering the mix.&lt;/strong&gt; Angular is on the downslope of the Gartner Hype Curve; VueJS is still being lifted to the top; React, meanwhile, is sitting at the top of the Hype Curve Rollercoaster, and oh, my, here comes a new challenger in &lt;a href=&quot;https://mavo.io/&quot;&gt;Mavo&lt;/a&gt;. Some wars just don&apos;t know when to quit. Score: +1.&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;Android will release a new version, and it will be called Pecan.&lt;/strong&gt; Ha! &amp;quot;Pie&amp;quot; shipped in August. Score: +1 (out of a possible 2).&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;Kotlin will become the first-class citizen for Android development.&lt;/strong&gt; Kotlin is now included in the text of the documentation of &amp;quot;Build your first app&amp;quot;, and if Java is still the language used for the majority of the samples, well, Java&apos;s been the front-and-center for Android for the previous 27 releases, so you&apos;ll have to give Google a little time to get everybody to the point where they can forget Java like the passing of a bad migraine. Google is firmly committed to Kotlin as the language of choice for Android, it seems. Score: +1.&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;Swift 5 will come out, and it will break against Swift 4.&lt;/strong&gt; Sooooo close. Swift 5 development has preview snapshots that were out as late as December 27, but it hasn&apos;t shipped as part of Xcode and other packaging channels yet, so I don&apos;t get points. Swift 5 is trying to set a higher bar for source incompatibility with previous versions (yay), but hasn&apos;t ruled it out entirely (sigh). Details &lt;a href=&quot;https://github.com/apple/swift-evolution&quot;&gt;here&lt;/a&gt;. Still, no points for me---Swift 5 isn&apos;t expected to ship until early 2019. Score: -1.&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;Bitcoin will collapse into the obscurity from whence it came.&lt;/strong&gt; It&apos;s been falling &lt;a href=&quot;https://en.wikipedia.org/wiki/History_of_bitcoin#Prices_and_value_history&quot;&gt;pretty much continuously&lt;/a&gt; since the end of 2017, and there&apos;s no signs it&apos;ll rebound. It may not ever reach a $0 valuation, since some fools (like the &lt;a href=&quot;https://www.coindesk.com/ohio-becomes-first-us-state-to-allow-taxes-to-be-paid-in-bitcoin&quot;&gt;state of Ohio&lt;/a&gt;) have put at least some amount of faith into it (albeit probably as a way to attract additional hi-tech interest; that same article reports &amp;quot;In the same month, Ohio lawmakers also pitched their state as a future hub for blockchain, hoping to both attract companies in the space and blockchain talent to the jurisdiction.&amp;quot;), and there will always be those who will always continue to support it, just like some folks still insist that OS/2 is still a real operating system. Score: +1.&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;C# will reach an 8.0 release.&lt;/strong&gt; Nope. C# stopped at 7.3 (in Visual Studio 2017 15.7), and probably won&apos;t ship until Visual Studio 2019 ships, which will probably happen in... yeah, no points for me on this one. Score: 0.&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;Java v.Next is going to confuse the hell out of everyone.&lt;/strong&gt; So much so that Oracle abandoned the proposed versioning scheme and went back to &amp;quot;Java10&amp;quot;, &amp;quot;Java11&amp;quot;, &amp;quot;Java12&amp;quot;, ....  Score: +1.&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;Javascript releases will start to fade into obscurity.&lt;/strong&gt; Quick, which version of ECMAScript (which is, remember, the proper name of the language) are you using in your version of NodeJS or Chrome? ECMAScript 2016? ECMAScript 2017? ECMAScript 2018? ECMAScript 6? ECMAScript 7? Most people, I venture to guess, are running on ECMAScript v.&amp;quot;Who-cares-so-long-as-my-code-runs&amp;quot;. (For the record, the latest adopted standard is ECMAScript 2018, or the 9th edition of ECMA-262, and introduces &amp;quot;support for asynchronous iteration via the AsyncIterator protocol and async generators. ... four new regular expression features: the dotAll flag, named capture groups, Unicode property escapes, and look-behind assertions. ... [and] includes rest parameter and spread operator support for object properties.&amp;quot; In case you were curious.) Score: +1.&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;Tim Cook rumors begin.&lt;/strong&gt; As in, the rumors of his upcoming demise as CEO. And still, yet another year, and no real call for his resignation. I almost think the Apple community wants him to be the next incarnation of Steve Jobs that nothing short of getting out of tech completely and becoming the next Dunder-Mifflin paper producer would actually get them to want him out. Score: -1.&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;Some startup will emerge claiming to fix the &amp;quot;fake news&amp;quot; problem using AI.&lt;/strong&gt; Seriously? It took &lt;a href=&quot;https://www.cbinsights.com/research/startups-combating-fake-news/&quot;&gt;less than a month&lt;/a&gt;. One of them even uses blockchain for maximum buzzwordiness. Score: +1 (I really shouldn&apos;t, since this one was so easy to predict, but....)&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;Salesforce starts making some acquisitions again.&lt;/strong&gt; They picked up five, some of which were technology companies, and one of which (MuleSoft) definitely had some &amp;quot;splash&amp;quot; impact, valued at US$6.5 billion. Called it with a major flourish. Score: +1.&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;Docker hype starts wearing off.&lt;/strong&gt; Well.... not really. Some of the shine is coming off of Docker, but not necessarily with Docker itself. As more and more companies (and cloud providers) are adopting it, we&apos;re all finding some pretty big limitations with it, which is why much of the conversation isn&apos;t about Docker itself, but how we can put groups of Docker images together into a larger unit---as in, in Kubernetes clusters or some of its competitors. Which means the hype around Docker isn&apos;t causing us to abandon or question it, just... work around it. Score: -1.&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;Microsoft will continue to push Amazon in the cloud world at every step.&lt;/strong&gt; Look at the &lt;a href=&quot;https://azure.microsoft.com/en-us/blog/&quot;&gt;Microsoft Azure blog&lt;/a&gt;. Look at the list of features and products offered by Azure. How anyone can keep track of this is anyone&apos;s guess. By some measures, Azure is ahead of AWS; by others, AWS is leading. It&apos;s a tight race, by most peoples&apos; estimation, and there&apos;s no signs of it letting up. Score: +1.&lt;/li&gt;
&lt;li&gt;... that &lt;strong&gt;Amazon will start to get into the developer tools game.&lt;/strong&gt; Last year, I wrote
&lt;blockquote&gt;
&lt;p&gt;Amazon can&apos;t let Microsoft continue to have a real or perceived advantage in terms of the tools and development experience for building in the cloud, so I expect within the next year or two Amazon will announce or acquire a development toolchain specifically for building cloud applications.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In some ways, I was a bit off, because &lt;a href=&quot;https://techcrunch.com/2017/11/30/amazon-launches-aws-cloud9-a-browser-based-ide-for-cloud-developers/&quot;&gt;Amazon announced Cloud9&lt;/a&gt; in the previous year, which I missed, but strangely enough, Amazon seems to be content with leaving it there, which I don&apos;t understand. Definitely missed something here. Score: -1.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;.. that &lt;strong&gt;Quietly, more and more companies will start looking to build &amp;quot;Developer Relations&amp;quot; departments.&lt;/strong&gt; If this is happening, it&apos;s happening too quietly for me to see with any great confidence. I believe it to be happening, based on casual conversations I have with various folks in different parts of the country, and certainly LinkedIn shows close to 600 open positions around &amp;quot;developer relations&amp;quot;, but it&apos;s still mostly with technology companies (those that sell to developers and/or the IT side of a company). It was probably folly to expect to see it &amp;quot;explode&amp;quot; within a single year, and I still have faith it will, but for now.... Score: -1.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Eleven &amp;quot;+1&amp;quot;s, to five &amp;quot;-1&amp;quot;s. Not bad, better than my average (which is usually right about a push). Can&apos;t get too upset about those numbers, really. For comparison, last year&apos;s were 15 +1s. 10 -1s, which again confirms that my skills as a psychic are definitely not going to keep me and the family fed.&lt;/p&gt;
&lt;p&gt;But that&apos;s the past, and most people are interested in...&lt;/p&gt;
&lt;h2&gt;In 2019&lt;/h2&gt;
&lt;p&gt;As an awkwardly-named decade (&amp;quot;the teens&amp;quot;? &amp;quot;the 2010s&amp;quot;?) draws to a close, a number of interesting things are going to start shifting the industry around in some very interesting---and potentially scary---ways.&lt;/p&gt;
&lt;p&gt;Here&apos;s what I mean:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Blockchain might actually start being understood.&lt;/strong&gt; (Probability 0.4) Blockchain itself is not going away---if anything, companies seem to be putting more resources into it, not less---which suggests that enough people are seeing something of value buried deep (&lt;em&gt;very&lt;/em&gt; deep) inside the hype. It may not be clear yet what it is, but that message is going to start trickling and filtering out and a few people might actually start to clue in on how best to use it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;AI and ML will begin to start separating... a little.&lt;/strong&gt; (0.6) There&apos;s lots of things that fall under the umbrella term &amp;quot;artificial intelligence&amp;quot;, and machine learning is only one of them. As we get more experience with ML in practical usage, we&apos;ll start to see that the different branches of AI are useful for different things, and we&apos;ll begin to use those terms a little more carefully. Look for &amp;quot;natural language&amp;quot; and &amp;quot;expert systems&amp;quot; and &amp;quot;machine learning&amp;quot; to start getting used independently, rather than the catch-all &amp;quot;AI&amp;quot;. What&apos;s more....&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;AI will start to move out of the startup and into the enterprise.&lt;/strong&gt; (0.7) Lots of people have kicked their AI startup off, and lots of big companies have started AI initiatives within their own companies, and they&apos;re all finding... this stuff is hard. And what&apos;s worse, the kind of skills required to do &amp;quot;AI&amp;quot; (whichever flavor you care to name) are rare, and those departments simply will resist scaling to the rest of the company. What usually happens after that first wave of interest, however, is that a small group of companies start to figure out how to apply AI to more mundane and practical purposes inside the big companies&apos; IT space, and that&apos;s where the serious money lives. Sure, there&apos;s going to be some flashy bits about robots and image recognition and stuff, but the real money is waiting to be made in machine learning being used to discover patterns in the data that up until this point mostly got discovered by accident. Look for a few companies to start selling AI not as a raw technology, but as part of a toolchain that a company can buy to do &amp;quot;something else&amp;quot;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Amazon gets hauled in front of the DOJ.&lt;/strong&gt; (0.8) If it doesn&apos;t happen this year, it&apos;ll happen in 2020. Jeff Bezos has been doing a great job of staying out of the limelight when it comes to the ugly whispers of &amp;quot;monopoly&amp;quot;, but good Lord, folks, Amazon is clearly making no secret of the fact that it wants to take over the entire retail experience---and when you couple that with the fact that Amazon is now opening brick-and-mortar stores, there&apos;s not a huge leap from &amp;quot;Company using its monopoly power to drive competitors out of business by taking losses on sales&amp;quot; to &amp;quot;Amazon founder Jeff Bezos was in Washington DC today to sit in front of a Congressional inquiry...&amp;quot;. Particularly when Amazon just bought Whole Foods, a non-technology company if ever there was one.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Facebook undergoes some kind of radical transformation.&lt;/strong&gt; (0.8) Zuckerberg is on the ropes, whether he realizes it or not. People are quitting the app in droves. Milennials aren&apos;t taking it up. Every single day, various political groups scream about Facebook&apos;s censorship of their particular pet issue, and the shine has come off of Sheryl Sandberg&apos;s star. Facebook&apos;s various other branded platforms, notably Instagram, are also starting to come under fire as people begin to openly question exactly how much influence these &amp;quot;social media influencers&amp;quot; have on them---or should. Congress may or may not get involved here, but either way, what was once pretty much a lock on a market has shown some serious cracks, and I suspect several competitors will start sharpening their knives, including several startups that may or may not already exist. Zuck will need to show some determined leadership and strike off in a bold direction, or the calls will come for his head faster than they did for any of IBM&apos;s CEOs in the 90s.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Google will look to capitalize on Facebook&apos;s struggles... and fail miserably.&lt;/strong&gt; (0.8; 0.6) This is another two-fer. Right now, deep in the heart of Menlo Park, a Google executive is putting the finishing touches on a presentation to the Alphabet board around building yet another social media network app, complete with numbers about how many GMail users want to see a union of their email and social media profiles, and how that could drive additional AdWords revenue, and.... And the people to whom that presentation is shown will nod sagely, approve the effort, and.... Google will announce the beta of yet &lt;em&gt;another&lt;/em&gt; Google social media app that will somehow be different than all the other social media Google-branded apps, because &lt;em&gt;this&lt;/em&gt; time, it will be different... somehow.... And yet, it won&apos;t, and it won&apos;t, and somewhere in 2023 Google will kill it because &lt;em&gt;this&lt;/em&gt; time, it&apos;s replacement will be different....&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Microsoft will, too.&lt;/strong&gt; (0.6) Unfortunately, here in Seattle, a Microsoft exec is putting the finishing touches on almost exactly the same presentation. With any luck, Satya will toss the whole idea out the window before the presentation is even finished, but....&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Uber is going to struggle even more.&lt;/strong&gt; (0.8) Uber was once the darling of the Silicon Valley and Wall Street---now, it&apos;s having a hard time getting the time of day from either group. This past year was not kind to them (a net loss of close to US$3 billion, if we leave out one-time investments), and people have figured out that Lyft and other Uber-competitors are just as convenient, but without the soul-selling that using Uber brings to mind. Uber Eats might be a saving grace here, but again, lots of competitors, and those competitors don&apos;t have the &amp;quot;Uber&amp;quot; logo that is increasingly turning from balloon to boat anchor around their branding.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;AWS (and Azure) will only continue to add services.&lt;/strong&gt; (0.9) There&apos;s no end in sight! AWS already has ten database services, but is there another angle to data storage that needs to be in the cloud? Go create it! Brand it! Sell it! Turn it into a thing that Bezos can show off at re:Invent 2019! There&apos;s no end in sight! In fact....&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Calls of &amp;quot;enough already!&amp;quot; will begin to echo in the clouds.&lt;/strong&gt; (0.9) It&apos;s becoming far more than anyone can keep up with. AWS, Azure, Google, all of them have way too many services for anybody to reasonably keep track of, and as a result, we will start to see a new industry of &amp;quot;cloud advisors&amp;quot; begin to form---speakers, online courses, and the like---simply geared to guide people through the choices of which of Amazon&apos;s dozen or so data services you might actually need to use.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;C# 8.0 will ship in Visual Studio 2019.&lt;/strong&gt; (0.9) This one&apos;s a gimme, but I&apos;m never one to take a free point or two.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Java12 will ship.&lt;/strong&gt; (0.9) Oracle has announced that they want to move to a six-month release cadence, so given that Java11 shipped in September of 2018, it would make sense that Java12 will follow in March of 2019. One thing that needs saying, though: it&apos;s not clear what features would actually ship in Java12, particularly since some of the proposed features could take a year or two to ensure that they meet the high quality bar that a language and platform as widely-used as Java requires. (Note that the same thing is true of C# and .NET, but Microsoft hedges their bets some by doing major releases as part of the two-year release cadence of Visual Studio; Oracle lacks that &amp;quot;ship vehicle&amp;quot; channel, since they don&apos;t really own a widely-used IDE---and no, sorry, NetBeans doesn&apos;t count there.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Android ships... Q-something.&lt;/strong&gt; (0.8) Android definitely seems on a 1-year release cadence, but hell if I can think of a dessert that starts with &amp;quot;Q&amp;quot;. &lt;a href=&quot;https://fossbytes.com/android-q-name-prediction-10-dessert/&quot;&gt;Fossbytes&lt;/a&gt; suggests names like &amp;quot;quarabiya&amp;quot; or &amp;quot;quince&amp;quot;, but only one of the names is actually found inside the US (&amp;quot;quesito&amp;quot;, from Puerto Rico), and all of Android&apos;s previous code-names have been US-centric names (with one exception, the &amp;quot;Petit Four&amp;quot; release, 1.1, which was also before they started using the alphabetical order, too). OK, OK, I know, &amp;quot;Eclair&amp;quot; is technically French, but it&apos;s widely-known and -recognized in the US, so it counts. So Android has to come up with a &amp;quot;Q&amp;quot;-based dessert that is widely-known in the US and won&apos;t be impossible to pronounce.... or they just skip it and go to &amp;quot;R&amp;quot;. Either way, I don&apos;t envy the person who has to make that decision.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;iOS 13 is skipped, and 14 ships.&lt;/strong&gt; (0.4) Hey, nobody in the Western world likes the number &amp;quot;13&amp;quot;, and Apple is not one to try to convince them otherwise. Look for Apple to pull another marketing shift and try to call iOS 13 &amp;quot;X3&amp;quot; or something, just to avoid the superstitious&apos; wrath.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Security is going to quietly become a must-have skill.&lt;/strong&gt; (0.6) The public is tired of the bleeding. Companies are tired of the scrutiny and managing PR fallout. Developers are tired of the second- guessing and accusations. Everybody is tired of security holes biting them in the ass. Slowly, quietly, companies are going to start demanding their developers be held accountable somehow---either in interviews or in internal code reviews or in any other form they can actually use---to make sure code doesn&apos;t get compromised. It&apos;s become clear that the hackers are only getting more and more organized, including state-level backing, and that &amp;quot;thoughts and prayers&amp;quot; are not effective as a security strategy any more than they are as a gun strategy.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;More security legislation like GDPR will come.&lt;/strong&gt; (0.7) For the same reason as the previous one, governments will start laying down regulations about data privacy and use, and many of those laws will be contradictory to one another, if not to itself. (Even GDPR has a few edge-case flaws inside of it.) What&apos;s worse, because it will be new legislation, and the penalties will be stiff enough to merit actually doing something about it, lots of companies will find it impossible to understand what to do, obtain help from &amp;quot;experts&amp;quot;, and choose to take the most conservative route that will only make end-users&apos; lives harder---much like what happened with GDPR. (You think accepting the privacy-policy-to-use-cookies messages are bad now---just wait. This is only getting started.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Developers start finding their voice on ethics.&lt;/strong&gt; (0.7) It started with Microsoft and Google, but it won&apos;t end there---more and more developers are finding that they have a certain amount of power at their fingertips, and that unlike a number of their non-technical colleagues, if they threaten to abandon work on a project, their employers will listen to them. (So long as the demand for developers exceeds the supply, this will continue to hold true.) While there will always be some numbers of developers who will not care what they work on---so long as the checks cash---a similar percentage of developers are growing more and more aware that what they do could be used for less-than-innocent purposes... and will start to become an active voice. Look for a few more attempts (successful or otherwise) at coordinated walkouts by developers and other IT staff over easily-identifiable egregiously-unethical uses of some technology or other.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Developers are going to start a backlash against coding-school graduates.&lt;/strong&gt; (0.5) This is one I hope I&apos;m wrong about... but I&apos;m guessing I won&apos;t be. Here&apos;s the thinking: More and more, &amp;quot;coding&amp;quot; is being seen as the next-great-way-to-get-out-of-poverty by millions of people who have little to no idea what &amp;quot;coding&amp;quot; means. They are, however, putting thousands of dollars onto credit cards and loans in an effort to learn &amp;quot;coding&amp;quot;, so that they, too, can get at this untold paradise of billions of dollars that we technology-types have been enjoying for the past two decades. But, as any average economist will tell you, the equilibrium point depends on the intersection of supply and demand---and so long as the demand for software was high, and supply of those who could deliver it relatively low, then the price (the equilibrium point) would stay high. Floods of new developers threatens to increase the supply---shifting the supply curve to the right---and bring down the equilibrium (price) point. Salaries will fall. Developers&apos; power relative to the rest of the company will fall with it. And developers are analytical enough to know this, see through how the rest of that story ends, and look to take steps to solidify their &amp;quot;hold&amp;quot; that they&apos;ve enjoyed for so long. (For the record, I believe this has already been happening for several years now---why else would we as an industry be so concerned with discerning between the true &amp;quot;craftsmen&amp;quot; and the casual practitioner of code?) Look for more and more tech-minded folks to start openly resisting the idea of hiring and mentoring junior developers as they start to figure out (or guess) that their position and high income will be threatened if they don&apos;t.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lastly, one more:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ted will write another one of these in a year.&lt;/strong&gt; (0.99; it should be a 1.0, but there&apos;s always the chance that the whole country will undergo some kind of apocalypse, thanks to the orange buffoon who sits in the White House, that would keep me from writing this.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I was pretty terrible about blogging in 2018, largely because I was pretty well-occupied with a number of different things in my life. Some of that is getting straightened out now, and frankly I felt an &amp;quot;itch&amp;quot; every so often to write something in the blog---but couldn&apos;t thanks to the aforementioned &amp;quot;things&amp;quot;, mostly due to lack of time---that I think will force itself to the surface more often in 2019. I&apos;ll probably be shuffling some of my various IT properties around a bit, too, so don&apos;t be too surprised if in 2020 this blog is split between my &lt;a href=&quot;http://www.newardassociates.com&quot;&gt;professional site&lt;/a&gt; and a more personal one (which would remain tedneward.com, but with an actual website at that domain name instead of the silly placeholder that&apos;s there now).&lt;/p&gt;
&lt;p&gt;Thanks for reading. Have a happy, prosperous, and adventurous 2019, and feel free to drop me comments or feedback in the comments below.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2018 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2018/2018-tech-predictions.html</link>
      <pubDate>Tue, 2 Jan 2018 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2018/2018-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;It&apos;s that time of year again... well, actually, a few days late, but I&apos;ve been busy, I swear. As has become my tradition now for nigh-on a decade, I will first go back over last years’ predictions, to see how well I called it (and keep me honest), then wax prophetic on what I think the new year has to offer us.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;As per previous years, I’m giving myself either a +1 or a -1 based on a purely subjective and highly-biased evaluational criteria as to whether it actually happened (or in some cases at least started to happen before 31 Dec 2017 ended).&lt;/p&gt;
&lt;h2&gt;In 2017...&lt;/h2&gt;
&lt;p&gt;Oh, my, it&apos;s been something of a roller-coaster for all of us, to be sure. Even if we leave out&lt;br /&gt;
some of the political mess (and Lord has it been a mess!), the tech industry has seen a huge&lt;br /&gt;
element of chaos and uncertainty thanks to a whole slew of factors, some related and some not.&lt;br /&gt;
Untangling all of this is going to take some time, but no better time than now, so...&lt;/p&gt;
&lt;p&gt;First, let&apos;s look at the personal predictions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ted will celebrate his one-year anniversary at Smartsheet in September.&lt;/strong&gt; +1! I&apos;ve now been at&lt;br /&gt;
Smartsheet for a year-plus, and have no real desire to change my immediate surroundings anytime&lt;br /&gt;
soon. The company is growing like mad, we just &lt;a href=&quot;http://converse.ai&quot;&gt;made our first acquisition&lt;/a&gt;,&lt;br /&gt;
and my team is starting to go out into the world on its own. Management has its downsides, but&lt;br /&gt;
it certainly has its upsides, too.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ted will do less speaking this year.&lt;/strong&gt; +1! And this will probably continue into the new year&lt;br /&gt;
as well. As it stands, I&apos;m probably looking at no more than a dozen conferences, total, through&lt;br /&gt;
all of 2018.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ted will not be renewed as a Microsoft MVP.&lt;/strong&gt; +1! Despite some repeated promises from the MVP&lt;br /&gt;
team that they would examine my candidacy once they had done some refactoring in the process, no&lt;br /&gt;
new invitation to rejoin that program has come from Microsoft, and I strongly suspect that they&lt;br /&gt;
will continue to ignore me. Fortunately, as I said last year, most of what I care about in the&lt;br /&gt;
Microsoft world is already open-source, and the rest of it... meh.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ted will look to engage with other tech companies beyond Microsoft.&lt;/strong&gt; +1! Google and I have&lt;br /&gt;
circled around each other for a year or so now, yet something keeps coming up that keeps me from&lt;br /&gt;
being a GDE. Fortunately, like Microsoft, most (if not all) of the Google stuff I care about is&lt;br /&gt;
also open-source, so the lack of the &amp;quot;GDE&amp;quot; credential at the end of my email signature isn&apos;t&lt;br /&gt;
really all that big a deal. On a related note, though, I did become an IBM Champion of Cloud...&lt;br /&gt;
for a year.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ted will continue to teach at UW.&lt;/strong&gt; +1! Still going. Still loving it. Still looking to continue&lt;br /&gt;
doing it through all of 2018 and beyond.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ted will look to publish a few mobile apps.&lt;/strong&gt; -1! Not a single one published. Kinda frustrated&lt;br /&gt;
at myself over that.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ted will continue to write for various tech &apos;zines.&lt;/strong&gt; +1! My column at developerWorks dried up, but&lt;br /&gt;
CODE Magazine and MSDN are still going strong, and honestly, I&apos;m OK with that---things at work have&lt;br /&gt;
gotten really busy as I&apos;ve taken on more &amp;quot;management&amp;quot; tasks and less &amp;quot;technical&amp;quot; ones.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;And finally, Ted will try to blog more.&lt;/strong&gt; -1! It&apos;s been a busy year, and frankly I&apos;ve been&lt;br /&gt;
just too caught up in things to really make a good go of it. Looking to change that, boss, looking&lt;br /&gt;
to change that.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OK, despite the +6 and -2, I&apos;m going to reset the score back to zero, because, really, personal&lt;br /&gt;
predictions are just not all that interesting to anybody but me.&lt;/p&gt;
&lt;p&gt;Let&apos;s get to the meat of it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The calendar year 2017 is going to be a wild one for the tech industry...&lt;/strong&gt; +1! Oh, my Lord,&lt;br /&gt;
was that a +1. The year opened with Trump&apos;s &amp;quot;Technology Summit&amp;quot; with Elon Musk and Jeff Bezos,&lt;br /&gt;
and within a month it was disbanded and completely discredited. I said &amp;quot;The man &lt;em&gt;thrives&lt;/em&gt; on&lt;br /&gt;
being unpredictable,&amp;quot; which was obviously spot-on, &amp;quot;and the techn industry... thrives on&lt;br /&gt;
predictability.&amp;quot; The tech sector almost immediately distanced itself from Trump, and many&lt;br /&gt;
companies have since found themselves in a position where they are actually sitting across&lt;br /&gt;
the courtroom against his Administration.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Congress will call for an investigation into the &apos;hacking&apos; of the 2016 US election.&lt;/strong&gt;&lt;br /&gt;
+1! We&apos;re all getting a little tired of the investigation, actually, but it&apos;s not wrapping up&lt;br /&gt;
any time soon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security becomes a HUGE deal for the industry.&lt;/strong&gt; +1! If you weren&apos;t convinced of the accuracy&lt;br /&gt;
of this, allow me introduce you to my friends SPECTRE and MELTDOWN (which, I admit, is cheating&lt;br /&gt;
a little since the news about them broke just after the new year). Coupled with all the other&lt;br /&gt;
hacks---which, admittedly, we&apos;re starting to get a little jaded about---it&apos;s pretty clear that&lt;br /&gt;
life as a security consultant is a pretty prime gig. Just ask Troy Hunt.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple continues to plummet.&lt;/strong&gt; +1! MacBookPro&apos;s continue to hover at 16GB max RAM. The iPhone X&lt;br /&gt;
has a chunk carved out of it and Apple claims that was deliberate. Facial recognition, water&lt;br /&gt;
resistance, and a few other &amp;quot;amazing!&amp;quot; features were all already invented and mass-produced by&lt;br /&gt;
Samsung.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple doesn&apos;t introduce any new products this year.&lt;/strong&gt; +1! iPhone X doesn&apos;t count, since it&lt;br /&gt;
didn&apos;t change the form factor. No new iPad. No new MacBooks. Nothing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PC manufacturers double their efforts to build a MacBook Pro.&lt;/strong&gt; +1! The MBP PC clones are&lt;br /&gt;
becoming too legion to count---as a matter of fact, I just ordered a ThinkPad P51, 64GB RAM,&lt;br /&gt;
2TB SSD, and it&apos;s not much thicker than my MBP 15&amp;quot; from 2012. You are falling way behind,&lt;br /&gt;
Apple, and don&apos;t think we all don&apos;t notice it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple rumors about Tim Cook&apos;s departure begin.&lt;/strong&gt; -1. If those rumors have circled, it&apos;s not&lt;br /&gt;
been anywhere I could hear them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Oracle will continue to just write Java.&lt;/strong&gt; +1! &amp;quot;... releases of Java just keep coming through&lt;br /&gt;
both commercial and OSS channels.&amp;quot; In fact, Oracle has committed to a new and ridiculously short&lt;br /&gt;
release cycle for JDK releases. There is zero evidence that they have any secret plans to screw&lt;br /&gt;
the entire Java-based world over by charging licenses, so let&apos;s put that one to bed already,&lt;br /&gt;
shall we?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Oracle Cloud emerges onto the cloud scene in a big splash.&lt;/strong&gt; -1. Oracle has a cloud? This&lt;br /&gt;
was a pretty big whiff---Oracle&apos;s cloud play, if anything, appears to be falling further and&lt;br /&gt;
further behind the &amp;quot;Big Three&amp;quot; (Amazon, Google, Microsoft).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Salesforce makes a major database acquisition.&lt;/strong&gt; -1. While Salesforce did eventually acquire&lt;br /&gt;
Attic Labs, that didn&apos;t happen until&lt;br /&gt;
&lt;a href=&quot;https://techcrunch.com/2018/01/08/salesforce-acquires-attic-labs-the-startup-behind-decentralized-database-noms/&quot;&gt;two weeks ago&lt;/a&gt;,&lt;br /&gt;
and I would hardly call the &lt;a href=&quot;https://github.com/attic-labs/noms&quot;&gt;Noms database&lt;/a&gt; a major database&lt;br /&gt;
to boot. Good luck to them, but this is hardly a +1 for me.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Salesforce releases a new programming language.&lt;/strong&gt; -1. Salesforce was actually pretty quiet&lt;br /&gt;
through the calendar year 2017, probably trying to figure out what to do with all the companies&lt;br /&gt;
they purchased the year before.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LinkedIn Learning starts to make a serious dent in online developer training.&lt;/strong&gt; +1! LIL is&lt;br /&gt;
growing their training curriculum, and while they&apos;re not to the point of buying up ridiculous&lt;br /&gt;
amounts of ad space online, they&apos;re definitely starting to grow their online presence.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Swift doesn&apos;t go to 4.&lt;/strong&gt; -1. &amp;quot;Swift 3 held breaking changes from Swift 2, and the folks at&lt;br /&gt;
Apple are not stupid. Swift 4 will be far, far down the horizon for a few years yet, given that&lt;br /&gt;
each major version number bump has heralded incompatibilities.&amp;quot; Well, yeah, called that one way&lt;br /&gt;
wrong, and what&apos;s worse, Swift 4 had breaking changes from Swift 3. Swift is a cool language,&lt;br /&gt;
but if they keep breaking it like this, it&apos;s going to acquire a very nasty reputation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microsoft ships C# 7.&lt;/strong&gt; +1! As a matter of fact, C# 7.1 and C# 7.2 came out as well. Microsoft&lt;br /&gt;
seems determined to keep committed to a much shorter release cycle, so it&apos;s reasonable to assume&lt;br /&gt;
that C# will continue to ship once or twice each year.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No new Android version.&lt;/strong&gt; -1. I got the code-name right (Oreo), but it shipped to the public&lt;br /&gt;
in August.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Twitter will continue its slide into irrelevancy.&lt;/strong&gt; -1. Whether for good or for ill, Trump&lt;br /&gt;
is giving the world a view into his mindset every day through his Twitter account, and Twitter&lt;br /&gt;
continues to love giving him that stage. I don&apos;t know if it&apos;s good for the Twitter brand to be&lt;br /&gt;
so closely aligned with Trump like this, but they&apos;re clearly not &amp;quot;irrelevant&amp;quot;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The &amp;quot;Internet of Things&amp;quot; continues to draw hype, and continues to fail to deliver.&lt;/strong&gt; +1!&lt;br /&gt;
Sorry, but IoT continues to hover at this stage of &amp;quot;Honest, it&apos;s going to be huge!&amp;quot; as it has&lt;br /&gt;
for the last three years. There&apos;s still no compelling &amp;quot;gotta-have-it&amp;quot; IoT toy or tool or app&lt;br /&gt;
yet, and not for lack of trying.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tech &amp;quot;unicorns&amp;quot; will start to watch the bubble pop.&lt;/strong&gt; -1. Uber took some serious hits in 2017,&lt;br /&gt;
but overall the unicorn bubble hasn&apos;t started to pop yet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Voice-controlled fart apps will emerge.&lt;/strong&gt; -1. I&apos;m thinking of writing one, actually.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Facebook will find that preventing &apos;fake-news sites&apos; is a lot easier said than done.&lt;/strong&gt; +1!&lt;br /&gt;
As a matter of fact, Facebook&apos;s latest suggestion (as of today) is to put a &amp;quot;credibility rating&amp;quot;&lt;br /&gt;
on stories from various websites that&apos;s based on a crowdsourced opinion poll---in other words,&lt;br /&gt;
we&apos;re going to let the masses decide what&apos;s believable, because the masses are a good judge of&lt;br /&gt;
what&apos;s believable. (In related news, the Flat Earth Society has seen their membership numbers rise&lt;br /&gt;
in recent years.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A driverless car will kill somebody.&lt;/strong&gt; +1! -1! I wrote &amp;quot;The circumstances may not be the software&apos;s&lt;br /&gt;
fault---and in fact it&apos;s likely that it won&apos;t be, when the final analysis comes back---but the&lt;br /&gt;
headlines will scream, and the widespread fear of a human &amp;quot;not being in the loop&amp;quot;&lt;br /&gt;
will set driverless cars back by years.&amp;quot; Well, &lt;a href=&quot;https://www.theguardian.com/technology/2016/jun/30/tesla-autopilot-death-self-driving-car-elon-musk&quot;&gt;it actually happened in 2016&lt;/a&gt;.&lt;br /&gt;
What&apos;s more, in 2017, &lt;a href=&quot;https://www.nytimes.com/2017/01/19/business/tesla-model-s-autopilot-fatal-crash.html&quot;&gt;the software &lt;em&gt;was&lt;/em&gt; cleared of guilt&lt;/a&gt; in the crash.&lt;br /&gt;
Despite the &lt;a href=&quot;https://www.wired.com/story/tesla-ntsb-autopilot-crash-death/&quot;&gt;NTSB saying Tesla had some fault&lt;/a&gt;&lt;br /&gt;
later in September, the public at large basically yawned and said, &amp;quot;So?&amp;quot; So I don&apos;t get to claim a&lt;br /&gt;
point for that one.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The topic of ethics and programming will begin to become fashionable.&lt;/strong&gt; -1. The programming&lt;br /&gt;
industry has started having some of these conversations among itself, but that&apos;s hardly the kind of&lt;br /&gt;
scope I was imagining.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;The cloud&amp;quot; continues to grow, even as consumers wonder what the hell it is.&lt;/strong&gt; +1! Public comprehension&lt;br /&gt;
of &amp;quot;the cloud&amp;quot; still remains pretty low---but what&apos;s worse, what they do comprehend is actually pretty&lt;br /&gt;
wrong.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;Blockchain&amp;quot; remains the most opaque &apos;thing&apos; of the year.&lt;/strong&gt; +1! Hello Holy Hype Machine, Batman!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Artificial intelligence will continue to remain a &apos;future&apos; thing.&lt;/strong&gt; +1! Alexa is an amazing thing&lt;br /&gt;
(we have several Echo Dots in the house, mostly to use as an intercom system and alarm clocks), but&lt;br /&gt;
it&apos;s not really doing anything but a natural language parser so far. Now, I&apos;ll admit, I&apos;m a little&lt;br /&gt;
behind the times in terms of wiring up my house, but I&apos;m also at far less risk of having my house&lt;br /&gt;
held hostage to a Russian hacker at the same time. AI is much more than just a voice interface,&lt;br /&gt;
but right now that seems to be the extent of it to the rest of the world.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Total score: 15 +1s. 10 -1s. Like most years, a mixed bag. I sincerely hope my future as a manager&lt;br /&gt;
is bright, because clearly I will not make for a good psychic.&lt;/p&gt;
&lt;h2&gt;2018 Tech predictions&lt;/h2&gt;
&lt;p&gt;The computing world in 2018 is going to see some interesting changes, I think. Here&apos;s what I mean:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SPECTRE and MELTDOWN are going to ripple through the hardware in a big way.&lt;/strong&gt; (0.8 probability)&lt;br /&gt;
These attacks go after the speculative execution nature of modern CPUs, and frankly if the chips&lt;br /&gt;
can&apos;t be fixed to correct for the flaw (and there appears to be some debate about that), then this&lt;br /&gt;
means that an entire branch of hardware optimizations are going to go the way of the DoDo bird.&lt;br /&gt;
That is not going to be easy for us as an industry---accustomed as we are to &amp;quot;everything doubles&lt;br /&gt;
every eighteen months&amp;quot;---to get used to.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple will still not ship anything new.&lt;/strong&gt; (0.6) Apple desperately needs a reputation recovery&lt;br /&gt;
after the whole battery fiasco, but they aren&apos;t ready to ship anything with major &amp;quot;pop&amp;quot; yet. The&lt;br /&gt;
new MBPs won&apos;t be ready to go this year, I&apos;m guessing, particularly since Apple will want to see&lt;br /&gt;
how the SPECTRE/MELTDOWN thing plays out, and it takes a fairly long lead time to make any sort&lt;br /&gt;
of hardware changes before they roll out.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tech unicorns are going to feel a lot more pressure.&lt;/strong&gt; (0.7) After Uber&apos;s mishaps at the C-level&lt;br /&gt;
thanks to their toxic CEO and their questionable business practices, a lot of investors are going&lt;br /&gt;
to start taking a much harder look at what&apos;s going on inside the companies they&apos;ve invested in.&lt;br /&gt;
Expect to see more than a few &amp;quot;unicorns&amp;quot; having their &amp;quot;bro&amp;quot; CEOs replaced by actual adults who&lt;br /&gt;
have actual business models.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Voice-controlled interface design is going to go out of control.&lt;/strong&gt; (0.8) Like it or not, the voice&lt;br /&gt;
thing is here to stay, and the &amp;quot;or not&amp;quot; part of that statement comes when &lt;em&gt;everything&lt;/em&gt; is voice-controlled.&lt;br /&gt;
Why is this an issue? Think about this---when working with an application on your desktop or a&lt;br /&gt;
tablet or phone, the application that currently has focus---the one in front of you, selected,&lt;br /&gt;
responding to your mouse or touch---is the only one that gets access to the input that you provide,&lt;br /&gt;
whatever that may be. But voice applications, they can&apos;t tell when they have focus---as a matter&lt;br /&gt;
of fact, the whole point of them (as evidenced by the commercials) is that you can be doing something&lt;br /&gt;
entirely unrelated, and just toss off an &amp;quot;Alexa, drop in on Master Bedroom...&amp;quot; and suddenly you can&lt;br /&gt;
be doing something on the Internet or talking with somebody else a whole house away. So what happens&lt;br /&gt;
when you have two or three devices all listening simultaneously, and what happens if you refer to&lt;br /&gt;
them by name during casual conversation? More than once, my family and I have been talking about our&lt;br /&gt;
Echo devices, and suddenly Alexa pipes up with, &amp;quot;I didn&apos;t know you felt that way&amp;quot; or &amp;quot;I can&apos;t find&lt;br /&gt;
camel sushi on the Internet.&amp;quot; (I have no idea, either.) The proliferation of voice devices is going&lt;br /&gt;
to vastly exceed our ability to regulate between them, and that&apos;s going to create some serious chaos&lt;br /&gt;
in the household and the workplace.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Javascript SPA Wars will rage on, with new players entering the mix.&lt;/strong&gt; (0.7) In the beginning,&lt;br /&gt;
it was AngularJS. Then React. Then Angular. Then React countered with ReactNative. Now VueJS is tossing&lt;br /&gt;
its hat into the ring, and the Javascript developers of the world are still fighting about which is&lt;br /&gt;
the best single-page application framework to use. They will probably be fighting about it long after&lt;br /&gt;
we&apos;re all dead, too, by the way, if the Java Web framework wars are any kind of history by which to&lt;br /&gt;
guide us. Honestly, VueJS shouldn&apos;t even be considered a competitor to these, since it&apos;s not really&lt;br /&gt;
a SPA framework but more of a &amp;quot;page&amp;quot; framework, but does that stop people from lumping them all&lt;br /&gt;
together and demanding a casualty count? Nope.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Android will release a new version, and it will be called Pecan.&lt;/strong&gt; (0.8, 0.4) I&apos;m giving myself&lt;br /&gt;
two probabilities here, one that a new version will come out, and one that it will be called Pecan.&lt;br /&gt;
Android seems to be trying to aim for a yearly cadence, and for the most part they seem to be reaching&lt;br /&gt;
it, but again, whether a new Android release comes out and whether a new Android release is made&lt;br /&gt;
available for your device are two very different (and seemingly unrelated) stories. Oreo will&lt;br /&gt;
probably just be reaching general availability by this time next year, it seems like.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kotlin will become the first-class citizen for Android development.&lt;/strong&gt; (1.0) This is a no-brainer&lt;br /&gt;
to me; between Google&apos;s choice of JetBrains as the backplane for Android DevStudio, and the fact that&lt;br /&gt;
they really want to be rid of the whole Oracle lawsuit baggage as quickly as possible, it seems to&lt;br /&gt;
me that it&apos;s a no-brainer that Google will basically deprecate all of the Java toolchain they can,&lt;br /&gt;
get Kotlin to produce ART bytecode natively out of the compiler, &amp;quot;hide&amp;quot; the existing Java libraries&lt;br /&gt;
behind Kotlin standard libraries, suggest that Kotlin&apos;s Java compatibility provides a &amp;quot;legacy access&amp;quot;&lt;br /&gt;
feature for &amp;quot;legacy&amp;quot; libraries, and essentially move the whole developer ecosystem over to a Kotlin-&lt;br /&gt;
based one for all future Android development. Note that this process will take years (if not a full&lt;br /&gt;
decade) to complete, but 2018 is the year Google starts making that move really hard to ignore.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Swift 5 will come out, and it will break against Swift 4.&lt;/strong&gt; (0.6) It&apos;s the dumbest thing Apple and&lt;br /&gt;
the Swift community could possibly do at this point, but that hasn&apos;t stopped them from doing it three&lt;br /&gt;
times already (from 1 to 2, from 2 to 3, and from 3 to 4), so why buck the historical trend? Sure,&lt;br /&gt;
just break all that code---it&apos;s not like people have legacy code bases in the mobile world, we&apos;re&lt;br /&gt;
all just writing everything new and from scratch anyway, right? (Incidentally, I think this is part&lt;br /&gt;
of why Swift is having such a hard time spinning up a huge component/package ecosystem the way Ruby,&lt;br /&gt;
Node, Java and .NET have all managed to do. Yes, Cocoapods is a thing, but it&apos;s a lot smaller and&lt;br /&gt;
less active in many ways than its peers in the other ecosystems are.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bitcoin will collapse into the obscurity from whence it came.&lt;/strong&gt; (8.4) Bitcoin is a currency that&lt;br /&gt;
is based on nothing more than the faith of the people who buy into it, and that&apos;s an extremely weak&lt;br /&gt;
basis upon which to build a currency. Supporters of bitcoins will say that all currencies are based&lt;br /&gt;
on faith, but that&apos;s not entirely true---faith in a currency is based upon faith in the strength of&lt;br /&gt;
the government that backs that currency. A US dollar is worth anything at all because we trust the&lt;br /&gt;
strength and faith of the US government. This has been true of every currency ever issued by any&lt;br /&gt;
nation (or other non-national organization, such as the Confederate States of America) throughout&lt;br /&gt;
history, and simply wanting it to be different won&apos;t make it so. People put trust and faith into a&lt;br /&gt;
government; they don&apos;t (or simply can&apos;t) put that faith into cryptography, particularly since it&apos;s&lt;br /&gt;
not obvious to them how the whole crypto/bitcoin thing works in the first place. Coupled with the&lt;br /&gt;
increasing costs (in power and heat, both of which are starting to have environmental impact) of&lt;br /&gt;
generating bitcoin and the huge time sink involved in transferring bitcoin from one party to another,&lt;br /&gt;
this whole thing is basically a scam, a sham, and a Ponzi scheme. The sooner it dies the better.&lt;br /&gt;
Now---all of that said, the reason this is a 0.4 probability is that people have (literally) bet&lt;br /&gt;
their life savings on this, and those who have invested that heavily will not want to see it go&lt;br /&gt;
down without a fight, and will be struggling like mad to keep the house of cards upright. Couple&lt;br /&gt;
that with the back that the bitcoin exchange sponsors are making out like bandits, and you have a&lt;br /&gt;
ripe situation for exploitation and outright criminal behavior---which is precisely why governments&lt;br /&gt;
are starting to take notice and take action.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C# will reach an 8.0 release.&lt;/strong&gt; (0.4) It&apos;s possible, but not highly likely; the smaller, more&lt;br /&gt;
incremental releases of C# actually work against this, since they can release (literally) one&lt;br /&gt;
new feature at a time, and thus avoid the need to do a major-version release. If C# doesn&apos;t reach&lt;br /&gt;
8.0, it&apos;ll probably end the year on a 7.3 or 7.4 release, however.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Java10 will ship.&lt;/strong&gt; (0.0) Ha! Fooled you. No, the real prediction is....&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Java v.Next is going to confuse the hell out of everyone.&lt;/strong&gt; (0.9) Oracle has said that there will be no&lt;br /&gt;
more numbered releases of Java, and that they will move to a YY.M versioning scheme of Java. This&lt;br /&gt;
means that in March, Java 18.3 will ship, and in September, 18.9. The goal is the same as&lt;br /&gt;
Microsoft&apos;s---frequent incremental releases---and I think the reaction will be much the same:&lt;br /&gt;
confusion, chaos and frustration from their principal user base as everybody tries to figure out&lt;br /&gt;
what the hell it is they&apos;re running and what the hell it is they need to run in order to use some&lt;br /&gt;
particular tool or library.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Javascript releases will start to fade into obscurity.&lt;/strong&gt; (0.5) Not the language itself, but the&lt;br /&gt;
different release versions of Javascript. Or, rather, ECMAScript, since that&apos;s its proper name.&lt;br /&gt;
Proof: which version of the ECMAScript standard does Node 8.current implement? 2015? 2016? 2017?&lt;br /&gt;
2018? Answer: none of the above---it&apos;s a mix of each. Which then suggests the question, why have&lt;br /&gt;
&amp;quot;bundled&amp;quot; language releases described in documents like the ECMAScript Specification documents at&lt;br /&gt;
all? Before the end of 2018, the general Javascript population&apos;s concern for ECMAScript specs,&lt;br /&gt;
if there ever was any, will be almost entirely gone.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tim Cook rumors begin.&lt;/strong&gt; I still think this is going to happen soon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Some startup will emerge claiming to fix the &amp;quot;fake news&amp;quot; problem using AI.&lt;/strong&gt; (0.7) It will be&lt;br /&gt;
big news, it will make a huge splash, it will get snapped up by Facebook, and it will turn out to&lt;br /&gt;
be entirely worthless in the long run.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Salesforce starts making some acquisitions again.&lt;/strong&gt; (0.7) I suspect that Salesforce will start&lt;br /&gt;
looking around for some larger companies to acquire to bring them into some fields that they currently&lt;br /&gt;
don&apos;t have much play or reputation in. Some will be technology, some might be product/platform&lt;br /&gt;
vendors. But Benioff&apos;s going to do something in 2018, probably starting around April or May.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docker hype starts wearing off.&lt;/strong&gt; (0.6) Look, it&apos;s the natural cycle of technology, and now that&lt;br /&gt;
Docker has made its impact on the world, people will start using it for things that Docker was&lt;br /&gt;
never meant to do, fail miserably and publicly, and claim it&apos;s Docker&apos;s fault. People who&apos;ve ever&lt;br /&gt;
been burned by it will jump onto that train, and Docker will take a fairly large PR hit, the same&lt;br /&gt;
way MongoDB did in 2016 and 2017.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microsoft will continue to push Amazon in the cloud world at every step.&lt;/strong&gt; (0.6) Azure has, despite&lt;br /&gt;
all predictions close to a decade ago when it got started, managed to close the gap with AWS in terms&lt;br /&gt;
of both features, size and profit, and Satya doesn&apos;t show any signs of cooling off on it. Microsoft&lt;br /&gt;
is going to meet AWS feature-for-feature, and since Microsoft has a few things that Amazon itself&lt;br /&gt;
lacks (such as a development toolchain, among other things), Azure is going to start drawing some&lt;br /&gt;
attention away from AWS so long as it doesn&apos;t do something stupid. For that reason....&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Amazon will start to get into the developer tools game.&lt;/strong&gt; (0.4) Amazon can&apos;t let Microsoft continue&lt;br /&gt;
to have a real or perceived advantage in terms of the tools and development experience for building&lt;br /&gt;
in the cloud, so I expect within the next year or two Amazon will announce or acquire a development&lt;br /&gt;
toolchain specifically for building cloud applications. Were I a betting man, I would guess they will&lt;br /&gt;
announce something entirely new and put a ton of marketing and branding behind it, and that it will&lt;br /&gt;
be some kind of combination of object- and functional, with perhaps some security features built in,&lt;br /&gt;
but it will have &amp;quot;cloud&amp;quot; (and therefore &amp;quot;services&amp;quot;) as a key component laced within it. This will be&lt;br /&gt;
Amazon&apos;s &amp;quot;Apple/WWDC announcing Swift&amp;quot; moment, and they will play it as a signal that Amazon is ready&lt;br /&gt;
to go toe-to-toe against Microsoft in developer tools.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quietly, more and more companies will start looking to build &amp;quot;Developer Relations&amp;quot; departments.&lt;/strong&gt; (0.9)&lt;br /&gt;
With the acceptance that HTTP-based APIs are here to stay, more and more companies are going to start&lt;br /&gt;
putting together APIs to access and/or interact with the data they store. If &amp;quot;the new oil is data&amp;quot;,&lt;br /&gt;
as many economic periodicals are now claiming, then the new wells will be APIs, and those wells will&lt;br /&gt;
need to be advertised and explained by people who are familiar with talking to developers, even if&lt;br /&gt;
the company doesn&apos;t sell to the developer crowd. Think Ford, or Netflix, or even Zeek&apos;s Pizza, a&lt;br /&gt;
Seattle-local pizza chain that now has a website that will allow you to order pizzas online. If&lt;br /&gt;
Zeek&apos;s had an API, we could actually automate the ordering of pizza for user groups, which would save&lt;br /&gt;
my team at Smartsheet a ton of work---but somebody would have to be able to explain those APIs to the&lt;br /&gt;
developer community, serve as some level of technical support on those APIs, and so on. With the&lt;br /&gt;
rise of &amp;quot;software platforms&amp;quot; behind these APIs will come the need for people who can talk to the&lt;br /&gt;
developers (and their bosses), hence the need for more DevRel departments.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some of this is stuff I plan to blog on more in the coming calendar year. For now, thanks for reading,&lt;br /&gt;
thanks for staying tuned, and talk to you more in 2018.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>On the Google-bro Memo</title>
      <link>http://blogs.newardassociates.com/blog/2017/on-google-bro-memo.html</link>
      <pubDate>Tue, 29 Aug 2017 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2017/on-google-bro-memo.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;tl;dr&lt;/em&gt; By now, everybody has heard of the memo that was passed around by the Google-bro, claiming that Google should reduce its efforts at explicit diversity hiring and how his message was unwelcome within Google&apos;s halls; my reaction is that he had a small point, but it was drowned in the inanity of his larger, and far more incorrect, message.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;First, let&apos;s set a few facts out into the world:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I read the memo. Front to back, top to bottom.&lt;/li&gt;
&lt;li&gt;I spent a significant amount of my college years analyzing papers like these.&lt;/li&gt;
&lt;li&gt;My politics tend to stem from left of center principles, although I have for years believed that the nation is best served by a healthy balance between right and left. (For example, I mourn the loss of a conservative party in the US whose principal concern is reducing government spending.)&lt;/li&gt;
&lt;li&gt;I do not now work for Google, nor have I ever.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Having established that, let&apos;s begin.&lt;/p&gt;
&lt;h3&gt;Summary of the memo&lt;/h3&gt;
&lt;p&gt;Effectively, my read on the memo was simple: Google-bro sought (despite all the caveats and disclaimers) to effectively posit the argument that women are inferior to men as Google employees, and that therefore the efforts Google puts in to hire them are efforts that could be better used elsewhere. (Or, put another way, the gender gap in tech is explainable not by systemic bias in the industry, but by other factors that Google fails to recognize, and that programs that seek to reduce that gap are wasteful and potentially creating greater problems.) He also states that this argument is not welcome inside of Google because of the monocultural echo chamber that Google has built that makes people of right-of-center beliefs feel unwelcome, unaccepted, and &amp;quot;shamed&amp;quot; for their beliefs.&lt;/p&gt;
&lt;h3&gt;Reaction from the outside&lt;/h3&gt;
&lt;p&gt;Reactions of course spanned a gamut of emotion. Much of it centered around the notions of free speech and reverse discrimination, or in some cases reacting to Google&apos;s reaction to terminate the Google-bro&apos;s employment.&lt;/p&gt;
&lt;p&gt;Many were outraged at the argument about women being inferior in technology, but for the most part, as is common in this industry around the critical points, everybody was basically arguing past each other: &amp;quot;Misogyny!&amp;quot; &amp;quot;Free speech!&amp;quot; &amp;quot;Misogyny!&amp;quot; &amp;quot;Free speech!&amp;quot; &lt;em&gt;ad infinitum&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Some chose to try to co-mingle the two points, including the essay written by one well-known industry talking head who chose to frame his discussion in terms of an elevator or some such. Alas, that well-known industry pundit&apos;s piece entitled &amp;quot;Thought Police&amp;quot; did nothing to really shed any light on the subject, and his follow-up piece lamenting the inability to discuss things rationally similarly failed to offer up anything resembling a discussion. Or rational thought. He then later offered up a piece about his experience working with women in technology which, as is common for white dudes who want to continue to believe that there&apos;s no real gender issue in the technical world, because he hadn&apos;t really run across it. He cites his horrible mistake at a keynote that actually offended a ton of people (calling it &amp;quot;stumbling upon an &lt;em&gt;issue&lt;/em&gt;&amp;quot;, italics included), but never really apologizes for actually having, you know, offended anybody. (His take is that &amp;quot;I thought about the complaints and issued appropriate apologies if I thought they had a reasonable point.&amp;quot; Because only the rational and reasonable are due an apology when a mistake is made.)&lt;/p&gt;
&lt;p&gt;(In the same post, he goes on to talk about &amp;quot;character assassination&amp;quot; conducted against him, which I personally find amusing in a post entitled &amp;quot;Women in Tech&amp;quot;. Yes, Uncle Bob, I&apos;m referring to you; no, I&apos;m not seeking to assassinate your character; yes, I&apos;m calling you out for having made multiple mistakes on this issue; and no, I&apos;m not expecting that you will come to hear anything I say here as a reasonable or rational discussion. I have tremendous respect for your professional skill, but my respect for your personal morals and ethics has taken a huge hit, nor am I in any way under the illusion that your stance on this issue will be affected an iota by my analysis, commentary or opinion. What you choose to do from here is, as always, entirely up to you.)&lt;/p&gt;
&lt;p&gt;Unfortunately, numerous people have made similar mistakes, conflating the two issues, until it got all well out of hand and impossible to discuss in any way, shape or form even remotely resembling fair, calm, or open-minded exchange. I chose to wait for a while before throwing my own comments out into the world. I don&apos;t expect that this will do much to provide additional clarity, but the more I was chewing it over in my head, the more I wanted to get all these thoughts out.&lt;/p&gt;
&lt;h2&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;I don&apos;t mean to suggest that these views represent anybody&apos;s viewpoint but my own.&lt;/p&gt;
&lt;p&gt;In point of fact, my company recently posted &lt;a href=&quot;http://developers.smartsheet.com/node/7741&quot;&gt;a statement&lt;/a&gt; on their position on the whole thing, which I thought was neatly summarized by this single sentence:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In short, our position is this: If we didn’t think each and every one of our employees had smart things to say, they wouldn’t be here. We will fight to ensure that every employee’s voice is heard, so long as it does no harm to anyone else.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can stop right here if you want to---that&apos;s basically the &lt;em&gt;tl;dr&lt;/em&gt; version of my own viewpoints on the matter. What follows is my dissection of what I thought was a ridiculously poorly-written position paper.&lt;/p&gt;
&lt;h2&gt;My take&lt;/h2&gt;
&lt;p&gt;As I said above, I noted two basic points to the memo, but those points comprise some pretty wide territory, so I will seek to address them in manageable pieces.&lt;/p&gt;
&lt;h3&gt;Biodeterminism&lt;/h3&gt;
&lt;p&gt;Google-bro&apos;s main argument, that women are somehow not as well-suited for positions at Google as men are, is an argument that reappears every decade or two, and its more widely known as &amp;quot;biodeterminism&amp;quot;, that is, that your biology has a deterministic effect on your success at a particular &amp;quot;thing&amp;quot;. It was widely used, for example, as an argument in the years leading up to the Civil War against the Negro race being able to survive in a modern world.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Among our neighbors of Central and Southern America, we see the Caucasian mingled with the Indian and the African. They have the forms of free government, because they have copied them. To its benefits they have not attained, because that standard of civilization is above their race. &lt;a href=&quot;https://en.wikiquote.org/wiki/Jefferson_Davis&quot;&gt;Jefferson Davis, Speech, 1858&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We recognize the fact of the inferiority stamped upon that race of men [African-American] by the Creator, and from the cradle to the grave, our Government, as a civil institution, marks that inferiority. &lt;a href=&quot;https://en.wikiquote.org/wiki/Jefferson_Davis&quot;&gt;Reply in the Senate to William H. Seward (29 February 1860), Senate Chamber, U.S. Capitol. As quoted in The Papers of Jefferson Davis, Volume 6, pp. 277–84. Transcribed from the Congressional Globe, 36th Congress, 1st Session, pp. 916–18.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Biodeterminism (also known as &lt;a href=&quot;https://en.wikipedia.org/wiki/Scientific_racism&quot;&gt;&amp;quot;scientific racism&amp;quot;&lt;/a&gt; has been used in all sorts of arguments, including those which have suggested that black atheletes are naturally more athletic than their white counterparts, or that Asians are intrinsically better studiers, and so on. In fact, it goes back centuries, including but not limited to the development of the IQ test, as well as the study of &amp;quot;craniometry&amp;quot;, or that the shape of your skull is a highly determining factor in your intelligence.&lt;/p&gt;
&lt;p&gt;In 1981, Stephen Jay Gould wrote &lt;a href=&quot;https://www.amazon.com/dp/B007Q6XN2S&quot;&gt;the definitive takedown&lt;/a&gt; of biodeterminism as an argument, in response to much of the biodeterministic argument taking place at the time. (He wrote a revised edition in response to the same argument that cropped up a decade or so later. He&apos;s since passed away, or I suspect he&apos;d be hard at work on a third edition.) A paleontologist by training, Gould effectively sought to demonstrate that much of the evidence being submitted as supportive of a theory of biological determination of intelligence was in effect bad science and confirmation bias of the researchers&apos; pre-determined opinion. (His work was criticized in turn for succumbing to bad science, but much of that was done by those who sought to push the biodeterministic argument forward---his science has since been cleared, though his prose is argued to be a bit &amp;quot;overgeneralized&amp;quot; and &amp;quot;broad&amp;quot; in places, which is a fair critique.)&lt;/p&gt;
&lt;p&gt;More to the point, Google-bro&apos;s work in the memo was shoddy and largely unsubstantiated. For example, he listed a number of ways men and women differ biologically, such as &amp;quot;The underlying traits are highly heritable&amp;quot;, a wonderfully vague statement that fails to list the traits of which he speaks, how they are heritable, which traits aren&apos;t heritable, and by what scientific basis he makes the claim. (We won&apos;t even begin to dissect the point &amp;quot;[The biological differences are] exactly what we would predict from an evolutionary psychology perspective.&amp;quot;)&lt;/p&gt;
&lt;p&gt;His attempts at making use of gender stereotypes as assumed psychological behavior of all (or at least a stastically significant majority) men and women involved in technology is cherry-picked at best. For example, he cites the Wikipedia article &lt;a href=&quot;https://en.wikipedia.org/wiki/Sex_differences_in_psychology&quot;&gt;&amp;quot;Sex differences in psychology&amp;quot;&lt;/a&gt; for his &amp;quot;differences in personality traits&amp;quot;, and yet fails to note the very first line of that page, which reads:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Sex differences in psychology or gender differences are differences in the mental functions and behaviors of the sexes, and are due to a complex interplay of biological, developmental, and cultural factors. Differences have been found in a variety of fields such as mental health, cognitive abilities, personality, and tendency towards aggression. Such variation may be both innate or learned and is often very difficult to distinguish. Modern research attempts to distinguish between such differences, and to analyze any ethical concerns raised. Since behavior is a result of interactions between nature and nurture researchers are interested in investigating how biology and environment interact to produce such differences,[1][2][3] although this is often not possible.[4]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In particular, let&apos;s take note of the sentence &amp;quot;Such variation may be both innate or learned and is often very difficult to distinguish&amp;quot;, which sort of blew right past him when he read the page.&lt;/p&gt;
&lt;p&gt;Also of particular interest is the last sentence of the opening section:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Differences in socialization of males and females may decrease or increase the size of sex differences.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Considering that much of the criticism leveled at the industry from women in the field centers around the social aspects---and the fact that they are routinely subjected to a degree of criticism and discrimination (accidental or otherwise)---including but not limited to the assumption made at very early ages that &amp;quot;boys are better at math and science&amp;quot;, it seems that at the very least, Google-bro&apos;s biodeterminstic argument is on flawed and very, very shaky ground. Lacking any sort of empirical evidence or experiments specific to this industry, it is reasonable to conclude that his argument is fundamentally flawed, particularly considering the overwhelming amount of anecdotal (and some scientific) evidence to suggest that yes, there is in fact a structural bias weighing in against women in technology.&lt;/p&gt;
&lt;p&gt;And frankly, that&apos;s not the point I really want to discuss.&lt;/p&gt;
&lt;h3&gt;Free speech&lt;/h3&gt;
&lt;p&gt;The right of free speech is guaranteed by the Consitution of the United States, such that the government is not permitted to muzzle its citizens with regard to the topics they wish to discuss in public. You may demonstrate, you may assemble, and you may criticize your government and/or its leaders all without fear of reprisal by said government or any of its executive/enforcement bodies.&lt;/p&gt;
&lt;p&gt;That said, however, a private company is not a government. Google has every right to terminate the employment of any of its employees &amp;quot;for cause&amp;quot; so long as that cause is not explicitly protected by law. You may not terminate somebody because of the color of their skin, the plumbing of their genitalia, the invisible entity they choose to worship, or the number of years they&apos;ve spent on the planet; these are all protected by law.&lt;/p&gt;
&lt;p&gt;The right to assemble, the right to speak your political mind, or the right to be ridiculously stupid are not protected rights within a private organization. (Neither is the length of hair, by the way, nor the kind of shoes you choose to wear.) If an employee walks into the company and states, &amp;quot;I believe that Adolf Hitler was a great man&amp;quot; in a very loud voice, that company has every right to terminate that person&apos;s employment every bit as much as if the same individual were to walk in and start proclaiming his allegiance to Stalin. Or to start chanting phrases from the Necronomicon.&lt;/p&gt;
&lt;p&gt;The cause here is not based on the words coming out of their mouth, but the impact those words are having on the people around them---frankly, walking into your place of employment and spending the day trying to convert everybody over to your form of religion is equally grounds for termination, &lt;em&gt;because you are impeding their work product&lt;/em&gt; by making them uncomfortable. It has nothing to do with the content of your words, but everything to do with the impact it is having on the people around you. Naturally, the more extreme the viewpoint, the more uncomfortable people will become, particularly if you come in wearing clothing and accessories that support that viewpoint, if only because they&apos;re thrust into a situation where they aren&apos;t sure how to react. Even if that viewpoint is &amp;quot;The US Army is an amazing place to be&amp;quot;, if you&apos;re decked out in fatigues and carrying a mock rifle.&lt;/p&gt;
&lt;p&gt;(True story: I contracted for a firm where one of the project managers was a recently-retired US Army vet. He was methodical, disciplined, and very effective as a project manager. However, over a span of four months, he grew increasingly irritable, came to work in his fatigues, and openly discussed killing techniques. Several complaints were filed, and the company finally took action when he came to work openly wearing his survival knife on his belt, since bringing a weapon onto company grounds was a clear violation of the company handbook. Prior to that, however, the company had already started to assemble the necessary documentation to demonstrate that his actions were creating a hostile workplace environment, so barring any major shift in his personality back to a more workplace-friendly manner, his termination was essentially assured. In retrospect, it was pretty clear he was suffering from some sort of PTSD-ish affliction, but any suggestions that he might want to look into some form of counseling or therapy were basically met with, &amp;quot;Are you saying I&apos;m unable to do my job? Are you calling me incompetent?&amp;quot; and a very threatening look. Most people stopped trying to help him after that, unfortunately. More to the point, however, even had he not brought the knife, his manner, his dress and his choice of topics made many people very concerned about coming in to work---he would today be easily labled as a &amp;quot;disgruntled employee risk&amp;quot;---and the company had every right, if not outright requirement, to terminate his employment. Their hesitation was driven by the fact that HR needed to make sure they had the necessary documentation in case of lawsuit.)&lt;/p&gt;
&lt;h3&gt;Employer resources&lt;/h3&gt;
&lt;p&gt;Google has been criticized by both sides: from the left, for not firing Google-bro right away, and from the right, for firing him at all. &amp;quot;Unsafe!&amp;quot; screams the left, and &amp;quot;Thought police!&amp;quot; screams the right. Google-bro filed a wrongful termination lawsuit immediately after his firing, which will make interesting fodder for the legal pages once it finally reaches a judge, if ever---it&apos;s actually in Google&apos;s best interest to make the case quietly disappear, most likely by trading a non-defamation clause and gag order in exchange for a cash payout.&lt;/p&gt;
&lt;p&gt;Again, regardless of the content, the bigger question here is, did the individual make use of company resources---his Google email account, his Google-issued equipment, the Google-supplied network or the Google-paid time---to engage in any of this? If so, he is clearly subject to the terms and conditions of his employment agreement, which usually state that such resources may not be used for personal purposes. Writing said memo, particularly one that was not submitted through any sort of HR channel or to his supervisors anywhere along the hierarchy, pretty much qualifies as personal purposes, every bit as much as using those resources to write a work of fiction would.&lt;/p&gt;
&lt;p&gt;If Google-bro made use of company resources to write and/or distribute his memo, he&apos;s basically in violation of the company&apos;s terms of service, and that&apos;s pretty much all she wrote there. If he wrote the memo on his personal Google Docs account (not his work one), on his own time, on his own laptop, and used his personal GMail account to send it to others at Google on their personal accounts (not their work accounts), then he can claim that he never used Google-corporate resources, and that this was every bit a &amp;quot;personal&amp;quot; exercise. Chances of this being the case? Pretty close to nil, from what little evidence I can see.&lt;/p&gt;
&lt;p&gt;If Google-bro can prove that this memo was, in fact, something he was expected and/or asked to do as part of his assigned duties, this becomes a very different scenario. Even then, however, we run into the next point.&lt;/p&gt;
&lt;h3&gt;Employer damage&lt;/h3&gt;
&lt;p&gt;If an employee does damage to the company in some tangible form, such as engaging in activites that harm the company&apos;s reputation (which I would argue would be the case here), then the employer absolutely has cause to terminate. Nowhere in the employee handbook at most programming positions does it say that stealing an entire Office Depot&apos;s worth of stationery supplies is grounds for termination, nor does it say that standing outside the company waving a sign that says &amp;quot;This company is run by a neo-Nazi&amp;quot; is grounds for termination. In fact, there&apos;s a lot of things that a company doesn&apos;t explicit say are grounds for termination, because anything that can be demonstrated to cause harm can be used as sufficient grounds.&lt;/p&gt;
&lt;p&gt;Consider the sample corporate e-mail and Internet use policy &lt;a href=&quot;https://www.shrm.org/resourcesandtools/tools-and-samples/policies/pages/cms_006400.aspx&quot;&gt;here&lt;/a&gt;; it states that&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;All technology provided by [Company Name], including computer systems, communications networks, company-related work records and other information stored electronically, is the property of the company and not the employee. In general, use of the company’s technology systems and electronic communications should be job-related and not for personal convenience.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&apos;s entirely likely that if you work in this industry, you signed something similar at your place of business, and if you&apos;re using your company laptop to write code for a side project, you&apos;re exposing that side project to a potential IP-ownership claim from your company to that side project. Most companies choose to look the other way on most personal- or personal-ish use, largely because it&apos;s hard to police and because they want to allow employees the freedom to use those resources in exchange for employees&apos; willingness to work a little extra beyond the standard 40 hours, but make no mistake---companies can, and will, assert that clause when it&apos;s apparent that what&apos;s being done harms them.&lt;/p&gt;
&lt;p&gt;Such as this case.&lt;/p&gt;
&lt;h3&gt;Free speech (redux)&lt;/h3&gt;
&lt;p&gt;But the issue Google-bro raises about free speech does highlight something that every company needs to be aware of: psychological safety. Google, as is also true of many other Silicon Valley companies, is quite left-leaning in their internal political views. For those of us who are of similar minds, that&apos;s comforting and feels natural. However, national statistics don&apos;t lie; only about half of us actually feel that way.&lt;/p&gt;
&lt;p&gt;Just as a left-leaning individual will feel a little out of place in a company that leans right, a right-leaning individual will feel similarly misunderstood in a company that leans left. And it should be obvious that there&apos;s limits even in the case where one leans in the same direction as the company---if executives at Google started advocating the violent overthrow of capitalist governments in order to usher in a glorious new age of the proletariat, a significant number of Google employees would feel really uncomfortable.&lt;/p&gt;
&lt;p&gt;This is perhaps the only place where Google needs to consider its actions terminating the Google-bro a little more carefully. Did they, by their action, lead those who &amp;quot;lean right&amp;quot; to feel more uncomfortable and unwelcome at work? If so, they&apos;ve bought themselves a much deeper and more problematic issue than just what Google-bro&apos;s misguided essay brought to their doorstep.&lt;/p&gt;
&lt;p&gt;His point that &amp;quot;People generally have good intentions, but we all have biases which are invisible to us&amp;quot; is a reasonable one, actually, and one confirmed by numerous psychological experiments over the past several decades. He goes on to say&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;At Google, we talk so much about unconscious bias as it applies to race and gender, but we rarely discuss our moral biases.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Again, I do not work at Google so I cannot comment on the truth of this statement as it applies at Google, but it is a fair point to suggest that companies often do not openly discuss the &amp;quot;moral biases&amp;quot; (although that term is pretty ambiguous and never defined within the scope of his memo) amongst the employees. That seems a fair statement to make.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Political orientation is actually a result of deep moral preferences and thus biases.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is where things start to go off the rails---political orientation is most often a combination of a large number of factors, and to suggest that they stem entirely (or even mostly) from &amp;quot;deep moral preferences&amp;quot; is fallacious. (Evidence: How many of the Christian Crusade voted for Donald Trump, a man who is divorced three times, each time to the woman he was cheating on his previous wife with? If we use that---or any of a number of other political examples---as the means by which to examine the statement, either the Christian Crusade clearly does not care about sexual fidelity in its elected leaders despite their protests to the contrary during the Clinton Administration, or the statement simply does not hold.)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Considering that the overwhelming majority of the social sciences,&lt;br /&gt;
media, and Google lean left, we should critically examine these prejudices.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And this is where things really fall apart.&lt;/p&gt;
&lt;p&gt;Much of the social sciences, while it does demonstrate strong political leanings, does not overly lean left. (Let&apos;s also leave alone the idea that the &amp;quot;social sciences&amp;quot; is another wonderfully vague and ambiguous noun that never gets defined.) Because much social science research is conducted on college campuses, it is easy to assume that anyone teaching a sociology class is immediately a leftist, but in fact, if we extend the definition of &amp;quot;the social sciences&amp;quot; to include the practice of social science, such as sales, marketing or human resources, it&apos;s pretty clear to see that there is no overt leaning anywhere. If, however, we are to assume that he means only the social science research, then it should also be an apples-to-apples comparison with media research and Google Research, which is obviously a touch nonsensical.&lt;/p&gt;
&lt;p&gt;(Let&apos;s also leave alone the idea that political philosophy---one of those &amp;quot;liberal arts&amp;quot; that I think he implies by the use of the term &amp;quot;social sciences&amp;quot;---is what&apos;s being discussed every day on various websites and Twitter, and just as obviously not leaning in any particular direction.)&lt;/p&gt;
&lt;p&gt;Neither does the media lean strongly in one direction---in fact, it&apos;s long been known among those who&apos;ve studied the political bias in newspapers over the last century that many/most reporters tend to lean left, while many/most editors tend to lean right. This was widely considered positive, as it leant a degree of balance to the newspapers&apos; reporting. Recent developments (over the last decade) in &amp;quot;fake news&amp;quot; and clearly-defined political bias (FOX News, MSNBC) have clearly upset that particular apple cart, but for the most part, traditionally high-ethic journalistic channels (New York Times, Washington Post, etc) have sought to maintain that balance, their Op-Ed sections notwithstanding.&lt;/p&gt;
&lt;p&gt;If we broaden the term &amp;quot;media&amp;quot; to include &amp;quot;anybody who can stand up a website&amp;quot;, which obviously could potentially include sites like Breitbart and Stormfront, then it should be patently obvious that the political leaning of &amp;quot;the media&amp;quot; is actually not leaning in any one particular direction at all.&lt;/p&gt;
&lt;h3&gt;Falsification Doctrine&lt;/h3&gt;
&lt;p&gt;One of the best ways in which one can test one&apos;s own hypothesis is to conduct what Karl Popper called &lt;a href=&quot;https://en.wikipedia.org/wiki/Falsificationism&quot;&gt;&amp;quot;falsificationism&amp;quot;&lt;/a&gt;, whereby one actively seeks to disprove one&apos;s assertion. To Popper, this was the critical distinction between science and pseudoscience:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Popper stresses the problem of demarcation—--distinguishing the scientific from the unscientific—--and makes falsifiability the demarcation criterion, such that what is unfalsifiable is classified as unscientific, and the practice of declaring an unfalsifiable theory to be scientifically true is pseudoscience. &lt;a href=&quot;https://en.wikipedia.org/wiki/Falsifiability&quot;&gt;Falsifiability&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For example, upon observing a white swan, an amateur at logic may suggest that &amp;quot;That swan is white&amp;quot;. That is a statement of fact, what Popper called a &amp;quot;singular existential statement&amp;quot;, since it makes a statement about the universe that can be verified by examining the evidence suggested. Upon observing a second and third and fourth swan, all of which are white, it may lead the amateur to conclude &amp;quot;All swans are white&amp;quot;. However, this is a statement that now suggests that there is no such thing as a black swan---proven incorrect as soon as a black swan is observed, which can only happen by continued observation and research. As a matter of fact, the only way that statement could ever be verified true is by finding all swans in the universe (including those not on planet Earth), observing their color, and documenting that they are, in fact, white. This is obviously a great deal of work, which most amateurs refuse to conduct. &amp;quot;I&apos;ve observed four swans, that seems like a sufficient set of data points from which to conclude, so clearly my observations are reflective of the universe.&amp;quot; (Most statisticians would probably refute that point quite strongly.)&lt;/p&gt;
&lt;p&gt;Instead of trying to observe all swans, taking the opposite approach---embracing a doctrine of falsification and seeking to observe or discover evidence that would render the statement incorrect---is often far more effective and efficient.&lt;/p&gt;
&lt;h3&gt;Conclusions&lt;/h3&gt;
&lt;p&gt;Google-bro&apos;s memo is a perfect example of an opportunity to refuse to throw the baby out with the bathwater. Discarding the ridiculous elements of his memo, we are still left with the very relevant and important question of, &amp;quot;Do people at Google of right-leaning political viewpoints feel psychologically safe in airing their views out at company events and forums?&amp;quot; Note the deliberate phrasing of my question: if we assume that Google is a left-leaning company (which seems reasonable) and that the left-leaning individuals are thus more comfortable airing their views out, the question should be whether those of the opposite side of the political spectrum feel the same way.&lt;/p&gt;
&lt;p&gt;This question, by the way, is one that should be asked at every company.&lt;/p&gt;
&lt;p&gt;In this particular case, if Google wants to assert that their company culture is &amp;quot;psychologically safe&amp;quot;, then the right question for Google to ask is, &amp;quot;How many people here feel &lt;em&gt;un&lt;/em&gt;safe rendering their views in an open forum?&amp;quot; Note that this doesn&apos;t mean that anybody at Google should feel open about sharing views that are openly hostile or threatening; the company bears a direct responsibility to ensure that all of its employees are physically safe before considering their psychological safety. But they have a responsibility to ensure that the safety extends to both sides of the political spectrum.&lt;/p&gt;
&lt;p&gt;And, bear in mind, that does not mean Google now has an obligation to ensure &amp;quot;equal air time&amp;quot; or &amp;quot;equal support&amp;quot; of all causes. As the executors of the company, Google executives are permitted to choose to pour company resources into whatever charitable or political causes they feel best benefit the company. In many cases, that means that firms will make campaign contributions to the electoral campaigns of candidates from both sides simultaneously, for example.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2017 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2017/2017-tech-predictions.html</link>
      <pubDate>Mon, 2 Jan 2017 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2017/2017-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;It&apos;s that time of the year again, when I make predictions for the upcoming year. As has become my tradition now for nigh-on a decade, I will first go back over last years&apos; predictions, to see how well I called it (and keep me honest), then wax prophetic on what I think the new year has to offer us.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;As per previous years, I&apos;m giving myself either a &lt;strong&gt;+1&lt;/strong&gt; or a &lt;strong&gt;-1&lt;/strong&gt; based on a purely subjective and highly-biased evaluational criteria as to whether it actually happened (or in some cases at least started to happen before 31 Dec 2016 ended).&lt;/p&gt;
&lt;p&gt;Bear with me for a moment, though. This is just too good.&lt;/p&gt;
&lt;h2&gt;In 2015...&lt;/h2&gt;
&lt;p&gt;... &lt;a href=&quot;http://blogs.tedneward.com/post/2015-tech-predictions/&quot;&gt;I said&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Microsoft acquires Xamarin.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Oh, baby. Off by a year. I&apos;m should go back and give myself a &lt;strong&gt;+1&lt;/strong&gt; for this one. It was really surprising that they hadn&apos;t. As a matter of fact, if Microsoft had listened to me and done it in 2015, they&apos;d probably have saved themselves a TON of money compared to what they actually paid for Xamarin in 2016. But they made the acquisition, Xamarin is now part of the Microsoft family, and (finally!) .NET developers have access to the Xamarin toolchain and can build native iOS and Android apps without having to shell out additional cash to do so. &apos;Bout time, Microsoft. (I suspect this had everything to do with Satya, to be honest.)&lt;/p&gt;
&lt;p&gt;OK, gloat over.&lt;/p&gt;
&lt;h2&gt;In 2016...&lt;/h2&gt;
&lt;p&gt;... &lt;a href=&quot;http://blogs.tedneward.com/post/2016-tech-predictions/&quot;&gt;I said&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Microsoft will continue to roll out features on Azure, and start closing the gap between it and AWS.&lt;/strong&gt; Calling this one a &lt;strong&gt;+1&lt;/strong&gt;; it doesn&apos;t take much research to see this has definitely been happening in 2016. However, it&apos;s not necessarily a true statement that they&apos;ve been closing the gap; Amazon keeps adding stuff as well, and the feature-parity lists are starting to get ridiculous. Whether these features are actually &lt;em&gt;of use&lt;/em&gt;, however, is an important distinction, and something for the second half of this post.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;(X)-as-a-Service providers will continue to proliferate.&lt;/strong&gt; Oh my, yes, Ted gets another &lt;strong&gt;+1&lt;/strong&gt; for this. When running a gaming convention has an (X)-as-a-Service for it (seriously, &lt;a href=&quot;https://tabletop.events/&quot;&gt;here&lt;/a&gt;) then you know the proliferation is in full swing. PaaS providers are exploding everywhere, and while a few have disappeared (farewell, Parse!), it&apos;s clear that this was the gold rush of 2016.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple will put out two, maybe three new products, and they&apos;ll all be &amp;quot;meh&amp;quot; at best.&lt;/strong&gt; I should&apos;ve broken this into two predictions: one about Apple&apos;s &amp;quot;meh&amp;quot; products, and one about wearables. If I&apos;d done that, I&apos;d have scored two &lt;strong&gt;+1&lt;/strong&gt;&apos;s for it, because not only have wearables not really gone very far (show me somebody wearing a smart watch, and I&apos;ll show you a geek with too much time on their hands and not enough &amp;quot;discrimination&amp;quot; in their discriminatory income), but Apple&apos;s product releases have been... &amp;quot;meh&amp;quot;! I&apos;m looking at you, iPhone 7, and I&apos;m &lt;em&gt;really&lt;/em&gt; looking at you, MacBook Pro. (When Consumer Reports doesn&apos;t give the MBP its top rating, you know the luster has failed.) More on Apple in the second half.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;iOS 10 will be called iOSX.&lt;/strong&gt; Dangit. Such an opportunity wasted. &lt;strong&gt;-1&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Android N will be code-named &amp;quot;Nougat&amp;quot;.&lt;/strong&gt; Why, hello there, Android 7.0 Nougat. So pleased to make your acquaintance. &lt;strong&gt;+1&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Java9 will ship.&lt;/strong&gt; As I noted last year, @olivergierke &lt;a href=&quot;https://twitter.com/olivergierke/status/684642273561329664&quot;&gt;pointed out&lt;/a&gt; that Java9 had already slipped to 2017, so this one was already a &lt;strong&gt;-1&lt;/strong&gt;. Sigh. And I called it a &amp;quot;no duh&amp;quot; event, too---I&apos;m going to let this one cancel out the extra +1 I&apos;d have given myself for the Apple/wearables thing, just to keep the math safe (and my ego relatively sized). &lt;a href=&quot;http://www.infoworld.com/article/3011445/java/java-9-delayed-by-slow-progress-on-modularization.html&quot;&gt;The article he cited&lt;/a&gt; says that Oracle &amp;quot;blamed the delay on complexities in developing modularization&amp;quot;, a la Project Jigsaw.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Facebook will start looking for other things to do.&lt;/strong&gt; Welllllllll, it&apos;d be really tempting to say that Facebook&apos;s now &amp;quot;things to do&amp;quot; was &amp;quot;Be the deciding factor in who gets elected by passively encouraging the widespread dissemination of fake news and outright falsehoods!&amp;quot;, but seriously, who would&apos;ve believed that even if I had predicted it? Which I didn&apos;t. &lt;strong&gt;-1&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google will continue to quietly just sort of lay there.&lt;/strong&gt; A year ago, I wrote, &amp;quot;Google, for all  that they are on the top of everybody&apos;s minds since that&apos;s the search engine most of us use, hasn&apos;t really done much by way of software product invention recently. ... I suspect the same will be true of 2016--they will continue to do lots of innovative things, but it&apos;ll all be &amp;quot;big&amp;quot; and &amp;quot;visionary&amp;quot; stuff, like the Google Car, that won&apos;t have immediate impact or be something we can use in 2016 (or 2017).&amp;quot; And.... yeah. &lt;strong&gt;+1&lt;/strong&gt; More emphasis around the existing products they&apos;ve built, but as a company, they&apos;ve clearly spent most of 2016 on the Alphabet/Google restructure (which accomplished... what, exactly?), and anything new has been either way quiet or way removed from the business.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Oracle will quietly continue to work on Java.&lt;/strong&gt; A year ago, I wrote, &amp;quot;[Oracle is not] going to kill it, but there&apos;s really not a whole lot of need to go around preaching its message, either. So they let the evangelists go, and they&apos;ll just keep on keepin&apos; on.&amp;quot; Score a &lt;strong&gt;+1&lt;/strong&gt; for the long-haired geek in Seattle; they just keep posting new code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C# 7 will be a confused morass.&lt;/strong&gt; If we permit me the freedom to call it &amp;quot;.NET Core&amp;quot; instead of just &amp;quot;C# 7&amp;quot;, then wow do I get a &lt;strong&gt;+1&lt;/strong&gt; on this one. Even if I just constrain my prediction to C# 7/Roslyn, I still score one, but once you throw in the CoreCLR and &amp;quot;dotnetcore&amp;quot; and the different profiles and.... Holy spaghetti web browser history, Batman! The demarcation lines of the different project teams working on this whole thing are starting to become &lt;em&gt;really&lt;/em&gt; clear as the different OSS projects each look really consistent within themselves, but then, when you get to the borders, things just.... fall apart.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Another version of Visual Basic will ship, and nobody will really notice.&lt;/strong&gt; Alas, there was no new version of Visual Basic, since it would be in lockstep with the release of C# 7 (which didn&apos;t ship), but nobody really noticed. Or cared. Still, nothing shipped, so &lt;strong&gt;-1&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple will now learn the &amp;quot;joys&amp;quot; of growing a language in the public as well.&lt;/strong&gt; First there was Swift 2, which was itself source-incompatible with Swift 1, and then during the summer, Apple shipped Swift 3, which was... source-incompatible with Swift 2, owing to some language changes that the community effectively decided was necessary. &lt;strong&gt;+1&lt;/strong&gt;. (And thanks for that, by the way---made teaching iOS this Fall a royal PITA.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ted will continue to layer in a few features into the blog engine.&lt;/strong&gt; You&apos;ve got comments! And I&apos;ll take that &lt;strong&gt;+1&lt;/strong&gt;, thank you very much.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nine up (ten, if we count my Xamarin prediction from 2015), four down. Not bad. But now, we move on to the more interesting part of the post: 2017.&lt;/p&gt;
&lt;h2&gt;2017 Predictions&lt;/h2&gt;
&lt;p&gt;The calendar year 2017 is going to be a wild one for the tech industry, largely owing to the rather large orange elephant in the room---Donald Trump&apos;s election to President of the United States is a huge wildcard whose randomness simply cannot be understated. The man &lt;em&gt;thrives&lt;/em&gt; on being unpredictable, and like most industries, the tech industry (for all that it cherishes &amp;quot;innovation&amp;quot; and &amp;quot;disruption&amp;quot;) thrives on predictability. His collection of &amp;quot;tech titans&amp;quot; at Trump Tower last month yielded absolutely zero positive traction that I can see, and I suspect that the various corporate tech leaders (Nadella, Bezos, Cook, etc) are all looking at him right now the way humans do a rogue elephant---he could be good for them, so long as he doesn&apos;t go wild and start tramping everything in his path out of spite, anger, fear, or any other of a half- dozen emotions. There&apos;s no prediction here, though---just a &amp;quot;wow, this is an X-factor&amp;quot; that in turn makes predictions that much harder.&lt;/p&gt;
&lt;p&gt;But on that note....&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Congress will call for an investigation into the &apos;hacking&apos; of the 2016 US election.&lt;/strong&gt; (0.8 probability) To be honest, I&apos;m not sure if anybody knows exactly what we mean when we say &amp;quot;the Russians &apos;hacked&apos; the US election&amp;quot; in casual conversation. There&apos;s no clear evidence that the voter machines themselves were cracked or tampered with, but it&apos;s fairly easy to see a correlation with the DNC hacks and Wikileaks disclosures and Trump&apos;s corresponding favorability gains in the polls. That said, though, the five-hundred or so US politicians that make up the Congress (and excluding Trump himself and his transition team) are not comfortable with the idea that somebody outside the US engaged in some kind of manipulation of the election, and they are going to want answers. Just yesterday or the day before, though, Trump made the comment that hacking is &amp;quot;extremely hard to prove&amp;quot;, and he&apos;s right about that---without some kind of &amp;quot;smoking gun&amp;quot; found in a Russian government employee&apos;s possession, it&apos;s going to remain a major point of contention in the coming year, and investigation or not, it&apos;s not going to go away regardless of what the investigation finds.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security becomes a HUGE deal for the industry.&lt;/strong&gt; (0.8) The election is just the tip of the iceberg; consumers may have gotten used to (and complacent about) corporate security disclosures, but the idea that the election could be hacked is sending shivers down the collective spines of anyone who does anything online. The downside is that it&apos;s such a complex topic, it&apos;s hard for anyone who&apos;s not a computer security expert to really understand what to do; even among experts, there&apos;s a fair amount of disagreement, even on simple issues like scope (how widespread is it) or actual facts vs hype. Pair that with the paranoia that is inherent in any security professional (if you think computer security types are paranoid, try talking to physical security professionals for a while), and you have an industry that&apos;s ripe for a lot of snake oil and hyperbole. My prediction, then, is that &lt;strong&gt;the industry starts to see the first set of &amp;quot;security snake oil&amp;quot; products&lt;/strong&gt; somewhere within the calendar year 2017. And by that, I mean products that claim to provide security for your interactions online but in fact do nothing of the sort. (Late-night infomercials about downloadable web pages that can &amp;quot;clean your system&amp;quot; of viruses and malware, move over---it&apos;s time for late-night infomercials about downloadable web page that can &amp;quot;secure you against even the most determined attacker&amp;quot;!)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple continues to plummet.&lt;/strong&gt; (0.7) Their products this year were merely slightly-enhanced copies of the previous line of products (iPhone 7 vs iPhone 6) or containing gimmicky &amp;quot;enhancements&amp;quot; while the core of the product remained essentially unchanged from prior generations (MacBook Pro). Sorry, folks, the TouchBar does not qualify as &amp;quot;disruption&amp;quot; or &amp;quot;innovation&amp;quot;; it&apos;s a strip of touch-sensitive glass from an iPad designed to start prepping you for the idea that Apple can remove the keyboard entirely, replace it with a touchpad, and then put a hinge in between two iPad Pros and call it a &amp;quot;MacBookPad Pro&amp;quot; and charge you $10k for it. (And by the way, if you&apos;re thinking about one of the new MacBook Pro machines, make sure you go into an Apple Store and try it out--the keyboard is definitely not the same as its been for years. It feels like they took about half of the keys&apos; &amp;quot;press depth&amp;quot; away, and it totally changes the &amp;quot;touch&amp;quot; on the keyboard. I imagine somebody could get used to it in time, but... ugh.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple doesn&apos;t introduce any new products this year.&lt;/strong&gt; (0.6) And by new, I mean something that&apos;s not an incremental improvement on what they&apos;ve already got. Heck, I&apos;ll even go so far as to say that this means that there&apos;s no new form factors to the existing product line. (Meaning, no new-sized iPad or iPhone or laptop.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PC manufacturers double their efforts to build a MacBook Pro.&lt;/strong&gt; (0.8) The MBP is vulnerable, for the first time in a half-decade, and PC manufacturers are going to look for ways to capitalize on that. Somebody is going to put out a similarly-sized, similarly-weighted non-touch-screen Windows 10 laptop with 32GB of RAM and a 1 or 2 TB SSD, the usual collection of ports, and price it around the same as MacBook Pro ($2k to $4k), and developers will start buying them. (Bonus points to that manufacturer if they offer Linux as an out-of-the-box option.) I know I will....&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple rumors about Tim Cook&apos;s departure begin.&lt;/strong&gt; (0.6) Cook has proven that he&apos;s no Steve Jobs; in fact, the comparisons between his and Steve Ballmer&apos;s reign at Microsoft are proving eerily and  entirely similar. Both basically took companies that were defining the marketplace and shepherded them into a position of trying to manage the cost structures and find better price-points, and in doing so, killed off much of the mojo that drove both firms. Ballmer took close to a decade to be run out of Microsoft (and even then, it took BillG&apos;s intervention behind the scenes, from what I can tell), but I don&apos;t think the Apple Board is going to wait that long---I think by the end of 2017 we&apos;re going to start hearing serious rumors about Cook being offered a golden parachute to give up the center chair and let somebody else in to run the show.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Oracle will continue to just write Java.&lt;/strong&gt; (0.7) Oracle, despite the best efforts of media and journalists everywhere, just refuses to get drawn into &amp;quot;techno-drama&amp;quot;. Java hasn&apos;t been the Trojan Horse into corporate pocketbooks that all the Java-doomsdayers were predicting back when Oracle acquired Sun, and releases of Java just keep coming through both commercial and OSS channels. There&apos;s really no reason at this point to doubt that Oracle is going to do anything but continue down that path. Make no mistake, I&apos;m sure they&apos;re looking for ways to monetize Java in some way so that they can try to earn back the cash they spent to buy Sun, but I don&apos;t think it&apos;s going to be through selling or charging for the JDK or JRE anytime soon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Oracle Cloud emerges onto the cloud scene in a big splash.&lt;/strong&gt; (0.6) IBM now has Bluemix and Watson, and they were really the last of the &amp;quot;big-iron&amp;quot; holdouts around the cloud. (What I mean by that is that all companies have been quietly flirting with cloud, but some push it loud and clear, a la Microsoft or Google, and some were playing it very quietly for a while.) With IBM acquiring Loopback (a NodeJS server-side stack) last year, it&apos;s clear that IBM is going to push JavaScript as their main cloud development play, essentially ceding the Java-cloud development ground to somebody else. Amazon has historically been the place that Java developers have gone to run their Java code in the cloud, but if Oracle can build a compelling offering (particularly with a free tier that AWS currently lacks), this could be a relatively big splash. Between Oracle&apos;s reputation in the database world, if they have a solid &amp;quot;stack&amp;quot; offering that basically makes a Java-based back-end a snap to start up, Oracle could essentially claim the Java-favored cloud play from Amazon. (Yes, Heroku is out there and holds a fair amount of Java and Scala love, but now that they&apos;re owned by Salesforce I suspect the Java-leaning flavor of Heroku to wane a bit.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Salesforce makes a major database acquisition.&lt;/strong&gt; (0.5) Salesforce is growing, and they&apos;re clearly interested in expanding their cloud to be more than just the CRM. With Heroku, they have a Platform that developers can feel comfortable on, but they don&apos;t have a big-name database (relational or otherwise) that complements that play. They currently are sitting on a ton of cash, and &lt;a href=&quot;http://talkincloud.com/saas-software-service/10-salesforce-acquisitions-2016&quot;&gt;last year&apos;s crop of acquisitions&lt;/a&gt; didn&apos;t include a big database storage name. There&apos;s not a ton of players left out there, but I could see them making a strong push to get something like Cassandra or Couchbase. (Yes, they have Data.com, but that doesn&apos;t seem to be making much headway in the developer mindset space.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Salesforce releases a new programming language.&lt;/strong&gt; (0.4) Let&apos;s call the spade a spade: Apex is a Java knock-off, and it shows a lot of warts, particularly since it hasn&apos;t really kept up with what few improvements Java-the-language has made in recent years. The last company to be in this position---a red-hot platform but a language feeling a little creaky at the corners and just plain &amp;quot;old&amp;quot; everyhwere else---was Apple right before they released Swift. Salesforce has the engineering power, they are looking to command more of the developer mindshare, and they have a ton of cash to blow, so.... Whether this happens this year, next year, or 2019, I&apos;m not sure, but if it doesn&apos;t happen this year, the odds go up each year after that.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LinkedIn Learning starts to make a serious dent in online developer training.&lt;/strong&gt; (0.5) Between the fact that LinkedIn Learning (formerly Lynda.com) is growing out its library to a pretty respectable degree, and the fact that Microsoft now owns LinkedIn, it&apos;s pretty reasonable to assume that Microsoft is going to start making this available to its developer community in various ways. This may happen in 2018, though, depending on how swiftly Microsoft moves to incporate LinkedIn assets across the rest of the firm; if they bought LinkedIn solely for the CRM data to go with Dynamics, for example, then this probably won&apos;t happen for a few years.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Swift doesn&apos;t go to 4.&lt;/strong&gt; (0.7) Swift 3 held breaking changes from Swift 2, and the folks at Apple are not stupid. Swift 4 will be far, far down the horizon for a few years yet, given that each major version number bump has heralded incompatibilities. Apple will not want to call anything &amp;quot;Swift 4&amp;quot; and dredge up memories of incompatibilities in their customers&apos; minds for a while. Swift might get a 3.1 in the summer, but that&apos;s as far as it&apos;ll go.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microsoft ships C# 7.&lt;/strong&gt; (0.8) Roslyn needs to ship in 2017 if Microsoft is going to be able to call this open-source process a success. Otherwise it&apos;ll start a lot of people grumbling. (Yes, a new version of Visual Basic will come with it, and it will make basically no news.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No new Android version.&lt;/strong&gt; (0.4) Android-N is still slowly making its way through the networks, and while we&apos;ll probably start hearing rumors of what Android-8 (Oreo?) will include, with a targeted ship date of 2018, probably 1Q or 2Q.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Twitter will continue its slide into irrelevancy.&lt;/strong&gt; (0.5) Let&apos;s face it, Twitter&apos;s days are  numbered. If you&apos;re holding Twitter stock, now&apos;s a good time to sell---when Twitter was left out of Trump&apos;s &amp;quot;tech summit&amp;quot; last month, the stated reason was that it was &amp;quot;too small&amp;quot;. Put that into your brain-pan and circulate for a while---the service that invented microblogging and is one of the core founders of &amp;quot;social media&amp;quot; was &amp;quot;too small&amp;quot; for the PEOTUS&apos; time. Twitter hasn&apos;t really done anything &amp;quot;new&amp;quot; or &amp;quot;interesting&amp;quot;, but simply continued to be the 140-character microblogging platform it&apos;s always been. It&apos;s reaching commodity status, in fact. That&apos;s not a good sign for a company that wants to be more than it is. I suspect Jack Dorsey gets tossed on his can, the company starts looking for a new CEO, and the &amp;quot;new vision&amp;quot; will start to take shape by the end of the year (2017), and then in 2018 we find out that the &amp;quot;new vision&amp;quot; is terrible, takes them out of their &amp;quot;core business&amp;quot;, and the slide accelerates. But nobody buys them this year, not yet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The &amp;quot;Internet of Things&amp;quot; continues to draw hype, and continues to fail to deliver.&lt;/strong&gt; (0.6) It&apos;s been how many years we&apos;ve heard about IoT now, and how it will revolutionize our lives, and all we&apos;ve really seen thus far is the wide variety of Internet-enabled devices being subverted for a widespread DDoS attack. Wearables, &amp;quot;smart refrigerators&amp;quot; and other IP-enabled devices are proliferating, but---to perhaps everybody&apos;s surprise but mine---nobody&apos;s quite sure what to DO  with these things once you have them. Your thermostat is online; terrific. Does it have an API that will let me query meter usage? No, that&apos;s a different thing, and a different API, and a different connection endpoint, and.... Oh, and be careful, somebody could remote-hack your thermostat and &lt;a href=&quot;http://motherboard.vice.com/read/internet-of-things-ransomware-smart-thermostat&quot;&gt;hold your house hostage&lt;/a&gt;. Because that&apos;s worth the risk.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tech &amp;quot;unicorns&amp;quot; will start to watch the bubble pop.&lt;/strong&gt; (0.3) Uber, Lyft, all these companies that are valued at double-digit billions with zero profits, major losses, and no real assets to sell in the event of a bankruptcy.... All of this is going to start to make some investors nervous, particularly when they look around and realize that the tech sector has been carrying the country&apos;s economy through its &amp;quot;recovery&amp;quot; (yes, we&apos;ve been in a recovery for the last half-decade!). All it takes is a few small stones to start the avalanche.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Voice-controlled fart apps will emerge.&lt;/strong&gt; (0.6) Seriously. As Alexa and Siri and these other voice-activated systems start to move into stationary devices in your home, and as the SDKs for these systems start to become more widespread, the first thing developers will do is build some kind of ridiculously silly app (it would be a kindness to call it a game) that will somehow sweep everybody&apos;s sense of humor into the toilet. (Seriously. Imagine it. &amp;quot;Alexa, did you have beans for dinner?&amp;quot; &amp;quot;Yes, I did, and-- BRAAAAAAAAAAP!&amp;quot; It&apos;s exactly the kind of thing that would get people giggling for hours on end, particularly in a weed-induced state. Did I mention I live in Seattle?)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Facebook will find that preventing &apos;fake-news sites&apos; is a lot easier said than done.&lt;/strong&gt; (0.8) As a result, they&apos;ll put some kind of &amp;quot;AI&amp;quot; filter on linked sites, declare a victory, and try to get out of the political game entirely. It&apos;s a lose-lose scenario for them: one man&apos;s &amp;quot;fake news&amp;quot; site is another man&apos;s &amp;quot;revolutionary take&amp;quot; backed by the First Amendment, and Facebook does not want to be anywhere near a court trying to justify their actions against Free Speech. (Old-timers like me will remember Prodigy, &lt;a href=&quot;http://www.techrepublic.com/blog/classics-rock/prodigy-the-pre-internet-online-service-that-didnt-live-up-to-its-name/&quot;&gt;an online service&lt;/a&gt; that started censoring content, which started its slide into doom.) Zuckerberg doesn&apos;t want to be held responsible for swaying important political events one way or another, but neither does he want to be the target of numerous political activist lawsuits (from all directions). As Joshua (the AI in the WOPR, back in the 80s movies that every geek my age openly worshipped) learned, Zuck will discover that sometimes &amp;quot;the only winning move is not to play&amp;quot;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A driverless car will kill somebody.&lt;/strong&gt; (0.5) It&apos;s only a matter of time. The circumstances may not be the software&apos;s fault---and in fact it&apos;s likely that it won&apos;t be, when the final analysis comes back---but the headlines will scream, and the widespread fear of a human &amp;quot;not being in the loop&amp;quot; will set driverless cars back by years. Expert testimony and repeated demonstrations will do nothing to shake the public&apos;s fear that a computer-driven car could &amp;quot;hit a bug and kill me&amp;quot;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The topic of ethics and programming will begin to become fashionable.&lt;/strong&gt; (0.3) Somewhere alongside the driverless car&apos;s first fatality, people will start asking how the car&apos;s programming makes decisions that most humans make in a split-second without even thinking about it. Case in point: the car detects that a motorcycle rider has had a problem and the rider has laid the bike down in the road right in front of the car. (For discussion purposes, there is no room left to brake; the rider is too close.) The car can either swerve to the side to avoid the now-helpless rider, potentially causing a major accident involving multiple people; or the car can simply continue forward, running over (and very likely killing) the motorcycle rider but avoiding the possibility of multiple fatalities from a larger accident. Most humans would swerve---but is that the &amp;quot;right&amp;quot; decision? More to the point, what should the software be programmed to do? Once the public gets wind of these kinds of decisions being made by geeks behind flat-screen LCDs, it&apos;s going to cause a major outcry. (And yes, these kinds of decisions are going to be encoded in the software, somewhere.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;The cloud&amp;quot; continues to grow, even as consumers wonder what the hell it is.&lt;/strong&gt; (0.7) Let&apos;s be clear---as of right now, the cloud is basically a developer thing. My parents really don&apos;t &amp;quot;get&amp;quot; the cloud, largely because there&apos;s really nothing they get from it. Sure, one can argue that GMail is the world&apos;s most popular cloud email service.... but your email is just stored on a server that Google owns, as opposed to a server that your ISP owns. (If that&apos;s your definition of &amp;quot;cloud&amp;quot;, then pretty much all client-server computing is &amp;quot;cloud&amp;quot; in your world.) People are looking at more online services for things like bill payment, true, but those are basically services being offered by vendors with whom these people are already doing business--again, that&apos;s not &amp;quot;cloud&amp;quot;. Cloud offerings have basically found a home in the developer world, but general-purpose cloud, the way that cloud was first being sold, is losing its window of opportunity to get hold of general consumers&apos; minds. (I lose this prediction if my parents are suddenly smitten with a product that stores or computes for them and isn&apos;t a vendor they already have a relationship with.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;Blockchain&amp;quot; remains the most opaque &apos;thing&apos; of the year.&lt;/strong&gt; (0.8)  Everybody will go on and on about its huge technical advantages and obvious benefits, while never actually describing what it is or how it could work to change the world it&apos;s so clearly destined to change. It&apos;s the ultimate hype machine, and it will show no signs of slowing down until maybe the end of the year. By that time, something will emerge out of it (the way blockchain emerged out of bitcoins and cryptocurrency) that will carry forward the legacy of &amp;quot;changing the world&amp;quot; without actually changing anything.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Artificial intelligence will continue to remain a &apos;future&apos; thing.&lt;/strong&gt; (0.8) Part of the reason I say this is because AI is like magic---if you can understand it, it&apos;s not interesting anymore and it&apos;s just an implementation detail. We&apos;ve had rules engines and natural language processing for years. When Amazon started doing &amp;quot;predictive analysis&amp;quot; of what you would like to buy, we pulled &amp;quot;data science&amp;quot; and &amp;quot;behavioral analytics&amp;quot; out of the &amp;quot;AI&amp;quot; world and into its own category. When AI figured out how to make the spoken word make sense, we called it &amp;quot;speech-to-text&amp;quot; and it was a feature on Android already back in the v2 days. (Marry speech-to-text up with a natural language parser, and you have Siri---which, remember, was its own company before Apple acquired them.) No, Alexa is not going to revolutionize the world any more than Siri did---the act of talking to a machine is not particularly new, and it&apos;s only as good as the services that sit behind the parser and can &amp;quot;hook in&amp;quot; to the parsed text. &amp;quot;Cortana, fire up StarCraft 2&amp;quot; is easy to parse and start an application; &amp;quot;Cortana, fire up StarCraft 2, and find me a random Hard co-op match as Artanis&amp;quot; requires not just firing up an application, but also &amp;quot;hooking&amp;quot; inside the application to know how to carry out the rest of the request. That requires an API platform that all applications can hook into, provide, and describe (in natural-text terms) to the voice-control system. That is not going to be easy to define, adopt, or test.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On a personal note, several predictions come to mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ted will celebrate his one-year anniversary at Smartsheet in September.&lt;/strong&gt; I&apos;m optimistic about these guys, and the things we can do together. I&apos;m looking forward to taking them into the developer limelight in a variety of different ways.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ted will do less speaking this year.&lt;/strong&gt; My new role actually encourages me to help develop new talent for my employer to go out and do the actual speaking, so while I&apos;m definitely down for doing a few conferences this year, it&apos;s not going to be more than 12, total, for the calendar year. I enjoy speaking, but I&apos;m looking to be a lot more careful about where I speak now.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ted will not be renewed as a Microsoft MVP.&lt;/strong&gt; Actually, this appears to be fact, not a prediction. MVP renewals for the January cycle went out already, and I didn&apos;t receive one. Fortunately, most of the stuff I care about in the Microsoft world is all open-source (or moving that way) anyway, and while it&apos;s been nice being on the MVP mailing lists, there&apos;s really been nothing there that&apos;s been all that insightful or amazing. (And, fortunately, living in Redmond makes it trivially easy to get together with anybody on a product team if I really want or need to, and I am privileged to call many of the people on those teams &amp;quot;friend&amp;quot;.) It would&apos;ve been 14 years, but as we Stoics say, &amp;quot;All good things, in time, must come to an end.&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ted will look to engage with other tech companies beyond Microsoft.&lt;/strong&gt; Google just started a new MVP-like program, and I&apos;ve been teaching Android and Angular and some Google Cloud Platform stuff for a while, so perhaps they&apos;ll welcome me into their fold.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ted will continue to teach at UW.&lt;/strong&gt; I&apos;ve been guest-lecturing at UW for the past three years now, and I&apos;m loving it. The students are bright, eager, and a helluvalot smarter than I was at that age. They&apos;re an incredible joy to teach.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ted will look to publish a few mobile apps.&lt;/strong&gt; I&apos;ve had a few ideas floating around for a while, but just never really made the time to do it. Even if they never turn a dime in profit, I&apos;m long overdue for having a few apps in the respective mobile stores.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ted will continue to write for various tech &apos;zines.&lt;/strong&gt; I love having the back-page editorial at CODE Magazine, the column in MSDN, and the various series on developerWorks, among others. I fully intend to keep all that going at full speed. (And I&apos;m always looking for new outlets, if anybody has any leads on paid technical content gigs!)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;And finally, Ted will try to blog more.&lt;/strong&gt; The perennial projection. I&apos;ve got much to blog about, including the patterns series, as well as some interesting themes and ideas floating around the ol&apos; brain pan.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Happy Holidays, and thanks for reading!&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Revisiting Rotor</title>
      <link>http://blogs.newardassociates.com/blog/2016/revisiting-rotor.html</link>
      <pubDate>Thu, 13 Oct 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/revisiting-rotor.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; As part of preparing for a workshop next week in Poland, I&apos;ve been diving back into the CLR source code---which takes me back to my old friend, Rotor.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;For those of you who came to the CLR late, back in 2002 Microsoft offered up an open-source version of the CLR called the Shared Source CLI. (&amp;quot;CLI&amp;quot;, for those who don&apos;t know, is the official ECMA Specification describing the virtual machine that .NET uses as its runtime. The &amp;quot;CLR&amp;quot; is the commercial name for Microsoft&apos;s implementation of the Common Language Infrastructure specification.) I can still remember the feeling of shock and awe when I heard that Microsoft was actually going to release the source---albeit with some of the core parts simplified for easier research purposes---to what it considered its flagship technology for the coming decade. Wow.&lt;/p&gt;
&lt;p&gt;And then I got to write a book on it. Double wow.&lt;/p&gt;
&lt;p&gt;And then Microsoft decided to pay me to follow up on the first edition with a second edition, which they would give away for free. Which, by the way, you can get &lt;a href=&quot;../../files/SSCLI2.pdf&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Triple wow.&lt;/p&gt;
&lt;p&gt;But I want to call out something I wrote &lt;a href=&quot;http://blogs.tedneward.com/post/sscli-20-internals/&quot;&gt;eight years ago&lt;/a&gt;, in the Prologue to the second edition:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;[T]he book also marks a turning point, as well: with the release of the FCL source to the wider world of the development community and the lack of significant changes to the execution engine since v2, the Rotor distribution has effectively been &amp;quot;cut loose&amp;quot; by its original creators, to stand on its own within the community, as every open source project must do at some point. This is not a cause for alarm or concern—-the Mono project continues full force, and Microsoft‘s growing comfort with the open-source community leads to the distinct possibility that the commercial CLR source will, one day, stand where Rotor once stood.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&apos;s probably bad form to smirk as hard as I am right now. But I&apos;m still doing it.&lt;/p&gt;
&lt;p&gt;Thank you, David Stutz, for blazing the trail that Rotor could go down, and in doing so start the avalanche that would eventually become Microsoft&apos;s engagement in the larger world of open source. We in the Microsoft community owe you a pretty big debt.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Fallacies of Enterprise Computing</title>
      <link>http://blogs.newardassociates.com/blog/2016/enterprise-computing-fallacies.html</link>
      <pubDate>Wed, 24 Aug 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/enterprise-computing-fallacies.html</guid>
      	<description>
	&lt;p&gt;More than a decade ago, I published &lt;a href=&quot;https://www.amazon.com/Effective-Enterprise-Java-Ted-Neward/dp/0321130006&quot;&gt;Effective Enterprise Java&lt;/a&gt;, and in the opening chapter I talked about the Ten Fallacies of Enterprise Computing, essentially an extension/add-on to Peter Deutsch&apos;s Fallacies of Distributed Computing. But in the ten-plus years since, I&apos;ve had time to think about it, and now I&apos;m convinced that Enterprise Fallacies are a different list. Now, with the rise of cloud computing stepping in to complement, supplment or replace entirely the on-premise enterprise data center, it seemed reasonable to get back to it.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;I&apos;ll expand on the items in the list over future blog posts, I imagine, but without further ado, here&apos;s the Fallacies of Enterprise Computing.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;New technology is always better than old technology&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Enterprise systems are not &amp;quot;distributed systems&amp;quot;&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Business logic can and should be centralized&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Data, object or any other kind of model can be centralized&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;The system is monolithic&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;The system is finished&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Vendors can make problems go away&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Enterprise architecture is the same everywhere&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Developers need only worry about development problems&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As Deutsch said, &amp;quot;Essentally everyone, when they first build a [enterprise] system, makes the following [nine] assumptions. All prove to be false in the long run and all cause big trouble and painful learning experiences.&amp;quot;&lt;/p&gt;
&lt;p&gt;Naturally, I welcome discussion around these, and I may edit and/or append to this list as time goes by, but this is where the past decade has led me.&lt;/p&gt;
&lt;h3&gt;New technology is always better than old technology&lt;/h3&gt;
&lt;p&gt;After building IT systems for more than sixty years, one would think we as an industry would have learned that &amp;quot;newer is not always better&amp;quot;. Unfortunately, this is a highly youth-centric industry, and the young have this tendency to assume that anything new to them is also new to everybody else. And if it&apos;s new, it&apos;s exciting, and if it&apos;s exciting, it must be good, right? And therefore, we must throw away all the old, and replace it with the new.&lt;/p&gt;
&lt;p&gt;This cannot be emphasized enough: This is fallacious, idiotic, stupid, and brain-dead.&lt;/p&gt;
&lt;p&gt;This fallacy is an extension of the old economic &amp;quot;limited market&amp;quot; fallacy: The more gains one entity makes in a market, the more that other entities lose. (Essentially, it suggests that the market is intrinsically a zero-sum game, despite obvious evidence that markets have grown substantially even in just the last hundred years since we started tracking economics as a science.) Thus, for example, if the cloud is new, and it has some advantages over its &amp;quot;competitors&amp;quot;, then every &amp;quot;win&amp;quot; for the cloud must mean an equal &amp;quot;loss&amp;quot; for the alternatives (such as on-prem computing). Never mind that the cloud solves different problems than on-prem computing, or that not everything can be solved using the cloud (such as computing when connections to the Internet are spotty, nonexistent, or worse, extremely slow).&lt;/p&gt;
&lt;p&gt;Now, for those of you who have been engaged in the industry for more than just the past half-decade, here&apos;s the $65,535 question for you: How is &amp;quot;the cloud&amp;quot; any different from &amp;quot;the mainframe&amp;quot;, albeit much, much faster and with much, much greater storage?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Those who cannot remember the past are condemned to repeat it. --George Santanyana, Historian&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&apos;ve seen this play out over and over again, starting with my own entry into the IT universe with C++ (which was the &amp;quot;new&amp;quot; over C), and participated in a few system rewrites to C++ from other things (Visual Basic being one, C being another, sometimes some specific vertical stuff as well). Then I saw it again when Java came around, and companies immediately started rewriting some of their C++ systems into Java. This time around, I started to ask, &amp;quot;Why?&amp;quot;, and more often than not, answers of &amp;quot;We don&apos;t want to fall too far behind&amp;quot; or &amp;quot;We need to modernize our software&amp;quot; were the fairly vague answers. (When pressed as to why &amp;quot;falling behind&amp;quot; was bad, or why software needed to be modernized, I was usually shushed and told not to worry about it.)&lt;/p&gt;
&lt;p&gt;In the years since, I keep thinking that companies have started to get this message more thoroughly, but then something comes along and completely disrupts any and all lessons we might have learned. After Java, it was Ruby. Or, for those companies that didn&apos;t bite on the Java apple, it was .NET. Now NodeJS. Or NoSQL. Or &amp;quot;cloud&amp;quot;. Or functional programming. Or take your pick of any of another&lt;br /&gt;
half-dozen things.&lt;/p&gt;
&lt;p&gt;Unfortunately, as much as I wish I could believe that &amp;quot;it&apos;s different this time&amp;quot; and we as an industry have learned our way through this, I keep seeing signs that no, unfortunately, that&apos;s too much to hope for. The easy way to mitigate this fallacy is to force those advocating new technology to enumerate the benefits in concrete terms---monetary and/or temporal benefits, ideally, backed by examples and objective analysis of pros and cons.&lt;/p&gt;
&lt;p&gt;By the way, for those who aren&apos;t sure if they can spot the fallacy, the easy way to tell if somebody is falling into this fallacious trap is to see if their analysis contains both positive and negative consequences. No technology is never without its negatives, and a practical and objective analysis will point it out. If it&apos;s you doing the analysis, then force yourself to ask the question, &amp;quot;When would I &lt;em&gt;not&lt;/em&gt; use this? What circumstances would lead me away from it? When is using this going to lead to more pain than it&apos;s worth?&amp;quot;&lt;/p&gt;
&lt;h3&gt;Enterprise systems are not &amp;quot;distributed systems&amp;quot;&lt;/h3&gt;
&lt;p&gt;This means, simply, that any enterprise system is subject to the same fallacies as any other distributed system. Reliability, latency, bandwidth, security, the whole nine yards (or the whole eight fallacies, if you prefer) are all in play with any enterprise system.&lt;/p&gt;
&lt;p&gt;If you&apos;re not familiar with the Eight Fallacies of Distributed Systems, take some time to make yourself familiar with them and some of the mitigation strategies.&lt;/p&gt;
&lt;h3&gt;Business logic and should be centralized&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;(Note: I wrote this up a long time ago in a blog post as the &amp;quot;Eleventh Fallacy of Distributed Systems&amp;quot;, but it feels vastly more relevant as an Enterprise Fallacy.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The reason this is a fallacy is because the term &amp;quot;business logic&amp;quot; is way too nebulous to nail down correctly, and because business logic tends to stretch out across client-, middle- and server- tiers, as well as across the presentation and data access/storage layers.&lt;/p&gt;
&lt;p&gt;This is a hard one to swallow, I’ll grant. Consider, for a moment, a simple business rule: a given person’s name can be no longer than 40 characters. It’s a fairly simple rule, and as such should have a fairly simple answer to the question: Where do we enforce this particular rule? Obviously we have a database schema behind the scenes where the data will be stored, and while we could use tables with every column set to be variable-length strings of up to 2000 characters or so (to allow for maximum flexibility in our storage), most developers choose not to. They’ll cite a whole number of different reasons, but the most obvious one is also the most important–by using relational database constraints, the database can act as an automatic enforcer of business rules, such as the one that requires that names be no longer than 40 characters. Any violation of that rule will result in an error from the database.&lt;/p&gt;
&lt;p&gt;Right here, right now, we have a violation of the &amp;quot;centralized business logic&amp;quot; rule. Even if the length of a person’s name isn’t what you consider a business rule, what about the rule stating that a person can have zero to one spouses as part of a family unit? That’s obviously a more complicated rule, and usually results in a foreign key constraint on the database in turn. Another business rule enforced within the database.&lt;/p&gt;
&lt;p&gt;Perhaps the rules simply need to stay out of the presentation layer, then. But even here we run into problems–--how many of you have used a website application where all validation of form data entry happens on the server (instead of in the browser using script), usually one field at a time? This is the main drawback of enforcing presentation-related business rules at the middle- or server-tiers, in that it requires round trips back and forth to carry out. This hurts both performance and scalability of the system over time, yielding a poorer system as a result.&lt;/p&gt;
&lt;p&gt;So where, exactly, did we get this fallacy in the first place? We get it from the old-style client/server applications and systems, where all the rules were sort of jumbled together, typically in the code that ran on the client tier. Then, when business logic code needed to change, it required a complete redeploy of the client-side application that ended up costing a fortune in both time and energy, assuming the change could even be done at all–the worst part was when certain elements of code were replicated multiple times all over the system. Changing one meant having to hunt down every place else a particular rule was–or worse, wasn’t–being implemented.&lt;/p&gt;
&lt;p&gt;This isn’t to say that trying to make business logic maintainable over time isn’t a good idea–--far from it. But much of the driving force behind &amp;quot;centralize your business logic&amp;quot; was really a shrouded cry for &amp;quot;The Once and Only Once Rule&amp;quot; or the &amp;quot;Don’t Repeat Yourself&amp;quot; principle. In of themselves, they&apos;re good rules of thumb. The problem is that we just lost sight of the forest for the trees, and ended up trying to obey the letter of the law, rather than its spirit and intentions. Where possible, centralize, but don&apos;t take additional costs beyond the benefits of doing so.&lt;/p&gt;
&lt;p&gt;By the way, one place where the &amp;quot;centralize only if it&apos;s convenient&amp;quot; rule has to be set aside is around validating inputs from foreign locations---in other words, any data which is passed across the wire or comes in from outside the local codebase. In order to avoid security vulnerabilities, data should &lt;em&gt;always&lt;/em&gt; be verified as soon as it reaches your own shores, even if that means duplicating it in every foreign-accessible interface.&lt;/p&gt;
&lt;h3&gt;Models can be centralized&lt;/h3&gt;
&lt;p&gt;As tempting as it is to create &amp;quot;one domain model to rule them all&amp;quot;, particularly given all the love for Domain-Driven Design in the past ten years or so. A similar corollary to the &amp;quot;one domain model&amp;quot; is the &amp;quot;one database model&amp;quot;---at some point in the enterprise IT manager&apos;s tenure, somebody (usually a data architect or consultant) will suggest that massive savings (of one form or another) can be had for the taking if the company takes the time to create a unified database. In other words, bring all the different scattered databases together under one roof, centralized in one model, and all the data-integration problems (data feeds into databases, ETL processes, and so on) will be a thing of the past as every single codebase now accesses the Grand Unified Data Model.&lt;/p&gt;
&lt;p&gt;I have never seen one of these projects ever actually ship. Other architects have told me that they&apos;ve had them ship, but when I follow up with people who&apos;ve been at said companies, the universal story I hear is that once built, the resulting model was so complex and unwieldy that within a short period of time (usually measured in months) it was abandoned and/or fractured into smaller pieces so as to be usable.&lt;/p&gt;
&lt;p&gt;The problem here is that different parts of the enterprise care about different aspects of a given &amp;quot;entity&amp;quot;. Consider the ubiquitous &amp;quot;Person&amp;quot; type, which is almost always one of the first built in the unified model. Sales cares about the Person&apos;s sales history, Marketing cares about their demographic data (age, sex, location, etc), HR cares about their company-related information (position, department, salary, benefits status, etc), and Fulfillment (the department that ships your order once purchased) cares about address, credit card information, and the actual order placed.&lt;/p&gt;
&lt;p&gt;Now, obviously, trying to keep all of this in one Person entity (the so-called &amp;quot;fat&amp;quot; entity, since it has everything that any possible department could want from it) is going to be problematic over time---if nothing else, fetching a list of all of the Persons from the system for a dropdown will result in downloading orders of magnitude more data than actually required. (This also runs afoul of the &amp;quot;Bandwidth is inifite&amp;quot; and &amp;quot;Latency is zero&amp;quot; and &amp;quot;Transport cost is zero&amp;quot; fallacies of Distributed Systems.) Clients will quickly start caching off only the parts they care about, and the centralized data model is essentially decentralized again.&lt;/p&gt;
&lt;p&gt;The next reasonable step is to split Person up into &amp;quot;derived&amp;quot; models, usually (in the relational sense) by creating subsidiary tables for each of the specific parts. This is reasonable, assuming that the cost of doing joins (in the relational sense) across the tables is acceptable. Unfortunately, these sorts of centralized data models are usually supposed to hold the entirety of the enterprise&apos;s data in one database, so the costs of doing joins across millions of rows in multiple tables is often prohibitive. But let&apos;s leave that alone for a moment.&lt;/p&gt;
&lt;p&gt;Where things really start to go awry is that enterprise systems are never monolithic (see the next fallacy), and the code that accesses the centralized data model often needs to be modified in response to &amp;quot;local&amp;quot; concerns; for example, HR may suddenly require that &amp;quot;names&amp;quot; (which are common to the Person core table) be able to support internationalization, but Marketing is right in the middle of an important campaign, and any system downtime or changes to their codebase are totally unacceptable. Suddenly we have a political tug-of-war between two departments over who &amp;quot;owns&amp;quot; the schedule for updates, and at this point, the problem is no longer a technical problem whatsoever. (This is the same problem that sank most centralized distributed systems, too---any changes to the shared IDL or WSDL or Schema have to ratified and &amp;quot;bought off&amp;quot; by all parties involved.)&lt;/p&gt;
&lt;p&gt;Where this falls apart for domain models is right at the edge of the language barrier---a domain model in the traditional DDD sense simply cannot be shared across language boundaries, no matter how anemic. Classes written in C# are not accessible to Java except through tools that will do some form of language translation for local compilation, and these will almost always lose any behavior along the way---only the data types of the fields will be brought along. Which sort of defeats half the point of a Rich Domain Model.&lt;/p&gt;
&lt;h3&gt;The system is monolithic&lt;/h3&gt;
&lt;p&gt;While this may have been true in older systems (like, around the mainframe era), often the whole point of an enterprise system is to integrate with other systems in some way, even if just accessing the same database. Particularly today, with different parts of the system being revised at different times (presentation changes but business logic remains the same, or vice versa), it&apos;s more important than ever to recognize the different parts of the system will need to deploy, version, and in many cases be developed independently of one another.&lt;/p&gt;
&lt;p&gt;This fallacy is often what drives the logic behind building microservice-based systems, so that each microservice can be managed (deployed, versioning, developed, etc) independently. However, despite the fact that many enterprise IT departments are building microservices, they then undo all that good work by then implicitly creating dependencies between the microservices with no mitigating strategy to deal with one or more of those microservices being down or out. This means that instead of explicit dependencies (which might force the department or developers to deal with the problem explicitly), developers will lose track of this possibility until it actually happens in Production---which usually doesn&apos;t end well for anybody.&lt;/p&gt;
&lt;h3&gt;The system is finished&lt;/h3&gt;
&lt;p&gt;The enterprise is a constantly shifting, constantly changing environment. Just when you think you&apos;ve finished something, the business experts come back with some new requirements or some changes to what you&apos;ve done already. It&apos;s the driving reason behind a lot of the fallacies of both distributed systems and enterprise systems, but more importantly, it&apos;s the underlying impetus behind most, if not all, enterprise software development. Enterprise developers can either embrace this, and recognize that systems need to be able to evolve effectively over time---or look for work in other industries.&lt;/p&gt;
&lt;p&gt;This means, then, that anything that gets built here should (dare I say &amp;quot;must&amp;quot;) be built with an eye towards constant-modification and incessant updates. This is partly why agile methodologies have taken the enterprise space with such gusto---as a construction approach, by the fact that agile embraces the idea that everything is constantly in flux, it deals far more easily with the idea that the system is never finished.&lt;/p&gt;
&lt;h3&gt;Vendors can make problems go away&lt;/h3&gt;
&lt;p&gt;Alternatively, we can phrase this as &amp;quot;Vendors can make problem &apos;X&apos; a vendor problem&amp;quot;, where &apos;X&apos; is one of scalability, security, maintainability, flexibility, and just about any other &amp;quot;ility&amp;quot; you care to name. As much as vendors have been trying to make this their problem, for the better part of two or three decades, they&apos;ve never been able to do so except in some very narrow vertical circumstances. Even in today&apos;s cloud-crazed environment, companies that try to take their existing enterprise systems and move them to the cloud as-is (the classic &amp;quot;lift and shift&amp;quot; strategy) are finding that the cloud has nothing magical in it that makes things scale automagically, secure them, or even make them vastly more manageable than they were before. You can derive great benefits from the cloud, but in most cases you have to meet the cloud halfway---which then means that the vendor didn&apos;t make the problem go away, they just re-cast the problem in terms that make it easier for them to sell you things. (And even then, they can only make a few of those probems go away, often at the expense of making other problems more difficult. As an example of how deployments and dependency management got burned, for example, see &amp;quot;npm-Gate&amp;quot;.)&lt;/p&gt;
&lt;h3&gt;Enterprise architecture is the same everywhere&lt;/h3&gt;
&lt;p&gt;Somehow, there seems to be this pervasive belief that if you&apos;ve done enterprise architecture at company X, you can take those exact same lessons and apply them to your experience at company Y. This might be true if every company had exactly the same requirements, but ask any consultant who&apos;s been engaged with clients for more than a few years, and you&apos;ll find out that the Venn diagram of requirements between any two companies overlaps about 80% or so. But here&apos;s the ugly truth of that secret: if we look at the Venn diagram of all the companies, they aren&apos;t overlapping on the same 80%---it&apos;s always a different 80% between themselves and any other company. Which means, collectively, that the sum total of all companies overlaps across maybe 5%. (All accounting systems agree on what credits and debits are, but from there, the business rules tend to diverge.)&lt;/p&gt;
&lt;p&gt;Given that enterprise architecture is highly context-sensitive to the enterprises for which it is being developed, it would stand to reason that enterprise architecture will differ from one company to the next. No matter what the vendor/influencer tries to tell you, no matter how desirable it is to believe, there is no such thing as a &amp;quot;universal enterprise architecture&amp;quot;; not MVC, not n-tier, not client-server, not microservices, not REST, not containers, and not whatever-comes-next.&lt;/p&gt;
&lt;h3&gt;Developers need only worry about development problems&lt;/h3&gt;
&lt;p&gt;Enterprise systems come with much higher criticality concerns than the average consumer software product. Consider, for a moment, the average iOS or Android application---if it crashes mid-use, the user is obviously annoyed, and if it happens too often, they might uninstall the application entirely, but no signficant monetary loss is incurred to the company. If, on the other hand, the company&apos;s e-commerce system crashes, literally thousands of dollars are potentially being lost per minute (or second, if the scale is that of an Amazon or other large-scale e-tailer) until that system gets back on its feet and can start processing transactions again. And that&apos;s not counting the cost of potential customer service costs or even lawsuits if an order is lost because the system went down mid-transaction and put the data into a corrupted or unrecoverable state. Nor does that consider the intangible costs that come into play when Ars Technica or Forbes or---worst of all---the Wall Street Journal covers the outage in their latest report.&lt;/p&gt;
&lt;p&gt;Enterprise systems, by definition, have much higher reliability and recoverability concerns. That means, practically speaking, that any enterprise system must pay much greater attention to how the system is administered, deployed, monitored, managed, and so on. Thanks to the emphasis on the whole &amp;quot;DevOps&amp;quot; thing, this is becoming less of an argument with most developers, but even within companies that don&apos;t subscribe to all of the &amp;quot;DevOps&amp;quot; philosophy, developers will need to spend time thinking (and coding) about how operations staff will do all of the things they need to do to the system after its deployment.&lt;/p&gt;
&lt;p&gt;For example, one such concern is that of error management and handling. But first, please repeat after me: &amp;quot;It is never acceptable to find out about an enterprise system outage from your users.&amp;quot; Why this is not an accepted truth is well beyond me, but countless enterprise systems seem to feel it perfectly acceptable to show their users stack traces when things go wrong, or that it&apos;s perfectly acceptable to only worry about restarting the system when a user complaint informs Operations it&apos;s down.&lt;/p&gt;
&lt;p&gt;Yes, vendors can often provide certain kinds of management software to look at the system from the outside---keeping track of processes to make sure they&apos;re still running and such---but on the whole, it&apos;s going to be up to developers building the enterprise system to make sure that Operations staff can peer inside the system to make sure everything is running, running smoothly, and can make the changes necessary (such as adding users, changing users&apos; authorized capabilities, adding new types of things into the system, and so on) without requiring a restart or editing cryptic text files. Management, monitoring, deployment, restarting the system after a failure---these, and more, are all developer responsibilities until the developers provide those capabilities to Operations staff to actually use.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>On Finding Learning</title>
      <link>http://blogs.newardassociates.com/blog/2016/on-finding-learning.html</link>
      <pubDate>Fri, 22 Jul 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/on-finding-learning.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;tl;dr&lt;/em&gt; In a recent blog post, a commenter asked some questions that I felt were a bit more easily answered in the main blog format than in comments. Specifically, he asked two of the more common &amp;quot;How do I...&amp;quot; questions---finding motivation, and finding time.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;In the &lt;a href=&quot;http://blogs.tedneward.com/post/the-value-of-failure/&quot;&gt;&amp;quot;The Value of Failure&amp;quot;&lt;/a&gt;, &lt;a href=&quot;http://disq.us/p/1a970ar&quot;&gt;Greg asked&lt;/a&gt; two questions:&lt;/p&gt;
&lt;h3&gt;Finding motivation&lt;/h3&gt;
&lt;p&gt;First off:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;How to motivate myself to grow and learn, when I&apos;m the only senior java developer in my company. I&apos;m surrounded with people who don&apos;t care about gro wing &lt;em&gt;[sic]&lt;/em&gt;, and learning.&lt;br /&gt;
Let&apos;s say I can change my &amp;quot;corporation&amp;quot;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For this one, I&apos;m going to channel some &lt;a href=&quot;https://www.amazon.com/Motivating-People-Doesnt-Work-What/dp/1626561826&quot;&gt;Susan Fowler&lt;/a&gt; and suggest that motivation comes in two basic forms: &amp;quot;extrinsic&amp;quot;, whereby motivation comes in external forms (external rewards, such as bonuses or raises, or external threats such as being reprimanded, shamed, or fired), or &amp;quot;intrinsic&amp;quot;, whereby motivation comes from within.&lt;/p&gt;
&lt;p&gt;Intrinsic motivation vastly trumps extrinsic motivation. Psychology has confirmed this through a variety of studies. Anecdotal evidence will usually affirm it as well, if you happen to be in a position to observe both.&lt;/p&gt;
&lt;p&gt;The real message is what Fowler says in the very beginning of the book: It&apos;s not a question of motivating you. You&apos;re already motivated; the real quetion is what you are motivated to do. And whether you&apos;re motivated to do the things that you think you want to do. (It&apos;s not always easy to answer that, and it&apos;s not always as obvious as we might think.)&lt;/p&gt;
&lt;p&gt;For example, you&apos;re already motivated to learn, Greg. You&apos;re asking questions, you&apos;re reading blogs and watching videos, and you&apos;re looking for new input. This isn&apos;t a question of motivation for you. At least, not yet, anyway.&lt;/p&gt;
&lt;p&gt;What you may be feeling is frustration, given that you&apos;re surrounded by people who don&apos;t feel similarly as you do. And that&apos;s where I&apos;d turn the tables on you, put on my philosopher&apos;s and psychologist&apos;s hat, and ask, why does their motivation matter to you? It&apos;s the only obstacle you cite in your question, so it&apos;s clearly important to you, but why?&lt;/p&gt;
&lt;p&gt;In fact, you&apos;re sort of arguing that they&apos;re not motivated. I would disagree---as Fowler points out, they, too, are motivated, but they are motivated in a different direction than you are. It might be an interesting exercise to find out what they&apos;re motivated to do, rather than blame them or implicitly shame them by suggesting that their motivations are somehow inferior or less professional than yours. (And I&apos;m not suggesting that you&apos;re making a big deal out of it; I&apos;m merely saying that there is a strong strain of &amp;quot;Everyone working in this industry should be constantly growing and learning&amp;quot; that is common to the Software Craftsmanship movement, and I find it to be a little (or a lot) elitist.)&lt;/p&gt;
&lt;p&gt;Getting back to the practical, I think your question is not so much about motivation as it is about facilitation---in other words, &lt;em&gt;how&lt;/em&gt; do you find new things when it&apos;s not coming to you through the channels of your current job? And for that, I think you can probably guess the answers: user groups, hackathons, and so on. You&apos;ve already hinted at the idea of leaving your current work situation, which is obviously one approach, but I wouldn&apos;t be too quick to pull the trigger on that just yet. Yes, it&apos;s always cool to (as Chad Fowler once put it) &amp;quot;Be the worst musician in any band you&apos;re in&amp;quot;, so that you&apos;re always surrounded by people who will challenge you, but those positions can be hard to find, and they still don&apos;t always give you everything you want or need. One thing that I do, which you may find one avenue to approach, is to teach---I currently guest-lecture at the University of Washington on mobile development, and frankly, I find that I&apos;ve learned more about mobile development for both iOS and Android from doing that than I ever did &amp;quot;just&amp;quot; writing code. (Students are amazingly good at challenging assumptions and asking questions you never think to ask yourself....)&lt;/p&gt;
&lt;h3&gt;Finding time&lt;/h3&gt;
&lt;p&gt;Next,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What is the most efficient balance between learning and working? I have two kids and no time after work to learn. The only time I can find is during my working day. Unfortunately project I&apos;m working on, don&apos;t give me any new experience...&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As a father of two boys-grown-to-men (23 and 16 as of this writing), I have total sympathy with you. It&apos;s not easy, trying to juggle family life and professional life outside of the usual forty hours a week. And while it would certainly be nice if work would help out by allowing you some dedicated time each week towards study and/or other kinds of advancement, the key thing is to remember that most companies are a little short-sighted on this point---they believe they are paying you for your time spent delivering direct value to the company, and most don&apos;t do a great job of tracking the indirect value that you can bring through taking time to train. We can rant and wail about how that should be different, but given the tight margins under which many companies operate, it&apos;s an established---and not soon-to-change---&lt;em&gt;fait accompli&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;And the fact is, I can&apos;t really tell you how to balance your life, other than to tell you to balance your work/life balance &lt;em&gt;deliberately&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;People will often speak of &amp;quot;finding&amp;quot; time. Time is not &amp;quot;found&amp;quot;. We all of us have the same amount of time per day, and the only variable here is how we choose to spend it.&lt;/p&gt;
&lt;p&gt;Most of the time, people will utter statements like the above with the intent to persuade you to spend more time with your family. I won&apos;t do that; in fact, I&apos;ll even go so far as to tell you to spend more time at work, not because I think you need to do so in order to be a solid &amp;quot;Craftsman&amp;quot;, but because if you are the principal breadwinner in your family, then you need to make sure you are doing your due diligence to your family not just for today, but for the next eighteen years (or more). You do that by maximizing your opportunities to bring in revenue to the family, so that your family can have the financial freedom and flexibility to live the kind of life you want them to be able to live.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;But&lt;/em&gt;, paired with that, is the realization that your children will only be young once. They will be looking at you all of the time, and they will be learning from you how to be an adult, even when you think they&apos;re busy playing with their toys or nose-deep in their phones.&lt;/p&gt;
&lt;p&gt;Yes, I&apos;m speaking out of both sides of my mouth here, because this decision---how much time to spend in your off-hours improving yourself both as a programmer and as a father---is one that is intensely personal, and not one that should be made for you by anybody other than yourself.&lt;/p&gt;
&lt;p&gt;Thus we get to what I mean by the phrase &amp;quot;make it &lt;em&gt;deliberately&lt;/em&gt;&amp;quot;: examine the things you do in your life on a daily basis. Look for ways to cut things out of your life that aren&apos;t really things that you think will bring real value. For example, none of my family watches TV together. (As a matter of fact, we don&apos;t really watch much TV at all, though my 16-year-old likes to binge-watch anime from time to time.) Cutting TV out actually creates a ton of extra time for reading or coding or cruising through blogs and such.&lt;/p&gt;
&lt;p&gt;When I tell this to people, I sometimes hear &amp;quot;But in some families, TV time is the only time the family really spends together, so if you cut that out....&amp;quot; In my family, that&apos;s not the only time we spend together; about ten or so years ago, one of the popular board-game companies (Milton-Bradley, I think) started an ad campaign about &amp;quot;Family Game Night&amp;quot;. Each week, one night is reserved for the family to play a board game together. My family started doing that, but before long we found that after making dinner and doing dishes, we were kind of burned out about cleaning up the table to set up a game.&lt;/p&gt;
&lt;p&gt;So we adopted a new rule: We took the games with us out to restaurants, and we played over dinner, there, in the restaurant. Lots of different games: Settlers of Catan, Magic: The Gathering, Carcassone, Ticket to Ride, Smallworld, and others. Wait staff at restaurants soon recognized us and (because we tended to tip a little extra by way of thanks for letting us consume a table for two or even three hours, sometimes) greeted us by name and took us to the larger tables so that we would have room to play.&lt;/p&gt;
&lt;p&gt;What does this have to do with making time to learn programming? Simple: It&apos;s easy to feel less guilty about telling the kids, &amp;quot;Hey, I have to go out and get some work done&amp;quot; when the kids know that they will get time with you later, and it will be &amp;quot;quality time&amp;quot;, playing a game and tossing trash talk back and forth. (Games in my family tend towards the competitive end of the spectrum.)&lt;/p&gt;
&lt;h3&gt;Mindfulness&lt;/h3&gt;
&lt;p&gt;This is where I get a little philosophical again, and start talking about that weirdly Zen thing called &amp;quot;mindfulness&amp;quot;. It&apos;s really not all that deep of a Zen thing, not like &amp;quot;the sound of one hand clapping&amp;quot; or anything; mindfulness is simply the idea that if you&apos;re going to be doing X, be doing X, and not any of the two hundred other things that tend to distract and weaken your presence.&lt;/p&gt;
&lt;p&gt;If you&apos;re in a meeting with somebody, and they&apos;re constantly checking their phone, looking at their laptop, jumping up every so often to take a phone call or send a text message, and so on, it&apos;s generally not a good feeling. You can&apos;t be sure that you&apos;ve got their full attention. Any decisions that come out of that meeting are always going to carry with them the stain of &amp;quot;But was Fred really listening to me when he said that?&amp;quot;&lt;/p&gt;
&lt;p&gt;If you&apos;re going to spend time with the kids, then focus on them. Play with them. Talk to them, listen to them, create new stories and games with them, and so on. Be &amp;quot;present&amp;quot; in that moment with them, without the distractions and without the constant interruptions (to the best of your ability; there&apos;s always going to be exceptions, obviously).&lt;/p&gt;
&lt;p&gt;But the other interesting thing about family is that sometimes, you can actually spend time with them &lt;em&gt;and&lt;/em&gt; be doing things that help your career simultaneously.&lt;/p&gt;
&lt;p&gt;Case in point: As I write this blog post, I&apos;m sitting in a restaurant with my wife. She is heads-down on her laptop, as am I. We&apos;re just sitting here, not talking to one another, each of us doing our own thing and in our own world, yet this will, in some indescribable way, count as &amp;quot;together time&amp;quot;. I&apos;ve done this with the kids, too: they bring homework, I bring the laptop, and we work together at a restaurant (have I mentioned my rather serious addiction to Diet Coke before now?). I&apos;m there if they have questions (though now at their age, I&apos;m generally not of much help other than to try and work through to the answers with them), and the rest of the time, I&apos;m heads-down writing code or working on an article or whatever.&lt;/p&gt;
&lt;h3&gt;Wrapping up&lt;/h3&gt;
&lt;p&gt;Keeping up with all of the things going on in this industry is tricky and hard. Do so deliberately---mindfully---by deciding very specifically what you want to study next. (Turns out it won&apos;t really matter what you choose, only that you choose something to study.)&lt;/p&gt;
&lt;p&gt;Decide very specifically how and when you want to spend the time with your family, and don&apos;t be afraid to carve out some time for yourself to do that study.&lt;/p&gt;
&lt;p&gt;Look for ways to claim some time back---if you currently mow your own lawn, look at the cost of hiring a gardener to do the work for you, and use the time you&apos;ve saved to study instead.&lt;/p&gt;
&lt;p&gt;Create some forcing functions---user group presentations, articles for publications, anything with a deadline---as extrinsic motivation to make sure you get that study time in. (Deadlines also help provide  &amp;quot;justifications&amp;quot; to the family for why Daddy needs to work, and can&apos;t help with the dishes, by the way. ;-) )&lt;/p&gt;
&lt;p&gt;Lastly, do all of this deliberately and consciously. Think about spending your time the same way you would your money---sit down with your spouse or significant other and discuss how you need to invest time into your career during the off-hours. Budget. Carve out some time for yourself to study whatever it is that sounds good. Take Sunday afternoons for yourself, and block out any sort of social activities with the family for that time, if you must.&lt;/p&gt;
&lt;p&gt;The first book(s) I ever wrote, I would do so at night. I would come home from work, do dinner and after-dinner with my wife and kids, then about 9pm or so, after the kids were asleep, I&apos;d take a laptop down to a 24-hour restaurant in town, and work on the book there until about midnight or 1 (or later, sometimes). Head home, slip into bed, wake up and go back to work the next day. Didn&apos;t leave me much time for doing much socializing, but that was OK with me---my friends understood that this book was a big deal, and from time to time, I&apos;d put the book aside and hang out with them for a while, just to recharge the batteries. Weekends, Saturdays were writing time, but Sundays were family time.&lt;/p&gt;
&lt;p&gt;You don&apos;t have to commit that kind of time. You don&apos;t have to give up anything you don&apos;t want to give up. But you do have to understand that all of life is about priorities and budgeting time, and that if you&apos;re doing it right, the time you&apos;re spending on activities matches the priorities that you&apos;ve set for yourself; if they&apos;re not, then it&apos;s time to do a thorough audit of your &amp;quot;time budget&amp;quot;, and get them back into line with one another.&lt;/p&gt;
&lt;p&gt;The rest, as they say, is up to you. Good luck.&lt;/p&gt;
&lt;p&gt;(&lt;em&gt;EDIT&lt;/em&gt;: My wife read this after it was published, and found a few typos and places where things weren&apos;t clear, so I tried to clean it up a touch. Release early, release often, as they say...)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Intellectual Honesty</title>
      <link>http://blogs.newardassociates.com/blog/2016/intellectual-honesty.html</link>
      <pubDate>Thu, 7 Jul 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/intellectual-honesty.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;tl;dr&lt;/em&gt; At last night&apos;s Seattle Languages meeting, I was reminded of what intellectually-honest debate does and does not look like; then, as part of the discussions and argument around the tragic deaths of several black men at the hands of police, I was presented with a link to a page entitled &amp;quot;Ten Signs of Intellectual Honesty&amp;quot;. This is good material.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;First off, the original link: &lt;a href=&quot;https://designmatrix.wordpress.com/2010/11/14/ten-signs-of-intellectual-honesty-2/&quot;&gt;Ten Signs of Intellectual Honesty&lt;/a&gt;. I&apos;m going to be quoting from it liberally, however, in case you don&apos;t want to click through. (But please do so at least once sometime, so the author gets their just kudos for posting such awesomeness.)&lt;/p&gt;
&lt;p&gt;With no further ado....&lt;/p&gt;
&lt;h4&gt;Do not overstate the power of your argument.&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;One&apos;s sense of conviction should be in proportion to the level of clear evidence assessable by most. ... Intellectual honesty is most often associated with humilty, not arrogance.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The humility thing really strikes a chord with me. Many years ago, I had the chance to conduct a one-on-one CNN-style interview with Bjarne Stroustrup (the creator of C++, if you&apos;re not familiar with the name), and one of the first things that struck me was how quick he was to disavow the things he &lt;em&gt;doesn&apos;t&lt;/em&gt; know. There is no &lt;em&gt;braggadocio&lt;/em&gt;, no &amp;quot;look at the cool shit I&apos;ve created&amp;quot;, nothing. Brian Goetz (the Java language architect at Oracle) is similarly quite ready to admit what&apos;s outside his wheelhouse. Venkat Subramaniam is one of the most open minds I&apos;ve ever met. And so on and so on and so on; the bigger the &amp;quot;name&amp;quot; in Computer Science, the more humble they tend to be. (With a few exceptions, many of whom have now &amp;quot;outed&amp;quot; themselves over social media.) I have since taken this to mean that the louder you crow about yourself, the less others are willing to crow about you, which is probably because there&apos;s not all that much to crow about.&lt;/p&gt;
&lt;p&gt;&amp;quot;If someone portrays their opponents as being either stupid or dishonest for disagreeing, intellectual dishonesty is probably in play.&amp;quot; Alas, it&apos;s not always that easy; too often, genuinely-interested people are arguing over the facts, because we&apos;re too busy clinging to the facts that we like and ignoring the ones we don&apos;t.&lt;/p&gt;
&lt;h4&gt;Show a willingness to publicly acknowledge that reasonable alternative viewpoints exist.&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;The alternative views do not have to be treated as equally valid or powerful, but rarely is it the case that one and only one viewpoint has a complete monopoly on reason and evidence.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is even more true in areas where clear objective evidence is simply lacking. I will freely admit that people can build non-trivial systems in Perl; that doesn&apos;t change the fact that &lt;a href=&quot;http://blogs.tedneward.com/post/so-i-dont-like-perl-sue-me/&quot;&gt;I dislike the language&lt;/a&gt;. Nor does it change the fact that it can be useful. I have my reasons for why I don&apos;t like it, and we can debate as to whether those reasons are legitimate or pure opinion, but that doesn&apos;t mean it isn&apos;t useful to people who&apos;ve used it in the past.&lt;/p&gt;
&lt;h4&gt;Be willing to publicly acknowledge and question one&apos;s own assumptions and biases.&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;All of us rely on assumptions when applying our world view to make sense of the data about the world. And all of us bring various biases to the table.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Another quote from Stroustrup: &amp;quot;The more I know, the more I know I don&apos;t know.&amp;quot; If the guy who&apos;s forgotten more about programming languages than I will ever know can say that, then there&apos;s no room for me to stand up and insist that somehow I am never wrong. I think I know things, but there&apos;s always the chance that I got the information wrong, the information I got was wrong when I got it, or the situation has changed since I got that information.&lt;/p&gt;
&lt;h4&gt;Be willing to publicly acknowledge where your argument is weak.&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Almost all arguments have weak spots, but those who are trying to sell an ideology will have great difficulty with this point and would rather obscure or downplay any weak points.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(Yeah, I really don&apos;t have a whole lot more to add to that.)&lt;/p&gt;
&lt;h4&gt;Be willing to publicly acknowledge when you are wrong.&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Those selling an ideology likewise have great difficulty admitting to being wrong, as this undercuts the rhetoric and image that is being sold.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is probably the hardest thing in the world to do, and it&apos;s why so often we do so with these weasel-word qualifiers. &amp;quot;If I offended anyone, I am sorry that they were offended.&amp;quot; Or &amp;quot;I was perhaps mistaken about the degree of truth in the statements you and I exchanged during that conversation.&amp;quot; These are not admissions of incorrectness. These are attempts to salvage the ego and balm the uncomfortable feeling that comes with being incorrect about something.&lt;/p&gt;
&lt;p&gt;Make the resolution right now: Admit when you are wrong at least once a day. That&apos;s mine.&lt;/p&gt;
&lt;h4&gt;Demonstrate consistency.&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;A clear sign of intellectual dishonesty is when someone extensively relies on double standards. Typically, an excessively high standard is applied to the perceived opponent(s), while a very low standard is applied to the ideologues&apos; allies.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&apos;s hard sometimes to see, but this is part of why I think we engage in some of these endeavors---not to convince anybody of anything, but to find out where my own thinking is not being consistent and/or &amp;quot;fair&amp;quot;.&lt;/p&gt;
&lt;h4&gt;Address the argument instead of attacking the person making the argument.&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Ad hominem arguments are a clear sign of intellectual dishonesty. However, often times, the dishonesty is more subtle. For example, someone might make a token effort at debunking an argument and then turn significant attention to the person making the argument, relying on stereotypes, guilt-by-association, and innocent-sounding gotcha questions.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yeah, this starts to sound like just about every &amp;quot;flame war&amp;quot; I&apos;ve ever seen go on between people who don&apos;t have respect for one another. Including a few I&apos;ve been in. (And apologies, by the way, to anyone I made ad hominem attacks against in the past, intentionally or accidentally. I don&apos;t recall any, but I&apos;m sure there&apos;s more than a few across my past.)&lt;/p&gt;
&lt;h4&gt;When addressing an argument, do not misrepresent it.&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;A common tactic of the intellectually dishonest is to portray their opponent’s argument in straw man terms. ... Typically, such tactics eschew quoting the person in context, but instead rely heavily on out-of-context quotes, paraphrasing and impression. When addressing an argument, one should shows signs of having made a serious effort to first understand the argument and then accurately represent it in its strongest form.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sometimes, unfortunately, in the tone-less medium of the Internet, it&apos;s too easy to interpret genuine questions for clarification or additional information around an argument as a precursor to a strawman, which is why as a general rule, if I&apos;m seeking additional information, I try to just keep it to the question and nothing else---no interpretation and no &amp;quot;spin&amp;quot;. (I will also be the first to admit that it&apos;s a favorite tactic of mine, to do exactly the opposite: Ask the question, anticipate the answer, and provide the &amp;quot;devastating&amp;quot; counterargument to what I think the answer will be. This is my commitment to try and break that habit.)&lt;/p&gt;
&lt;h4&gt;Show a commitment to critical thinking.&lt;/h4&gt;
&lt;p&gt;Want to start? Pick up a book on philosophy. Seriously. This is a subject that is all about doing nothing but critical thinking---there&apos;s little in the way of repeatable, observable experiments that can be done in philosophy to arrive at an empirical truth. (In fact, one could argue that as soon as we can do that in a subject, it becomes &amp;quot;science&amp;quot; instead of philosophy.)&lt;/p&gt;
&lt;p&gt;Best thing you can do for your career, honestly.&lt;/p&gt;
&lt;p&gt;The original post contains a quick link to &lt;a href=&quot;https://designmatrix.wordpress.com/2009/01/24/critical-thinking/&quot;&gt;this&lt;/a&gt;, which contains the following workable list:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;gather complete information – more than one source&lt;/li&gt;
&lt;li&gt;understand and define terms (make others define terms, too)&lt;/li&gt;
&lt;li&gt;question the methods by which results were derived&lt;/li&gt;
&lt;li&gt;question the conclusion: do the facts support it? is there evidence of bias? remember correlation does not equal causation.&lt;/li&gt;
&lt;li&gt;uncover assumptions and biases&lt;/li&gt;
&lt;li&gt;question the source of information&lt;/li&gt;
&lt;li&gt;don’t expect all the answers&lt;/li&gt;
&lt;li&gt;examine the big picture&lt;/li&gt;
&lt;li&gt;look for multiple cause and effect&lt;/li&gt;
&lt;li&gt;watch for thought stopping sensationalism&lt;/li&gt;
&lt;li&gt;understand your own biases and values&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;From &lt;em&gt;Human Biology: Health, Homeostasis, and The Environment, 3rd Edition&lt;/em&gt;, by Daniel D. Chiras.&lt;/p&gt;
&lt;p&gt;Again, all of these are things that philosophical thinking tends to drum out of you. It begins with asking questions, and then questions about the questions.&lt;/p&gt;
&lt;h4&gt;Be willing to publicly acknowledge when a point or criticism is good.&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;If someone is unable or unwilling to admit when their opponent raises a good point or makes a good criticism, it demonstrates an unwillingness to participate in the give-and-take that characterizes an honest exchange.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;More importantly, it demonstrates that you can separate the argument from the arguer---and gets the egos out of the way. (By the way, this holds for any criticism---if you&apos;re being criticized over something, including things like a code review, finding at least one thing in the critique that you can agree with in any way can help to separate your own ego out of the discussion.)&lt;/p&gt;
&lt;p&gt;This whole blog is good, if you&apos;re a fan of science (with an emphasis on biology, it seems).&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Speaking Tips: James Ward&apos;s Suggestions on Abstracts</title>
      <link>http://blogs.newardassociates.com/blog/2016/james-ward-suggestions.html</link>
      <pubDate>Thu, 7 Jul 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/james-ward-suggestions.html</guid>
      	<description>
	&lt;p&gt;James Ward also wrote an article on how to write abstracts, and I realized after I published that I forgot to call out to his article as well. &lt;em&gt;Mea culpa.&lt;/em&gt;&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;First off, &lt;a href=&quot;https://medium.com/@_jamesward/5-tips-for-getting-accepted-to-speak-at-conferences-7cabdb400fa#.38mazmaaw&quot;&gt;James&apos; post is here&lt;/a&gt;, and for the most part, I think we agree on most things.&lt;/p&gt;
&lt;p&gt;Where he says &lt;strong&gt;&amp;quot;Make the title clear, concise and enaging&amp;quot;&lt;/strong&gt;, I would word that differently, simply because too many readers will see &amp;quot;engaging&amp;quot; and think &amp;quot;cute&amp;quot;, which I have come to dislike. Go with simple, straightforward, and clear. Go with boring. (The body of that list item makes it more clear, I think, that he and I actually agree on this.)&lt;/p&gt;
&lt;p&gt;James then says &lt;strong&gt;&amp;quot;Start the abstract with a problem or controversial statement&amp;quot;&lt;/strong&gt;. Staring with the problem is basically the &amp;quot;pain&amp;quot; part of my abstract. I dislike the idea of starting with a controversial statement, however, because I think that tends to attract the wrong kind of attendee to your session. Specifically, it goes back to the whole, &amp;quot;You get what you go looking for&amp;quot; mantra that parents have been trying to teach their kids---if you go out there looking for a fight, you&apos;ll find one soon enough. In an abstract, if you say, &amp;quot;Object-orientation is dead; functional programming is here to rule the world&amp;quot;, several things will happen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Some of the people who will show up will show up just to argue with you. You are threatening their understanding of the universe, and in many cases you are directly threatening the tools they use to make a living, and as such, you are threatenting them.&lt;/li&gt;
&lt;li&gt;Some of the people who will show up will be functional programmers who are zealots like you profess to be, and they will either (a) turn on you if your session isn&apos;t as zealous as your abstract suggests, or (b) &amp;quot;help&amp;quot; you during the session by yelling or shouting at would-be object-oriented hecklers. What&apos;s worse, their behavior will often kick in even on questions asked by people who really don&apos;t have an opinion, thus ruining the experience for them.&lt;/li&gt;
&lt;li&gt;Most importantly, the people you really want to reach will probably not show up at all. Think about it---would you attend a session feeling safe and comfortable if the abstract read, &amp;quot;All computer programmers are a drain on our society, and in this session, we&apos;ll talk about how regular folks can throw off the chains of tyranny imposed on us by these pasty-white nerds and their mysterious boxes of electricity&amp;quot;? Probably not.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, if the intent of the session is to &lt;em&gt;encourage&lt;/em&gt; that kind of argumentation, which is common for a speaker panel or some other audience-participation-driven session, then by all means, go for it. But remember, your abstract is your contract with the audience---if you don&apos;t make good on the contract (including the salacious &amp;quot;Jer-ry&amp;quot; parts, if that&apos;s what you promise), then you&apos;ve failed and you&apos;re probably going to get hammered in the evals.&lt;/p&gt;
&lt;p&gt;Next: **&amp;quot;Make the abstract about the content and attendee, not you&amp;quot;. This one, I didn&apos;t talk about, and he&apos;s right. In all fairness, I think this is true of much more than the abstract, and something I think is just a general approach/attitude about all speaking, but it deserves mention and I&apos;m glad James throught to bring that out.&lt;/p&gt;
&lt;p&gt;Here we might disagree a little bit more strongly: &lt;strong&gt;&amp;quot;Clearly describe what attendees will take away from the session&amp;quot;&lt;/strong&gt;. My concern hinges on the word &amp;quot;clearly&amp;quot;; many reades might take that to mean &amp;quot;in great detail&amp;quot;, and as I said earlier, an abstract is not a detailed play-by-play of what you&apos;re going to do in the talk, but a high-level overview. The body of his tip suggests that he and I are more on the same page, though, when he says, &amp;quot;Make sure the abstract clearly identifies what the attendee has to gain from going to the session&amp;quot;. In other words, make sure the session has the Promise to go along with the Pain.&lt;/p&gt;
&lt;p&gt;But when he says, &amp;quot;Although this could have been improved by more clearly saying that attendees will not just walk away with the &apos;why&apos; but the &apos;how&apos;&amp;quot;, I&apos;m not sure I agree. It depends on the focus of the session---for a higher-level session, such as a discussion of the Fallacies of Distributed Computing, for example, the &amp;quot;how&amp;quot; isn&apos;t as important. The &amp;quot;why&amp;quot; is essentially the point of the session. If the session is supposed to be technical and demonstrative, however, then the &amp;quot;how&amp;quot; needs to come out, and it&apos;s a good idea to say that in the abstract, but without giving away which &amp;quot;how&amp;quot; points you&apos;re going to discuss. (Again, you as the speaker want to maintain some &amp;quot;pivot room&amp;quot; within the talk, even after it&apos;s been submitted.)&lt;/p&gt;
&lt;p&gt;Lastly, James rounds it out with &lt;strong&gt;&amp;quot;Like a resume, make it professional&amp;quot;&lt;/strong&gt;. People, that shouldn&apos;t even have to be mentioned. If you want to be taken seriously, you have to take your communication skills seriously in turn.&lt;/p&gt;
&lt;p&gt;(Sidebar: I&apos;ve heard some folks complain that this unfairly biases the selection process against those for whom English is not a native language. I&apos;m sympathetic to that point, but you have to see it from the organizers&apos; perspective---if the conference is in English, and the abstract doesn&apos;t demonstrate a strong grasp of the English language, what faith do the organizers have that the presentation itself will have a strong grasp of the English language, and thus be something the attendees will be able to understand? And let me be the first to say that if I were preparing to deliver a session in France, speaking in French, I would fully expect my session to be rejected out-of-hand, because my French simply isn&apos;t up to the task, written or spoken. This isn&apos;t about discrimination, it&apos;s about making sure the attendees get what they paid for: something they can understand and use in their day jobs. It&apos;s for this same reason that American speakers need to be very sensitive to American cultural references when speaking outside of the US, something I already alluded to in the previous article. &lt;em&gt;Clarity must triumph.&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;Honestly, if you&apos;re not a professional writer, then it behooves you to take your abstract to a copyeditor or your favorite family &amp;quot;GrammarNazi&amp;quot; and ask them to do a pass on it. It may not be fun---being corrected rarely is---but if it makes the difference between a &amp;quot;one look and to the rubbish bin&amp;quot; and &amp;quot;a second look and maybe a third and acceptance&amp;quot;,isn&apos;t it worth it?&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>It is too possible</title>
      <link>http://blogs.newardassociates.com/blog/2016/it-is-too-possible.html</link>
      <pubDate>Tue, 21 Jun 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/it-is-too-possible.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;tl;dr&lt;/em&gt; Once again I find myself in the position of needing to call BS on a blog post and deconstruct it: Yes, it is possible to be a good .NET developer, and here&apos;s why.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;First, as always, if you&apos;ve not read the original, &lt;a href=&quot;http://codeofrob.com/entries/why-you-cant-be-a-good-.net-developer.html&quot;&gt;check it out&lt;/a&gt;. Again, I&apos;ll be quoting from it, so you needn&apos;t remember all of it, but read it once just to get a good idea of what&apos;s there.&lt;/p&gt;
&lt;p&gt;Now, let&apos;s deconstruct.&lt;/p&gt;
&lt;h2&gt;Why you can&apos;t be a good .NET developer&lt;/h2&gt;
&lt;p&gt;Mr Ashton seems to be basing his argument on a couple of things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Developers are leaving .NET.&lt;/li&gt;
&lt;li&gt;The reason developers are leaving .NET isn&apos;t because of &amp;quot;self-loathing&amp;quot;, but because they work in shops that cater to the lowest-common-denominator.&lt;/li&gt;
&lt;li&gt;... There is no third reason. Just lots of use of the perjorative word &amp;quot;derpy&amp;quot;. Because that will make the point far better than any logic could.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let&apos;s break those down:&lt;/p&gt;
&lt;h3&gt;Developers are leaving .NET&lt;/h3&gt;
&lt;p&gt;Mr Ashton opens with:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The reason why people &amp;quot;leave&amp;quot; .NET is ---&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This one will be hard to invalidate, because there&apos;s two forms of evidence that we can pull into play: empirical evidence, which is hard to gather objectively, and anecdotal evidence, which is easy to gather (for each of us individually, anyway), hard to refute, and yet hardly industry-indicative.&lt;/p&gt;
&lt;p&gt;Here&apos;s what I mean. Assume that I have observed that when the door slams, people jump. As a matter of fact, I can go around and slam doors, and watch that everybody within close proximity of the door jumps. That means that, anecdotally, 100% of the population will jump when I slam the door. Yay science!&lt;/p&gt;
&lt;p&gt;Of course, I probably should mention that none of the people being observed are deaf, and none of them have been through this particular experiment before. (As it turns out, you can get used to anything, including the noise of slamming  doors, and thus not flinch, despite what anecdotal evidence may tell you.)&lt;/p&gt;
&lt;p&gt;But perhaps this is a tangent, becaues Mr Ashton never comes back to this point of developers leaving---he prefers instead to focus on the rationale, which is:&lt;/p&gt;
&lt;h3&gt;Lowest-common-denominator enterprise shops&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;To work in a development shop with a team is to continually cater for the lowest common denominator of that team and the vast majority of software shops using .NET have a whole lot of lowest common denominator to choose their bad development decisions for. ... It&apos;ll not happen because as long as you&apos;re working on a platform that is primarily used by derpy enterprise shops, you will continually be held back because those derpy enteprise shops are continually be held back by the derpy enterprise developers that work in the derpy enterprise shops.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In case you weren&apos;t quite clear on his position, he goes on to say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It isn&apos;t self loathing, it&apos;s self preservation and an eventual realisation that you can&apos;t actually progress so long as you&apos;re being held back by bad decisions made to cater for the slow and the stupid. Self loathing is just an intermediate stage that people go through while they still believe they can make an impact on the environment around them by caring and shouting into the void to enact tiny changes that help nobody.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sounds to me like Mr Ashton has some angst he needs to work out in therapy.&lt;/p&gt;
&lt;p&gt;Perhaps he has some strong empirical evidence to back this position?&lt;/p&gt;
&lt;p&gt;He cites two pieces of anecdotal evidence, and then makes some broad sweeping generalizations:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Tangible examples? I remember well the insistence of one boss that we use TFS because some developers would find it hard to use git.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Or, perhaps, because the boss had some other good reasons not to use Git. I&lt;br /&gt;
can imagine a couple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Git often implies GitHub, which can be costly for businesses if the source needs to remain closed-source. By all means, there are alternatives to GitHub, one of my favorites being &lt;a href=&quot;http://bitbucket.com&quot;&gt;BitBucket&lt;/a&gt;, but developers frothing at the mouth over Git often can&apos;t comprehend the idea of using it without GitHub.&lt;/li&gt;
&lt;li&gt;Managers often need their reports. TFS, for all of its flaws, has a better integration story in the ALM cloud than GitHub does, and management that is used to (as in, built processes around) some of these reports will find it is a non-trivial cost to move to something other than TFS.&lt;/li&gt;
&lt;li&gt;Why does which source control system you use matter all that much? Developers often get all worked up over this, but frankly, teams spent years working with non-distributed systems like Subversion and CVS before Git came along. As a matter of fact, unless your team spends significant amounts of time offline from the source-control server, there&apos;s a strong argument to be made that you don&apos;t need to use Git or Mercurial at all.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;I remember the steadfast committal to ASP.NET web forms because the &amp;quot;new concepts&amp;quot; in ASP.NET MVC were going to take too long for the team to become productive in.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And that&apos;s a reasonable concern. Look, developers love to chase the bright new shiny, whatever that happens to be, and frankly they&apos;re more than willing to learn at their employers&apos; expense at times, making mistake after mistake after mistake until they&apos;ve mastered the new shiny in question---at which point they start chasing after the next new bright shiny. Quite often, these bright shiny chasedowns don&apos;t yield any practical benefit to the end-user---in fact, they achieve the exact opposite. Working with new languages, platforms, and tools often leads to more bugs in the early days, and if there&apos;s no commensurate improvement to the end users (in the long term, forget about the short term), then there&apos;s absolutely no business reason to go down this path.&lt;/p&gt;
&lt;p&gt;I actually &lt;em&gt;agree&lt;/em&gt; that WebForms is vastly inferior to MVC. My former company had a client that was heavily invested in WebForms, and refused all interest in moving to MVC, and their code was literally impossible to automate testing around because of it. As a long-term strategic decision, it was a poor one. But as a short-term tactical one, it made sense.&lt;/p&gt;
&lt;p&gt;And that&apos;s the bigger picture: sometimes management needs to make short-term tactical decisions that aren&apos;t optimal in the long-term. Eventually, if the company has strong management, that course gets corrected. But that&apos;s not a flaw in the technology, it&apos;s a flaw in the management structure using it. I can (and have) see Java shops making the same decisions. C++ shops are hardly immune to this. Nor are COBOL shops.&lt;/p&gt;
&lt;p&gt;The answer to this, of course, is to make sure that the team is spending some time coming up to speed on the bright shiny things that strategically are important to the company; my preference would be that they spend at least two hours a week doing some guided study around those topics. But that&apos;s another topic for another day.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There is now this furore &lt;em&gt;[sic]&lt;/em&gt; over .NET core and the new thing in the tiny 0.001% of people that care are whether they persist in using Windows or switch to more productive environments.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Of course we assume that &amp;quot;more productive environments&amp;quot; is a shadowy reference to the Mac or a Linux environment, but frankly, I find that I&apos;m just as productive in a Windows-based world as I am in a Mac-based world. The tools are different, and the approach is different, but there&apos;s a reason why I still make use of both environments on a regular basis.&lt;/p&gt;
&lt;p&gt;And, by the way, .NET Core is an as-yet-unreleased environment. Trying to point to that as a failure of the .NET platform as a technology is like pointing to a half-finished supercarrier sinking. Of course it sank---it wasn&apos;t finished! Funny thing is, most half-finished environments or ships will also sink. Shall we compare the Ruby 0.9 release against the .NET 4.6 release and see which one wins, while we&apos;re at it?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Of course @aliostad gets it right here and points out that the primary &amp;quot;Important Thing&amp;quot; should be a focus on functional programming in languages like F# and of course the reason it doesn&apos;t happen is because &amp;quot;it&apos;s too hard for most people in our team&amp;quot;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I love the unattributed quote---it&apos;s so easy to pretend that you&apos;re quoting somebody without having to actually name anybody or any particular context, thus making it hard to refute. It&apos;s &amp;quot;almost as if you can&apos;t really find anybody to substantiate your arguments with actual fact&amp;quot;.&lt;/p&gt;
&lt;p&gt;But in this particular case, I&apos;ve heard it from several development managers, speaking to both F# and Scala. And I&apos;ve challenged them on several occasions, to let me spend a few hours going over the concept with their team, and see what the team thinks afterwards. In each of those situations, the team has &amp;quot;gotten it&amp;quot;, and although they&apos;re not functional programmers ready to embrace Haskell as the One True Programming Language (which is ludicrous anyway), they understand the core concepts and can see where and how it might be applied. Or not applied, as the case may be. (Because, quite honestly, there are a number of cases where a functional mindset doesn&apos;t really fit the problem at hand. And this is why both of those languages---F# and Scala---are actually object/function hybrid languages, and not strictly functional.)&lt;/p&gt;
&lt;p&gt;The larger issue here, though, is that managers understand---in ways that software developers don&apos;t seem to, as Mr Ashton emblemizes---that learning new syntax and concepts and approaches takes time. Absent any formal time set aside for the team to learn those new things, that time will most often come at the expense of the project on which these developers are working. And while sometimes that means that the project will come in early (because learning the new thing helped shorten the overall release cycle), far more often than not, it means the project gets pushed back. Which leads management to a pretty inescapable conclusion:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Project + Tool(new) = delays&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Perhaps management isn&apos;t the derp here, after all.&lt;/p&gt;
&lt;h2&gt;But why is this .NET&apos;s fault?&lt;/h2&gt;
&lt;p&gt;This the part that doesn&apos;t seem to be elucidated in Mr Ashton&apos;s rant; he cites his two anecdotal examples (only one of which is actually .NET specific; one could see the TFS/git argument taking place in a Java shop just as easily as in a .NET shop), then makes his two sweeping generalizations, but without any actual evidence that this is somehow localized to the .NET segment of the industry. News flash, Mr Ashton: This exact same argument happens in Java shops (&amp;quot;Why can&apos;t we use Groovy/Scala/Clojure/Kotlin?&amp;quot;) and, as companies invest more deeply into Ruby and/or NodeJS (assuming they ever do---Ruby seems to be fading fast from the enterprise landscape, for whatever reasons), they will make the same kinds of decisions around those platforms, as well.&lt;/p&gt;
&lt;p&gt;Because, Mr Ashton, it turns out that this isn&apos;t a question of the tool or the language, it&apos;s a question of the environment in which they are being used. And, as any &amp;quot;derpy&amp;quot; enterprise development manager knows, the bleeding edge is called the bleeding edge for a pretty good reason.&lt;/p&gt;
&lt;h2&gt;Well, that means it&apos;s the derpy co-workers&apos; fault&lt;/h2&gt;
&lt;p&gt;Let&apos;s be clear, fundamentally Mr Ashton&apos;s arguments really aren&apos;t with .NET, whether he realizes it or not. He&apos;s actually angry at his industry colleagues at these &amp;quot;derpy&amp;quot; enterprise shops, because (in his not-so-subtle opinion) they&apos;re the ones  that management is trying to accomodate with their &amp;quot;derpy&amp;quot; decisions. Again, just to be clear:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It isn&apos;t self loathing, it&apos;s self preservation and an eventual realisation that you can&apos;t actually progress so long as you&apos;re being held back by bad decisions made to cater for the slow and the stupid.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&apos;s pretty clear that Mr Ashton considers most enterprise software developers to be &amp;quot;slow and stupid&amp;quot;. This is elemental logic: a manager doesn&apos;t make a decision for a team based on the consequences for just one member of the team, but on the basis of what the majority of the team has or lacks. Therefore, in Mr Ashton&apos;s view, the majority of enterprise developers are &amp;quot;derps&amp;quot; who are simply too slow and too stupid to understand the new things. What magnificent benefits could be  had, if only they would stop plodding down the lane like oxen, and instead gallavant and run through the forests, wind whipping through their hair as they leap over obstacles like the rest of the stallions do!&lt;/p&gt;
&lt;p&gt;Except that oxen never break their ankles attempting to leap an obstacle that is too high for them. Oxen will never dump their riders on the ground because they ran under a low-hanging branch that was too low for the human on their back. And oxen will never decide on their own to simply refuse to make a particular jump because, frankly, they just don&apos;t want to.&lt;/p&gt;
&lt;p&gt;Roads were created to help eliminate the obstacles, and make it easier for farmers to get their goods to market where, you know, they can sell them and stuff. Which is used to buy other things, like food for the oxen. And a roof over their heads in the winter. And the brush the farmer uses to comb out the snarls in their fur. And so on.&lt;/p&gt;
&lt;p&gt;(OK, all analogies break down eventually.)&lt;/p&gt;
&lt;p&gt;Truth is, there&apos;s a lot of good reasons to stay to the road. Roads are something that anyone can navigate, whether oxen, stallion or simple plain ol&apos; human. Roads also have this funny way of making it clear what is interesting in the world---if a particular town starts to grow, more people will start traveling to it, and the roads will---organically---stablize and get smoother and easier to travel. In fact, funny thing---if the road gets too much traffic on it, it will start to degrade, at which point people will step in and pave the thing. And put up signs to regulate traffic on it. And so on, each time reducing the obstacles on the road itself and making it easier to travel.&lt;/p&gt;
&lt;p&gt;Don&apos;t be hating the &amp;quot;derpy&amp;quot; enterprise developer because they don&apos;t want to go crashing through the forests like stallions do. If you don&apos;t want to be one of those &amp;quot;derpy&amp;quot; enterprise developers, then don&apos;t be one. But considering those folks are the ones that wrote (and continue to maintain) the code that cashes your paycheck every month, maybe you&apos;d be better off thanking them, instead of insulting them.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Value of Failure</title>
      <link>http://blogs.newardassociates.com/blog/2016/the-value-of-failure.html</link>
      <pubDate>Sun, 29 May 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/the-value-of-failure.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;tl;dr&lt;/em&gt; Celebrating success is always a welcome thing. But in a lot of ways, the people we should be celebrating are the ones who failed, and then learned from it. As a matter of fact, there&apos;s a reasonable correlation to be drawn here---that those who are truly successful are the ones who failed first.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;This is actually a post that I&apos;ve been holding on to for a while now, having originally been inspired by a  &lt;a href=&quot;https://hbr.org/2016/03/companies-cant-be-great-unless-theyve-almost-failed&quot;&gt;Harvard Business Review&lt;/a&gt; article that goes into this more deeply. In it, the author states:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One intriguing feature of these enormous success stories is that so many of them are little-known companies in ordinary, sometimes downright boring industries: railroads, health insurance, back-office automation. ... But the more important part of the story... is that every one of these star performers faced at least one “near-death experience” during the course of its long-term success. I don’t mean a few quarters of sluggish growth or a one-time product flop, but a radical shift in its market, a major technology disruption, or a disastrous strategic bet that threatened the company’s very existence.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Many, many years ago, when I was contracting for this guy &lt;a href=&quot;https://www.mountaingoatsoftware.com/&quot;&gt;Mike Cohn&lt;/a&gt;, he mentioned to a good friend of mine (who was working there with me) that &amp;quot;Ted needs to fail. Twice.&amp;quot; Needless to say, Mike didn&apos;t say it to my face. I wouldn&apos;t have heard it for the advice that it was---I&apos;d have seen it (as many people do, when I tell this story) as a desire to see me brought low or something. In truth, it was anything but that. Mike also was the guy who told me that, &amp;quot;You have so much book knowledge, people forget that you don&apos;t have a lot of experience, and expect a lot more out of you than you&apos;re capable of delivering. It&apos;s like being 6-foot-4-inches at 13; you look like an adult, but you&apos;re not one, yet.&amp;quot;&lt;/p&gt;
&lt;p&gt;In other words, Mike was channeling the old adage: &amp;quot;Good decisions come from wisdom. And wisdom comes from bad decisions.&amp;quot;&lt;/p&gt;
&lt;p&gt;(And, sure enough, once I had failed, twice, it was then that I started making real progress in my career as a programmer/consultant/architect. Mike had that one absolutely spot-on.)&lt;/p&gt;
&lt;p&gt;The HBR author talks about how companies trying to avoid this near-death experience just somehow don&apos;t seem to &amp;quot;get it&amp;quot;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In an effort to understand the new logic of change and the emerging rules of success, we convened a conference around the theme “How Do You Overthrow a Successful Company?” .... It was a gathering of executives, strategists, and change agents from illustrious big companies who sensed that there were massive shifts on the horizon and who were determined to reckon with those shifts and embrace a new generation of business models, a new era of technology and communications, a new level of customer expectations and sophistication. ... In other words, they were leaders who wanted their companies to win big in fast-moving times without a near-death experience. It was a great idea for a conference, yet it amounted to a hill of beans.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;He goes on to point out that all of the named companies in attendance, and how they were struggling or had met with nothing but struggles and difficulties---clearly the conference didn&apos;t really help them all that much.&lt;/p&gt;
&lt;p&gt;So what is it about failure that is necessary for success?&lt;/p&gt;
&lt;h2&gt;Failure forces retrospection&lt;/h2&gt;
&lt;p&gt;First of all, far more than any success, failure forces players to examine what&apos;s going on and why they&apos;re not being successful. We see it all the time in sports: the first-round draft pick gets to the big leagues, and doesn&apos;t really seem to take the whole thing seriously, and (not surprisingly) performs disastrously. They&apos;re accustomed to success, so they don&apos;t bother with the kind of internal reflection and retrospection that is necessary to get better.&lt;/p&gt;
&lt;p&gt;This happens with companies, too. When a company is successful, the investigation as to the mechanics of that success are limited, or else captured as part of the company&apos;s CEO tossing off some sound bites. &amp;quot;We are a company of passionate individuals who are committed to our firm&apos;s success&amp;quot; seems to be the phrase &lt;em&gt;du jour&lt;/em&gt;. Success has everything to do with the company&apos;s effort, and nothing to do with any sort of external factors that might have affected the results.&lt;/p&gt;
&lt;p&gt;When you fail, though, suddenly people want answers, and the usual raft of platitudes don&apos;t hold up anymore.&lt;/p&gt;
&lt;h2&gt;Failure creates desperation&lt;/h2&gt;
&lt;p&gt;More importantly, though, when the company&apos;s on the brink, there&apos;s a sense of focus and desperation that says &amp;quot;Well, we&apos;ve got nothing left to lose, so let&apos;s go all-in on this and see what happens.&amp;quot; This isn&apos;t a new idea; &lt;a href=&quot;https://en.wikipedia.org/wiki/Spanish_conquest_of_the_Aztec_Empire&quot;&gt;Cortez used it in his conquest of the Aztecs&lt;/a&gt;. By &amp;quot;burning the boats&amp;quot; (though history actually records that he scuttled the ships, rather than burned them), Cortez created a &amp;quot;We have no road back, we have to go forward, or die&amp;quot; mentality among his men. Their options were thus narrowed down to exactly two: conquest or death. Robert Greene, in his book &lt;a href=&quot;https://www.amazon.com/Strategies-War-Joost-Elffers-Books-ebook/dp/B000W9149K&quot;&gt;&amp;quot;The 33 Strategies of War&amp;quot;&lt;/a&gt;, calls this &amp;quot;The Death-Ground Stragegy&amp;quot;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Quite often we feel somewhat lost in our actions. We could do this or that--we have many options, but none of them seem quite necessary. Our freedom is a burden--what do we do today, where do we go? Our daily patterns and routines help us to avoid feeling directionless, but there is always the niggling thought that we could accomplish so much more. We waste so much time. ... Over two thousand years ago, the Chinese strategist Sun-tzu came to believe that listening to speeches, no matter how rousing, was too passive an experience to have an enduring effect. Instead Sun-tzu talked of a &amp;quot;death ground&amp;quot;--a place where an army is backed up against some geographical feature like a mountain, a river, or a forest and has no escape route. Without a way to retreat, Sun-tzu argued, an army fights with double or triple the spirit it would have on open terrain, because death is viscerally present. Sun-tzu advocated deliberately stationing soldiers on death ground to give them the desperate edge that makes men fight like the devil. ... The world is ruled by necessity: People change their behavior only if they have to. They will feel urgency only if their lives depend on it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Obviously, we&apos;d prefer not to hold death to peoples&apos; faces in order to get them to better react at work, but sometimes, when the chips are down, the best thing to do is to simply state, &amp;quot;This is the only path forward, we either march, or we die.&amp;quot;&lt;/p&gt;
&lt;h2&gt;So....&lt;/h2&gt;
&lt;p&gt;... what&apos;s the takeaway here?&lt;/p&gt;
&lt;p&gt;Actually, it&apos;s pretty simple: Do you really want to succeed? The Death-Ground Strategy says that you should basically put yourself into a position where you either succeed, or die. If you&apos;re contemplating becoming a technical speaker, quit your job and throw &amp;quot;all-in&amp;quot; around speaking at technical conferences and what-not. Either you will speak at the user group, or you will starve.&lt;/p&gt;
&lt;p&gt;Yeah, I&apos;m not a huge fan of that. Try it if you like, but that seems like huge downside for very small upside. Maybe for an army trapped in a foreign land whose only hope for survival is to fight its way back home, it works, but for most of the rest of us, who are nowhere close to trapped behind enemy lines, much less staring death in the face.... yeah, not so much.&lt;/p&gt;
&lt;p&gt;But there is value in failure, if only because it forces us to engage in that reflective and introspective process that helps us emerge stronger and better over time. Which then suggests to me that practically speaking, the takeaway here is to &lt;strong&gt;&lt;em&gt;Put yourself into failure-potential situations&lt;/em&gt;&lt;/strong&gt;. Take those risks. Put your career and credibility on the line. Engage in things that you aren&apos;t sure you can do, and because nobody likes to fail (including you!), you&apos;ll put forth much more effort into the exercise.&lt;/p&gt;
&lt;p&gt;&amp;quot;33 Strategies&amp;quot; offers the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Stake everything on a single throw.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Act before you are ready.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enter new waters.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Make it &amp;quot;you against the world.&amp;quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keep yourself restless and unsatisfied.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, for example, if you want to be a technical speaker, stand up and volunteer to give a talk at the local user group. Matter of fact, volunteer to do four talks over the span of the next year. (&amp;quot;Four talks?! Are you out of your mind?!? That&apos;s like one every three months!&amp;quot;) Don&apos;t do just the same talk four times---do four completely different, separate talks, which will then force you to figure out how to write good talks in a compressed period of time.&lt;/p&gt;
&lt;p&gt;Or, if your desire is to get a startup off the ground, commit to having an MVP ready by the end of the calendar year 2016 without leaving your job yet. Because let&apos;s face it, if you can&apos;t get the MVP done in six months while holding down a regular full-time job, you won&apos;t be able to handle working the 80 hours a week that a startup will demand of you during the early days. And you&apos;ll need that MVP before you can get any kind of angel or seed funding anyway.&lt;/p&gt;
&lt;p&gt;And when (not if!) you fall, figure out why, get back up, and keep going.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Practice, practice, practice</title>
      <link>http://blogs.newardassociates.com/blog/2016/practice-practice-practice.html</link>
      <pubDate>Fri, 8 Apr 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/practice-practice-practice.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;tl;dr&lt;/em&gt; Recently the Harvard Business Review ran an article on how readers could prepare for difficult business situations, using the analogy of coaches preparing their teams for different eventualities by simulating those eventualities on the practice field. There&apos;s lessons to be learned here for both programming and speaking.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;First, go check out the HBR article: &lt;a href=&quot;https://hbr.org/2016/02/practice-for-tough-situations-as-youd-practice-a-sport&quot;&gt;“Practice for Tough Situations as You’d Practice a Sport”&lt;/a&gt; by Andy Molinsky. It&apos;s a relatively short reads (as all HBR&apos;s web articles are; they&apos;re usually summaries of longer books, either theirs or something closely related to business). His focus:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To learn soft skills in a way that truly prepares us for what we’ll face when it really matters, we can take a few lessons from a different arena where learning, development, and performance are essential: professional sports.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;Belichick: The Legend&lt;/h1&gt;
&lt;p&gt;My hometown football team is the Seattle Seahawks. Two years ago, we were defeated in the Super Bowl when a Patriots cornerback leaped in front of a sure-thing short slant pass for the game-winning touchdown on what was almost the final play of the game.&lt;/p&gt;
&lt;p&gt;(And yes, critics, that pass is a sure-thing; in the 168 times it was executed all across the season, by any team, including both the Seahawks and the Patriots, as well as all 30 other teams in the league, only once was it ever intercepted---that fateful play in the Super Bowl.)&lt;/p&gt;
&lt;p&gt;Bill Belichick is the coach of the New England Patriots. He is quite a character.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One key tenet of professional sports coaching, for example, is to prepare people in the most realistic contexts possible. When professional football teams prepare for their next opponent, they’ll take into account the likely conditions they’ll face. If the stadium the team is playing in is going to be noisy, coaches like Bill Belichick of the New England Patriots will play extremely loud music at practice to mimic game-time conditions. Belichick has even been known to pour water on practice balls to prepare the team for wet game-day weather.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Bill Belichick is one of the most intense, concrete, no-holds-barred anything-to-win coaches you will ever see in this lifetime. He oozes ruthlessness out of every pore, but it&apos;s a laid-back ruthlessness---he will never get in your face and be angry, but players have said that if he goes very quiet on you, you&apos;re in deep yogurt. Point is, Belichick has a strong reputation for success (more championship rings as a coach than I think any other coach in the history of the game), and much of that success is that &lt;em&gt;nothing fazes the guy&lt;/em&gt;. Absolutely nothing. Team&apos;s down by 42 going into the final two minutes of the game? Belichick has been there before, and the team feels it. &lt;em&gt;Knows&lt;/em&gt; it. If anybody&apos;s going to figure out how to score a metric crap-ton of points in an impossible amount of time, it&apos;s Belichick. Nobody relaxes playing against a Belichick-coached team, no matter how good your lead is.&lt;/p&gt;
&lt;p&gt;When Malcolm Butler, the cornerback, was talking about that interception at the goal line, he pointed out that he had recognized that formation and that play from game film that they had studied of the Seahawks&apos; game plan. He knew---from the bottom of his heart---what the play was going to be, and if you look at the replay, he simply muscles his way into the exact right spot where Russell Wilson threw the ball. He didn&apos;t have time to track where the ball was going---if I remember correctly, he was already muscling into the spot before Wilson let go of the ball. Butler &lt;em&gt;knew&lt;/em&gt; where that pass was going. He had seen it before. They had studied it before. Which is to say, his coaches had seen it, pointed it out to their players, and the players had spent time practicing what they would do if and when that situation emerged.&lt;/p&gt;
&lt;p&gt;And it paid off for them, in spades.&lt;/p&gt;
&lt;p&gt;Belichick isn&apos;t, perhaps, the smartest coach in the league. But he&apos;s always got an answer for anything the other team throws at him, and more often than not, the other teams can&apos;t match whatever scheme he&apos;s cooked up. His teams win through preparation, not talent.&lt;/p&gt;
&lt;p&gt;And that&apos;s the point: it&apos;s often the preparation---not the talent---that creates success.&lt;/p&gt;
&lt;h1&gt;Preparation&lt;/h1&gt;
&lt;p&gt;When I interviewed at DevelopMentor, all those many years ago, I was required to conduct a &amp;quot;test teach&amp;quot; down at the company&apos;s LA (home) office. I prepared a talk, of about 35 minutes in length, and I was asked to deliver the talk in one of the classrooms while the students were out having lunch. Luc (who would later become the &amp;quot;instructor liaison&amp;quot;, but for that moment was basically the &amp;quot;man Friday&amp;quot; for most of the company) took orders ahead of time, and ran out to a nearby restaurant to order and bring back the food.&lt;/p&gt;
&lt;p&gt;I set up my slides (which I&apos;d actually written as plain HTML files, since I was very much a newbie at PowerPoint), and as I glanced up, I saw about 30 people in the room. Some were standing, most were sitting, a number were typing away at keyboards, a few were chatting in the back. Most of them really weren&apos;t paying any attention at all to me. I waited for a few minutes to see if they would notice I was ready to go. I&apos;d been told, &amp;quot;You only have about 35 minutes, and we can&apos;t hold up class, so make sure you stay within time&amp;quot;.&lt;/p&gt;
&lt;p&gt;Fortunately, I&apos;d done some Toastmasters in the past. When a crowd doesn&apos;t notice you&apos;re ready to start, you might do something to get their attention, then go ahead and start. Some speakers will clear their throat, some will be timid and say, &amp;quot;I&apos;d like to get going now, please&amp;quot;, but me... well, I&apos;ve never really been wired that way.&lt;/p&gt;
&lt;p&gt;In a small room of about 30 people, I tossed off a &amp;quot;HELLO!&amp;quot; that was about two volume levels too high. It was pretty loud---a few people actually jumped. And everybody looked at me, completely shocked. And without missing a beat, I said in a much more appropriate tone of voice, &amp;quot;My name is Ted Neward, and I&apos;m here to talk to you about Design Patterns today.&amp;quot;&lt;/p&gt;
&lt;p&gt;See, at that point they had a choice---they could admit rudeness and go back to what they were doing (which most crowds won&apos;t do, since most of us are relatively polite people), or they could pay attention to the talk, but once I had their attention, it was really on them.&lt;/p&gt;
&lt;p&gt;And the only reason I knew this? Because I&apos;d practiced this before, as part of Toastmasters.&lt;/p&gt;
&lt;p&gt;I found out later, from Luc, that the room was quite deliberately coached to be a little &amp;quot;hard&amp;quot; on me. As a matter of fact, about ten minutes into my talk, Luc showed up with lunch, and stage-whispered his way around the room delivering lunch to everybody in it. All. Thirty. People.&lt;/p&gt;
&lt;p&gt;Because you know what? If I can&apos;t lecture through a distraction or two, I&apos;m not going to last long as a professional speaker. They had the same idea as Toastmasters has had: the more you practice dealing with a situation, the more comfortable you are at dealing with it when it eventually does happen.&lt;/p&gt;
&lt;p&gt;Professional sports players practice every scenario they can think off---physically and/or mentally---so that when the moment arises, they&apos;re up to the challenge.&lt;/p&gt;
&lt;p&gt;How do you prepare?&lt;/p&gt;
&lt;h1&gt;Practical&lt;/h1&gt;
&lt;p&gt;Molinsky writes,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For example, you might work on rehearsing your pitch to potential VCs in front of a crowd of colleagues you’ve coached to pepper you with difficult questions. You might create situations where a VC is late to the meeting — or rushing you to finish your pitch in half the time you had planned. You might also do the session in a setting that mimics what you’ll likely encounter in the real world, whether that’s a noisy coffee shop or an overheated conference room.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Many speakers often &amp;quot;practice&amp;quot; their presentations in front of a sympathetic crowd---friends, family, people who genuinely love this person, and want their feelings to be spared any sort of discomfort or pain.&lt;/p&gt;
&lt;p&gt;If you love me, and I ask you to help me practice, you won&apos;t spare me discomfort. You won&apos;t try to shield me from pain. I need that discomfort, so that I know what it feels like. You actually hurt me by not making the situation realistic. Or worse than realistic.&lt;/p&gt;
&lt;p&gt;When I was mentoring a young speaker before her first big debut presentation, I brought her down to the conference room where her talk would be to practice. We found the maintenance staff setting up chairs in there. I asked if we could use the room, and when they said, &amp;quot;Well, we need to be in here to set up the chairs&amp;quot;, I told them that was fine. It was &lt;em&gt;more&lt;/em&gt; than fine---it was perfect. I made her go to the front of the room and deliver her talk to an audience of five or so; myself, and the maintenance staff that could&apos;ve cared less about her talk while they were setting up. I spent most of the time fiddling with my phone; no eye contact, no nodding, no real feedback of any kind. She was essentially giving her talk into a vacuum. (Which, as any speaker can tell you, is an incredibly draining experience.)&lt;/p&gt;
&lt;p&gt;Eventually the staff finished, and after a few more minutes, where I deliberately kept moving around the room (partly to judge her voice volume while she was speaking, to be able to tell her whether she needed to go louder or softer), we wrapped up and went to go get dinner.&lt;/p&gt;
&lt;p&gt;It was perhaps a bit harsh, but the point remains the same: people will get up and leave your talk for reasons that have nothing to do with your talk. Distractions will happen. Cell phones will ring. Tornado sirens will go off. Water will start pouring out of the ceiling for no reason whatsoever. (All of these have happened to be at one point or another.) You cannot control the circumstances surrounding your talk.&lt;/p&gt;
&lt;p&gt;As an soccer coach, I routinely told my teams, &amp;quot;We are only as good as we practice.&amp;quot; As a volunteer football coach for my son&apos;s football team, I routinely said the same thing. As a manager, I used that same logic to justify the time spent setting up infrastructure for our own internal IT, seeking to mimic the same tools, technology and process that we would use for any client.&lt;/p&gt;
&lt;p&gt;An organization will only be as good as how it practices. How well do you deal with outages? How do you know? If you&apos;ve never actually practiced an outage, you have no idea. You may have a plan, but if you&apos;ve never practiced it, you&apos;ve never actually gone through it, and therefore you really don&apos;t &lt;em&gt;know&lt;/em&gt; if any of this is going to work. How well do you deal with bug triage? How well do you deal with peformance problems? How well do you deal with refactoring?&lt;/p&gt;
&lt;p&gt;How well do you practice any of these things? If you don&apos;t, then you suck at it. I guarantee it.&lt;/p&gt;
&lt;p&gt;The old joke says that a musician was stopped on the streets one day and asked, &amp;quot;How do you get to Carnegie Hall?&amp;quot; He looked at the questioner, and without a hint of irony, said, &amp;quot;Practice, my boy, practice.&amp;quot;&lt;/p&gt;
&lt;p&gt;Oh, and her talk? She killed it.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Reclaiming Design Patterns (20 Years Later)</title>
      <link>http://blogs.newardassociates.com/blog/2016/reclaiming-design-patterns.html</link>
      <pubDate>Fri, 25 Mar 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/reclaiming-design-patterns.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;tl;dr&lt;/em&gt; 20 years ago, the &amp;quot;Gang of Four&amp;quot; published &lt;a href=&quot;http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612&quot;&gt;the seminal work on design patterns&lt;/a&gt;. Written to the languages of its time (C++ and Smalltalk), and written using the design philosophies of the time (stressing inheritance, for example), it nevertheless spawned a huge &amp;quot;movement&amp;quot; within the industry. Which, as history has shown us, was already the hallmark of its doom---anything that has ever become a &amp;quot;movement&amp;quot; within this industry eventually disappoints and is burned at the public-relations stake when it fails to deliver on the overhyped promises that it never actually made. It&apos;s time to go back, re-examine the 23 patterns (and, possibly, a few variants) with a fresh set of eyes, match them up against languages which have had 20 years to mature, and see what emerges. (Spoiler alert: all of the original 23 hold up pretty well, and there&apos;s a lot of nuance that I think we missed the first time around.)&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2&gt;Patterns: What were they for, exactly?&lt;/h2&gt;
&lt;p&gt;In the early days of the patterns &amp;quot;movement&amp;quot;, when the patterns were new and fresh, we didn&apos;t spend much time really discussing this all that much. They just &lt;em&gt;were&lt;/em&gt;; those of us who read the book nodded at a few of them, having experienced them before in code &amp;quot;in the wild&amp;quot;, and we went on about our day. Intuitively, it seemed, we realized that there were places where we could apply this knowledge, we appreciated the new dimensions the patterns opened inside our heads, and... yeah, cool.&lt;/p&gt;
&lt;p&gt;The Gang of Four (GOF) seemed to realize from the beginning that this was a subtle art/science; in the last chapter of the book (which nobody ever seemed to read, unfortunately), they said:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It&apos;s possible to argue that this book hasn&apos;t accomplished much. After all, it doesn&apos;t present any algorithms or programming techniques that haven&apos;t been used before. It doesn&apos;t give a rigorous method for designing systems, nor does it develop a new theory of design—--it just documents existing designs. You could conclude that it makes a reasonable tutorial, perhaps, but it certainly can&apos;t offer much to an experienced object-oriented designer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And in truth, that was the case: it hadn&apos;t accomplished much. One guy with whom I taught at DevelopMentor called Design Patterns &amp;quot;23 ways to use a pointer&amp;quot;. What was the big deal?&lt;/p&gt;
&lt;p&gt;And similarly, when management/senior team leads/architects threw a copy of the book at junior developers, expecting that they could read the book and suddenly &amp;quot;level up&amp;quot;, they were profoundly disappointed.&lt;/p&gt;
&lt;p&gt;The benefits, it seemed, were more subtle:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We hope you think differently. Cataloging design patterns is important. It gives us standard names and definitions for the techniques we use. If we don&apos;t study design patterns in software, we won&apos;t be able to improve them, and it&apos;ll be harder to come up with new ones.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Certainly, the GOF book spawned a movement, and the patterns movement spawned a whole catalog of patterns beyond the original 23 that the GOF came up with. But then things started getting even more abstract and high-level; patterns became &amp;quot;pattern languages&amp;quot; and that in turn spawned &amp;quot;meta-patterns&amp;quot;. Then people started documenting the negative, calling them &amp;quot;anti-patterns&amp;quot;.&lt;/p&gt;
&lt;p&gt;Once people started realizing that there was money to be made, the writing was on the wall.&lt;/p&gt;
&lt;p&gt;Various book vendors started publishing &amp;quot;patterns&amp;quot; books that barely touched on the GOF&apos;s original model. Patterns books became synonymous with &amp;quot;reusable code&amp;quot; (instead of &amp;quot;reusable elements of design&amp;quot;). IDE vendors started looking for ways to incorporate patterns as code generators. Patterns somehow also became the provice of UML and other design notations, and the goal at one point was to figure out how to create reusable design templates in UML that corresponded to patterns.&lt;/p&gt;
&lt;p&gt;Like so many things, patterns became trendy and attractive to people who had no idea what they were for. How could they ever have actually met those peoples&apos; expectations?&lt;/p&gt;
&lt;p&gt;By the mid-2000s, patterns became a bad word, and speakers started essentially &lt;a href=&quot;http://www.oracle.com/technetwork/server-storage/ts-4961-159222.pdf&quot;&gt;&amp;quot;trashing&amp;quot; patterns&lt;/a&gt;, suggesting that somehow they were an artifact of &amp;quot;bad languages&amp;quot; and &amp;quot;primitive thnking&amp;quot; and &amp;quot;subsumed into good languages&amp;quot;.&lt;/p&gt;
&lt;p&gt;Patterns were clearly useless.&lt;/p&gt;
&lt;p&gt;And yet... they keep appearing. We keep using their terms and lingo. Why? The GOF actually (in that same chapter at the back of the book) called it back in 1995:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Design patterns provide a common vocabulary for designers to use to communicate, document, and explore design alternatives. Design patterns make a system seem less complex by letting you talk about it at a higher level ofabstraction than that of a design notation or programming language. Design patterns raise the level at which you design and discuss design with your colleagues.&amp;quot; (p389)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Knowing the design patterns in this book makes it easier to understand existing systems. ... People learning object-oriented programming often complain that the systems they&apos;re working with use inheritance in convoluted ways and that it&apos;s difficult to follow the flow of control. In large part this is because they do not understand the design patterns in the system. Learning these design patterns will help you understand existing object-oriented systems.&amp;quot; (p389)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Design patterns provide a way to describe more of the &amp;quot;why&amp;quot; of a design and not just record the results of your decisions. The Applicability, Consequences, and Implementation sections of the design patterns help guide you in the decisions you have to make.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;One of the problems in developing reusable software is that it often has to be reorganized or refactored [OJ90]. Design patterns help you determine how to reorganize a design, and theycan reduce the amount of refactoring you need to do later.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(Yep, they were talking about refactoring long before it became hip.)&lt;/p&gt;
&lt;p&gt;Most of all, they actually predicted the very problem that would be the downfall of patterns as a whole:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;It&apos;s easiest to see a pattern as a solution, as a technique that can be adapted and reused. It&apos;s harder to see when it is appropriate—--to characterize the problems it solves and the context in which it&apos;s the best solution. In general, it&apos;s easier to see what someone is doing than to know why, and the &amp;quot;why&amp;quot; for a pattern is the problem it solves. Knowing the purpose of a pattern is important too, because it helps us choose patterns to apply. It also helps us understand the design of existing systems. A pattern author must determine and characterize the problemthat the pattern solves, even if you have to do it after you&apos;vediscovered its solution.&amp;quot; (p393)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Too many short-sighted people saw the &amp;quot;solution&amp;quot;, and in their rush to find reusable code, they forgot (or chose not) to learn the &amp;quot;why&amp;quot;, and as a result ended up making some very stupid---and easily preventable---mistakes.&lt;/p&gt;
&lt;h2&gt;What is a pattern?&lt;/h2&gt;
&lt;p&gt;There&apos;s been a lot of discussion on this over the yeas, but I&apos;m going to keep this down to a single sentence:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;A pattern is a solution to a problem within a certain context that has a set of predictable consequences.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That&apos;s all it is. There&apos;s nothing magical, mysterious, or super-academic about it. If you can describe all four parts of that tuple, you have a pattern. Write it down. Publish it somewhere. When we start seeing some similarities between us all, we can start to see what the commonality is and then give it a nice well-chosen name, and it can join the general lexicon.&lt;/p&gt;
&lt;p&gt;The Gang of Four published 23 of them. There&apos;s a lot more out there. Most are actually pretty useful. But particularly the first 23, because they stretch across a ton of different languages. (The patterns community later came to the terminology of an &amp;quot;idiom&amp;quot;, which was something that was language-specific. Thus, the &amp;quot;Resource Acquisition Is Initialization&amp;quot; (RAII) idea from C++ was more-or-less tied to C++ as an idiom, and didn&apos;t really qualify as a pattern, &lt;em&gt;per se&lt;/em&gt;.)&lt;/p&gt;
&lt;h2&gt;Why are we arguing again?&lt;/h2&gt;
&lt;p&gt;The last sentence, however, brings up another important point: Too much of the patterns community spent too much time arguing about them, and whether a given thing was a pattern or not, or whether a particular code snippet was an implementation of this pattern or that pattern, or....&lt;/p&gt;
&lt;p&gt;There&apos;s several thoughts at work here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The exercise of philosophical debate around a pattern&apos;s composition is important to the benefit they provide.&lt;/strong&gt; This was why the patterns community said things like &amp;quot;It&apos;s not a pattern until it&apos;s been discovered three times&amp;quot; and &amp;quot;A pattern isn&apos;t really a pattern unless it&apos;s been workshopped at a patterns conference&amp;quot;. The point wasn&apos;t to add some kind of mystery or intrigue or make them solely the provice of those &amp;quot;in the know&amp;quot;; the point was to debate them in a philosophical matter to refine the pattern to its essence, and keep the quality high. But once people start saying, &amp;quot;Pfffft&amp;quot; and avoided those critical steps, then suddenly everything became a pattern. If suddenly we can start calling local variables a &amp;quot;pattern&amp;quot;, then the whole point of designing a higher-level toolbox of terms becomes lost. If anybody can call anything a &amp;quot;pattern&amp;quot;, then we have everybody calling everything a pattern, and patterns lose their efficacy in conversation. If patterns are somehow localized to the team they were &apos;born&amp;quot; on, then now I cannot converse with anybody outside of my team. Science has a rigor to it (in particular, the peer-review portions) for a reason, and that rigor was what the patterns community tried to bring.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Which pattern happens to be in use here is a subject of philosophical debate.&lt;/strong&gt; LOTS of people got hung up on arguing with other members of the team over what kind of pattern some code was. I cannot imagine a more useless activity, unless the discussion led to new insights (a new application of it, or a new &amp;quot;angle&amp;quot; to it) around said pattern. We burned a lot of goodwill by arguing with people over this.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Patterns were not the be-all/end-all of good design.&lt;/strong&gt; You can have a good design that doesn&apos;t fit an established pattern. Pattern snobs needed to stop putting a qualitative judgment around those who weren&apos;t pattern snobs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the end, we patterns snobs probably brought the downfall upon our own heads, but we had help.&lt;/p&gt;
&lt;h2&gt;Time to take them back&lt;/h2&gt;
&lt;p&gt;So I figure it&apos;s time, 20 years later, to start the discussion all over again. I don&apos;t imagine that I can rebuild the entire movement on my own, but at the very least, I can take the old prose, dust it off, and look to bring it into the 21st Century and the languages that we use. There&apos;s also probably a few more patterns that we&apos;ve found along the way, and where I think they fit, I&apos;ll take a stab at a few and put them up for people to consider and workshop. (Or, rather, more of a &amp;quot;mob-shop&amp;quot;, since a weblog isn&apos;t really a workshop setting.)&lt;/p&gt;
&lt;p&gt;Over the next &lt;em&gt;n&lt;/em&gt; months, I&apos;m going to put up the original 23 patterns re-cast for the &amp;quot;modern world&amp;quot;. I&apos;ll do a quick  recap of the pattern, but cast into the form I prefer (Problem/Solution/Context/Consequences). I deliberately won&apos;t spend a whole lot of time trying to re-describe all the prose from the book---that would be copyright infringement, in my mind, and I not only want to steer clear of that, but I really do want to encourage people to buy a copy of it for themselves, do their own reading, and debate whether my interpretation is legitimate and/or reasonable. Then, I&apos;m going show how a few languages can implement them, and I&apos;m going to range pretty freely over a bunch of different languages: C++, C#, Java, Swift, F#, Scala, JavaScript, and a few others. &lt;em&gt;I encourage you to comment and post suggestions/amendments/corrections.&lt;/em&gt; I&apos;m definitely not the smartest person in the world, and certainly not the last word on how to apply certain language idioms to a particular problem. Plus, I&apos;d love to see us collectively flesh out some implementations around these patterns across all the popular (and maybe a few less popular, just for educational purposes!) languages.&lt;/p&gt;
&lt;p&gt;It&apos;ll take time, so bear with me. I&apos;ll post another blog entry with the details soon, but in the meantime, if you haven&apos;t done so in a while, take down your copy of GOF, dust it off, and crack open to the first chapter.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>When Interviews Fail</title>
      <link>http://blogs.newardassociates.com/blog/2016/when-interviews-fail.html</link>
      <pubDate>Wed, 23 Mar 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/when-interviews-fail.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;tl;dr&lt;/em&gt; Peter Verhas asks a seemingly innocent question during a technical interview, and gets an answer that is not wrong, but doesn&apos;t really fit. He then claims that &amp;quot;Sometimes I also meet candidates who not only simply do not know the answer but give the wrong answer. To know something wrong is worse than not knowing. Out of these very few even insists and tries to explain how I should have interpreted their answer. That is already a personality problem and definitely a no-go in an interview.&amp;quot; I claim that Peter is not only wrong, but that in addition to doing his company a complete disservice with this kind of interview, I personally would never want to work for a company that takes this attitude.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Let&apos;s begin with his original article, &lt;a href=&quot;https://dzone.com/articles/can-you-call-non-static-method-from-a-static&quot;&gt;here&lt;/a&gt;. Go have a look before you read any further---it&apos;s actually not that long.&lt;/p&gt;
&lt;p&gt;Now, having familiarized yourself with the material, let&apos;s deconstruct it entirely, shall we?&lt;/p&gt;
&lt;h2&gt;Asking the wrong questions&lt;/h2&gt;
&lt;p&gt;For starters, the whole process begins, in my opinion, entirely on the wrong foot:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are questions on a Java technical interview that even the most entry level junior is expected to give the right answer for. Since I am facing candidates who are not that junior I do not even bother most of the times to ask those questions. I assume that the candidate knows the correct answer. Sometimes, however, there are some candidates who I feel from the start they are juniors and to cut the interview short not wasting his/her and my time I ask some of those simple questions. The answers usually reveal the real level of knowledge and we can get to an agreement in a short time about the assessed level.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It begins with the phrase &amp;quot;There are questions....&amp;quot;. Folks, let me be very clear about this: If you are conducting a technical interview, then you need to be asking them to write code, not answer questions. Unless their role in the position is to be a question-answerer of programming questions (in which case, you are interviewing for a teacher, not an actual programmer), then you need to be asking them to demonstrate their technical skills, not their knowledge of the terminology.&lt;/p&gt;
&lt;p&gt;The reasoning for this should be pretty clear, but in case it&apos;s not, I&apos;ll argue it from logic, example, and analogy.&lt;/p&gt;
&lt;p&gt;Logic: Not every programmer you interview will be classically-trained. They may not know all the preferred terminology. Are they &amp;quot;getters and setters&amp;quot;, or &amp;quot;automatically-defined properties&amp;quot;, or &amp;quot;accessors and mutators&amp;quot;? It really sort of depends on what language you grew up with (C++, for example, preferred the latter for quite some time). It depends on which books you read. It depends on whether you even had to discuss this with other people---perhaps the candidate actually learned everything from a book and reading stuff on the Internet. (StackOverflow&apos;s recent poll suggests that around a third or more of the developers in the candidate pool are self-identified &amp;quot;self-taught&amp;quot; developers.) Do you really want to be screening out perfectly-qualified candidates because they don&apos;t have the right words? And this doesn&apos;t even begin to address the pressure-cooker situation that most candidates feel they&apos;re in when they interview, causing them to flub even simple answers. Which brings me to...&lt;/p&gt;
&lt;p&gt;Example: A developer who worked for me for two years was a quite capable C# developer. This is a guy who led teams, mentored some of the more junior developers, and came up with some quite capable designs. And then, when asked during a meeting by a prospective client, to explain what a static method is, he flubbed it completely, and started talking about constructors and what-not. I sat there looking at him for a few minutes, with a total &amp;quot;Dude, WTF?!?&amp;quot; look on my face, before he realized what he was doing. By Peter&apos;s criteria, he&apos;d failed the interview. And yet, he served as the team lead for that client for nine months after that meeting, with nary a complaint about his skills, his abilities, or his answers on questions about static methods (which, ironically, never came up!) ever again. In other words, once we got out of the pressure cooker, he did fine, and his work showed it. Which brings us to...&lt;/p&gt;
&lt;p&gt;Analogy: If you&apos;re hiring a band to play your wedding, do you really care about their ability to explain musical theory and composition? Or do you care more about their ability to play your favorite dance tunes, to play the song that your spouse has chosen to be &amp;quot;your song&amp;quot;, and to get Grandma and Grandpa on to the dance floor with a rendition of &amp;quot;Funky Chicken&amp;quot;?  Most bands (dare I say all of them?) get a gig based on their body of work and/or their demo tape, not their ability to answer questions.&lt;/p&gt;
&lt;h2&gt;Expecting the wrong answers&lt;/h2&gt;
&lt;p&gt;Continuing, Peter says,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To know something wrong is worse than not knowing. Out of these very few even insists and tries to explain how I should have interpreted their answer. That is already a personality problem and definitely a no-go in an interview.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Oh, hubris, thy name is &amp;quot;programming interviewer&amp;quot;. Let&apos;s see what I mean:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One such simple question is: Can a static method in a class call a non-static method of the same class? If you know Java a little bit you know the answer: no, it can not. A static method belongs to the class and not the instance. It can even be executed using the name of the class directly without any instance of the class. It can even run when there is not even a single instance of the class in the whole JVM. How could it invoke a normal method that runs attached to an instance?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Oh, hubris. &lt;em&gt;There is no reason that a static method cannot invoke an instance method.&lt;/em&gt; The thing that Peter is hinging on here is the fact that the static method lacks a reference to a particular object (which normally is the &amp;quot;this&amp;quot; reference), which is his justification for his answer: &amp;quot;No &lt;em&gt;this&lt;/em&gt;, no method call&amp;quot;.&lt;/p&gt;
&lt;p&gt;And yet:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;But then again: the answer from one candidate this time was: yes. And he even started to explain that it may happen that the static method has access to an instance. It may get an instance as a method argument and through that reference, it can call an instance method. That person was right.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And yet:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It did not, however, change the fact that he did not know Java well enough, but as a matter of fact in this very specific question, she was right.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So let me get this straight: the answer to the question was right, when you&apos;ve said all along it was wrong, and yet &amp;quot;this candidate didn&apos;t know Java well enough&amp;quot;? I&apos;d say that the candidate understood Java well enough to be able to find an answer that was not the one you expected, and yet was actually correct.&lt;/p&gt;
&lt;p&gt;See, here&apos;s what&apos;s going on: the interviewer, convinced of their own technical superiority, is walking into an interview with a predetermiend set of answers to questions they&apos;re going to ask, and when a candidate doesn&apos;t follow that predetermined script, they&apos;re &amp;quot;not smart enough&amp;quot;.&lt;/p&gt;
&lt;p&gt;Here&apos;s a personal example. I was interviewing with a company years ago for a C++ position, and was asked, &amp;quot;Can a private field be accessed from outside of the class?&amp;quot; The normal candidate&apos;s answer is supposed to be &amp;quot;No, private creates an encapsulation barrier hiding the field from the rest of the world.&amp;quot;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c++&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;
using namespace std;

class Person
{
public:
  Person(const char* fn, const char* ln, int a)
    : first_name(fn), last_name(ln), age(a)
  { }
  
  string description() {
    return first_name + &amp;quot; &amp;quot; + last_name + &amp;quot; is &amp;quot; + to_string(age) + &amp;quot; years old&amp;quot;;
  }
private:
  string first_name;
  string last_name;
  int age;
};

int main() {
  Person ted(&amp;quot;Ted&amp;quot;, &amp;quot;Neward&amp;quot;, 45);
  cout &amp;lt;&amp;lt; ted.description() &amp;lt;&amp;lt; endl;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &amp;quot;age&amp;quot; field is, by design, unavailable to the rest of the world, right?&lt;/p&gt;
&lt;p&gt;My answer: &amp;quot;Of course it can. You just have to cast the object instance over to a void*, calculate the offset from the start of the object, and then access it.&amp;quot;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c++&quot;&gt;int main() {
  Person ted(&amp;quot;Ted&amp;quot;, &amp;quot;Neward&amp;quot;, 45);
  cout &amp;lt;&amp;lt; ted.description() &amp;lt;&amp;lt; endl;
  
  void* pTed = (void*)&amp;amp;ted;
  int offset = sizeof(string) + sizeof(string);
  char* pTedAge = (static_cast&amp;lt;char *&amp;gt;(pTed) + offset);
  cout &amp;lt;&amp;lt; static_cast&amp;lt;int&amp;gt;(*pTedAge) &amp;lt;&amp;lt; endl; // prints 45
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I even showed them how you could generalize this into a template (I called it &amp;quot;THackOMatic&amp;quot;, and consider it one of my finest creations in the language.)&lt;/p&gt;
&lt;p&gt;Now, you can take this one of three ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wow, never thought you could do that. That&apos;s interesting. I wonder...&lt;/li&gt;
&lt;li&gt;Well, yes, you can do this, but it&apos;s totally not a good idea.&lt;/li&gt;
&lt;li&gt;This is totally not in the spirit of the question. You are still wrong.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And If you&apos;re in the first two camps, I&apos;m kind of there with you. It&apos;s a cool hack, but it&apos;s a hack nevertheless, and hacks are usually a sign that you&apos;re doing something wrong, except in very narrow circumstances where there&apos;s simply no other way around it and you accept that you&apos;re the only one who will be touching that code from now on.&lt;/p&gt;
&lt;p&gt;But if you&apos;re in the third camp, you&apos;re missing the point. The point being, the candidate figured out a way around a supposed stumbling block in the language. If you can&apos;t recognize that, then I submit that the fault lies with you, not with the candidate.&lt;/p&gt;
&lt;p&gt;Which brings me to my last point.&lt;/p&gt;
&lt;h2&gt;You hire what you interview for&lt;/h2&gt;
&lt;p&gt;Right or wrong, the candidate took your question, thought their way through it, and came up with a novel answer to the question. And by focusing on the answer, you missed the important part--&lt;em&gt;they found a way around it&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Part of this process is supposed to be finding those candidates who meet a certain technical bar, but part of the process is also supposed to be finding those people who will find ways around obstacles. Bugs, production outages, design flaws, whatever, you&apos;re supposed to be finding the candidates who won&apos;t accept the status quo as a concrete law of the universe.&lt;/p&gt;
&lt;p&gt;A candidate did exactly that, and you shot them down.&lt;/p&gt;
&lt;p&gt;You wanted a plain vanilla, boring-as-shit, everybody-get-in-line-and-do-what-the-supervisor-tells-you kind of answer, and they gave out an &amp;quot;out of the box&amp;quot;, creative, hammer-throwing-at-the-screen one.&lt;/p&gt;
&lt;p&gt;Do you claim you hire &amp;quot;only the best&amp;quot;? When you&apos;re doing this, you&apos;re hiring only the middle part of the bell curve, at best. Those who are on the far right-hand-side of the curve will be the out-of-the-box thinkers, who understand that rules are made to be broken sometimes, and under specific circumstances.&lt;/p&gt;
&lt;p&gt;Do you really think they will &lt;em&gt;want&lt;/em&gt; to work for you at this point? I wouldn&apos;t.&lt;/p&gt;
&lt;h2&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;So my challenge here is this: If you&apos;re an interviewer, what are &lt;strong&gt;you&lt;/strong&gt; interviewing for?&lt;/p&gt;
&lt;p&gt;By the way, that company I interviewed at all those years ago? The interviewer&apos;s response was classic: &amp;quot;Well, the right answer was supposed to be &apos;no&apos;, but I can see what you&apos;re doing here. You&apos;re the first person to ever give me that as an answer.&amp;quot; They hired me shortly thereafter, and before I left the firm, I used a couple more language tricks to help cut the size of their codebase down pretty significantly in a couple of situations.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Hire the fired</title>
      <link>http://blogs.newardassociates.com/blog/2016/hire-the-fired.html</link>
      <pubDate>Wed, 24 Feb 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/hire-the-fired.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; A Forbes.com article Q/A recently stated that job-seekers need to hide the fact that they&apos;ve ever been fired from a position, because of the stigma associated with such an action. I couldn&apos;t disagree more.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;First off, as is common for my posts, &lt;a href=&quot;http://www.forbes.com/sites/lizryan/2016/12/06/if-youve-ever-been-fired-i-wont-hire-you&quot;&gt;read the original&lt;/a&gt;, so we all know what I&apos;m aruging against. But if you just want the short summary, a reader, &amp;quot;Madelyn&amp;quot;, writes to &amp;quot;Liz&amp;quot; (presumably the Forbes equivalent of a Dear Abbey or something), saying&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;You advise people to withhold the fact that they&apos;ve been fired and to make it sound like they left their last job on their own. How can you advise people to be so unprofessional? If someone got fired from a job, they need to say so and they need to explain it.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;quot;Madelyn&amp;quot; goes on:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Personally, I would never hire anyone who had been fired from a past job. ... Maybe some employers are okay with that, but I wouldn&apos;t take a chance on that person. If the person I hired had problems again, I would have to acknowledge that I knowingly hired someone who had already been fired once!&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Wow.&lt;/p&gt;
&lt;h2&gt;Why Madelyn is wrong&lt;/h2&gt;
&lt;p&gt;First of all, it&apos;s clear that &amp;quot;Madelyn&amp;quot; is making the fundamental assumption that being fired is a negative thing (a &amp;quot;black mark&amp;quot;) on your career history. I really don&apos;t agree---the assumption here is that you were fired &amp;quot;for cause&amp;quot;, meaning that your manager had a Really Good Reason to terminate you. While that sometimes might be true, that&apos;s hardly &lt;em&gt;always&lt;/em&gt; the case. Too many times, people are fired (terminated, separated, &amp;quot;let go&amp;quot;, or whatever other non-&amp;quot;fired&amp;quot; word HR cares to use) because of personality conflicts with their boss (which are not always the fault of the individual under consideration, that is to say, you), because of personality conflicts with their colleagues (which are not always the fault of the individual), or even because the company simply doesn&apos;t need that particular department or the excess capacity in that position (a la a merger or acquisition).&lt;/p&gt;
&lt;p&gt;Granted, much of the time, that latter scenario is called being &amp;quot;laid off&amp;quot;, and &amp;quot;Madelyn&amp;quot; allows for that as an out: &amp;quot;Maybe they get laid off, but that is a different scenario.&amp;quot; But let&apos;s be really clear about something---in a classic layoff, a company owes some form of severance pay, and most companies are quite loathe to pay that out, so they will simply terminate instead of &amp;quot;lay off&amp;quot;. Case in point: when I worked for Neudesic, I was terminated without severance because the company had taken a huge hit in the form of a client contract termination. There was no &amp;quot;cause&amp;quot;, &lt;em&gt;per se&lt;/em&gt;---they simply couldn&apos;t afford to keep me on given that they&apos;d taken this huge blow to their client portfolio. Should they have paid me severance? Probably, but it was likely a non-starter as a discussion point, and I didn&apos;t really feel like arguing with them about it.&lt;/p&gt;
&lt;p&gt;In the case that I think &amp;quot;Madelyn&amp;quot; is trying to use as her stalking horse, a company will fire an employee for making a mistake of some monumental proportions. In some scenarios, it&apos;s because an employee just keeps making the same mistakes over and over again. In this case, the termination is understandable, and justifiable. (Even then, that doesn&apos;t mean that the employee is entirely at risk--if they weren&apos;t trained, yet kept being tossed into the pool to drown over and over again, it&apos;s hard to blame the employee.)&lt;/p&gt;
&lt;p&gt;But in some scenarios, it&apos;s because an employee does something that the company doesn&apos;t want to be potentially liable for---the case of the fast food employee who chooses to give leftover food to homeless, for example, runs the risk of violating local FDA or health department rules. In order to avoid liability (or accountability) the company terminates that employee--even though in this case it&apos;s for doing something that most of us consider to be a good act--&amp;quot;with cause&amp;quot;, because it potentially could be termed &amp;quot;theft&amp;quot;. If you&apos;re that employee, this is really something to be ashamed of? This is really a reason not to hire a candidate---because they chose to act in accordance with a high moral standard (and didn&apos;t realize that doing so was creating problems)?&lt;/p&gt;
&lt;h2&gt;Why it shouldn&apos;t matter&lt;/h2&gt;
&lt;p&gt;But perhaps even more to the point, even if the company calls your previous employer to verify your employment, typically your employer will say nothing more than &amp;quot;He/she worked here from this date to that date&amp;quot; and hang up the phone. They won&apos;t say more than this in order to avoid any sort of legal liability. In fact, most employers of any size will &lt;em&gt;demand&lt;/em&gt; that any reference check go to their HR department, who will then verify the dates, and if asked a reason, choose not to disclose the reasons for the end of the engagment. (Granted, I suppose it&apos;s always possible that your manager could choose to say something &amp;quot;off the record&amp;quot;, but such things have a nasty way of somehow making it onto the record, which then leaves the company vulnerable to legal liability again; for that reason, most managers are taught pretty strictly not to say anything.)&lt;/p&gt;
&lt;p&gt;Which then brings up the point: Why on earth would &lt;em&gt;you&lt;/em&gt; bother telling them?&lt;/p&gt;
&lt;p&gt;Seriously, beyond the bare facts of your employment history, you need not disclose facts about your employment past: your manager&apos;s name, your colleagues&apos; names, your relationship with either employers or colleagues, your previous hits or misses, your previous salary or benefits, none of it is the interviewing manager&apos;s business! They of course may ask, but you are under no legal obligation (that I&apos;m aware of, anyway) to disclose any of it.&lt;/p&gt;
&lt;p&gt;And, given &amp;quot;Madelyn&amp;quot;&apos;s rather medieval opinion on how to judge people, I think it&apos;s in your best interests not to volunteer anything. After all, the interviewer is expecting you to come into the position with a &amp;quot;clean slate&amp;quot;, and not hold any of your previous managers&apos; mistakes against the company---shouldn&apos;t you be granted the same &amp;quot;clean slate&amp;quot; in turn?&lt;/p&gt;
&lt;h2&gt;Why you should hire the fired&lt;/h2&gt;
&lt;p&gt;Most of all, though, those who have been fired have something valuable that their new employer could really use: experience. It is an old adage that says, &amp;quot;Good decisions come from experience; experience comes from bad decisions.&amp;quot; For most people, being fired is not a positive thing, and they will replay the event over and over in their head, looking to learn from it. Personally, I would want the benefit of that experience. What did they learn from it? What can they bring to this position from that prior situation that we can learn from?&lt;/p&gt;
&lt;p&gt;If you ever interview with me, let me make it clear: You need not tell me why you were released from that position. (If I forget, and ask that question, you may remind me that you are under no obligation to tell me; quite frankly, you &lt;em&gt;should&lt;/em&gt; remind me.) If you choose to tell me that you were fired, I&apos;ll of course be interested to know what you learned from the experience, and how we can apply it to here.&lt;/p&gt;
&lt;p&gt;But, of course, I may ask you the &amp;quot;what did you learn&amp;quot; question anyway, regardless of whether you were ever fired. Because, again, how you left your last position really shouldn&apos;t matter a damn.&lt;/p&gt;
&lt;h2&gt;&amp;quot;Liz&amp;quot;&apos;s response&lt;/h2&gt;
&lt;p&gt;... is great. (Yes, she agrees with me.) Some excerpts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;I definitely advise job-seekers to steer clear of managers who have firm and unshakable stereotypes in their heads, including &amp;quot;Never hire someone who&apos;s been fired from a job! Such managers are not typically people who can inspire others to greatness.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Sometimes speaking up or bucking the status quo gets amazing people fired from their jobs.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;You can decide you don&apos;t want to hire people who are too outspoken, creative or non-linear for your taste. That is your privilege.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Getting fired is simply waiting an instant too long to say &apos;I quit.&apos;&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Never tell your prospective employer why you left. Because, again, how you left shouldn&apos;t really matter a damn to anyone.&lt;/p&gt;
&lt;h2&gt;2022 Edit: Caveat&lt;/h2&gt;
&lt;p&gt;If you were fired for reasons stemming from criminal violations and/or imprisonable offenses that required arrest and/or incarceration, you &lt;em&gt;are&lt;/em&gt; (I believe) under legal requirement to disclose that on your employment application. If you&apos;re one of those people and you&apos;re reading this blog, chances are pretty good you&apos;ve paid your debt to society and are looking for the clean slate. I, personally, think you are owed the chance to start over, but many big companies have different policies on that. I think your best bet is to identify those companies that have a heart and are willing to give you that chance--but, as I&apos;m sure you&apos;re aware, that is really going to be a hit-or-miss proposition. If you&apos;re interviewing with me, I&apos;ll do what I can, but my hands are likely to be tied by HR policy in that case.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>On Apple and encryption</title>
      <link>http://blogs.newardassociates.com/blog/2016/on-apple-and-encryption.html</link>
      <pubDate>Wed, 17 Feb 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/on-apple-and-encryption.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; By now, everybody has heard that the FBI has issued a request (which is now being backed by a court order to comply) to Apple to provide software to unlock the iPhone 5c of one of the San Bernardino shooters. This is a massive request, with huge implications for everybody (Apple, Americans, foreigners, I really mean everybody). And most of those implications, I believe, are bad.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;First of all, let&apos;s get some basic facts in place:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;a href=&quot;https://en.wikipedia.org/wiki/2015_San_Bernardino_attack&quot;&gt;San Bernardino shooters&lt;/a&gt; killed 14 people and seriously injured 22. However, &amp;quot;They were not directed by [foreign terrorist] groups and were not part of any terrorist cell or network.&amp;quot;&lt;/li&gt;
&lt;li&gt;The FBI obtained an iPhone belonging to one of the shooters. Because it was locked (like so many of us do), the FBI issued a request for technical assistance to unlock the phone.&lt;/li&gt;
&lt;li&gt;Apple has refused, and &lt;a href=&quot;http://www.apple.com/customer-letter/&quot;&gt;issued a statement why&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A federal court judge has &lt;a href=&quot;https://assets.documentcloud.org/documents/2714001/SB-Shooter-Order-Compelling-Apple-Asst-iPhone.pdf&quot;&gt;issued a court order&lt;/a&gt; demanding Apple&apos;s compliance with the FBI&apos;s request.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Whether Apple will comply with the court order remains to be seen. (&lt;strong&gt;UPDATE 2021:&lt;/strong&gt; From all available evidence, they did not.)&lt;/p&gt;
&lt;p&gt;I find myself a whole mess of different thoughts and reactions, and I&apos;m just going to lay all this out in no particular order. Naturally, the disclaimer &amp;quot;I am not a lwyer&amp;quot; applies to all of this, and I&apos;d &lt;em&gt;love&lt;/em&gt; for those with training in the law and having passed the bar exam to weigh in with their expert opinion.&lt;/p&gt;
&lt;h2&gt;Legal issues&lt;/h2&gt;
&lt;p&gt;Let&apos;s start with the legal stuff.&lt;/p&gt;
&lt;h4&gt;Why does the FBI need this?&lt;/h4&gt;
&lt;p&gt;I&apos;m confused. If the FBI issued a statement saying that they do not believe these people were part of an established foreign terror group or network, then what does the phone give them? In fact, what does the phone give them, period? Certainly there&apos;s the possibility that there&apos;s some kind of Twitter history (their favorites) or Facebook saved pages, but in both of those cases, they could go to the respective social media companies and get the information there. Even a history of SMS messages and phone log could be pulled from Verizon (the shooter&apos;s carrier).&lt;/p&gt;
&lt;p&gt;I simply don&apos;t understand what information the FBI expects to remove from the phone that they couldn&apos;t get elsewhere. There&apos;s only two scenarios I can imagine that require this step:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;there is something stored locally to the device that isn&apos;t stored in the cloud, or&lt;/li&gt;
&lt;li&gt;if there is information stored to the cloud that they cannot access, probably because the cloud provider in question is not subject to US legal injunction/demands.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Suddenly, the whole &lt;a href=&quot;https://en.wikipedia.org/wiki/International_Safe_Harbor_Privacy_Principles&quot;&gt;&amp;quot;Safe Harbor&amp;quot;&lt;/a&gt; argument of a few months ago takes on a wholly new light. For those who weren&apos;t following the crisis/discussion then, the US government&apos;s willingness to demand companies surrender consumer information, in violation of EU Data Protection Directives, caused the EU to declare that the US was no longer a &amp;quot;safe harbor&amp;quot; for its data, and therefore not a safe place to store EU consumer data.&lt;/p&gt;
&lt;p&gt;This is a perfect case where this can come into play---if the shooters&apos; phone was using a system that stores its data in data centers on European soil, the US government has no jurisdiction over those servers, and therefore cannot strong-arm the company into complying with an order to surrender that data. &lt;em&gt;This is exactly why the EU was concerned.&lt;/em&gt; And, apparenty, with good reason.&lt;/p&gt;
&lt;p&gt;You can argue that in this case, the US should have the right to be able to demand that data. After all, this is not only a criminal investigation, but an investigation that could potentially have international implications. This is not unusual, nor new. Which leads me to my next thought....&lt;/p&gt;
&lt;h4&gt;Why isn&apos;t a warrant sufficient?&lt;/h4&gt;
&lt;p&gt;Normally, when the police want to obtain data about an individual (living or dead) held by a third party, they must obtain a warrant from a judge, ensuring that the request is a legal one and within the boundaries of jurisprudence. We see this all the time in legal discussions and on TV shows (for crying out loud). But there&apos;s no discussion of any warrant being issued in this particular case, nor of Apple being given an opportunity to challenge the legality of the warrant, which leads me to wonder, was no warrant issued, and if so, why not?&lt;/p&gt;
&lt;h4&gt;The device was actually owned by the county&lt;/h4&gt;
&lt;p&gt;This story takes on a slightly different twist because the device apparently wasn&apos;t owned by the shooters themselves, but by the county (for whom they worked, apparently?). Thus, the legal steps necessary to obtain the right legal framework by which to obtain the data was easily navigated---the FBI asked, the county granted.&lt;/p&gt;
&lt;p&gt;This raises some interesting lessons for IT departments around the use of mobile devices, as well as for those who use mobile devices as part of their work day:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Never mix personal and professional on one device.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Look, I know it&apos;s really nice to be able to get your email on your phone, but there&apos;s all kinds of weird legal gray areas that come into play when you do so. Does the company have the right to wipe your phone remotely in the event that you lose it? Will the company pay you to replace the phone if some software they have you install on it somehow bricks the device? Will you be liable for violations of company privacy if your phone is lost with company email on it? (And the answer to that last one is a resounding yes, by the way.)&lt;/p&gt;
&lt;p&gt;But if you&apos;re an IT department, you have to worry about all of these things and more, because now, technically, if you allow a BYOD (&amp;quot;Bring Your Own Device&amp;quot;) policy, and you can&apos;t get on the device (such as is the case here), you&apos;re in for a world of PR nightmares at a minimum, and outright legal problems in the more common case. IT departments are, by definition, responsible for the data that resides on their systems, and if systems include the hardware on which the software resides, if it&apos;s not something the company owns or has access to, you are basically walking a very ugly line.&lt;/p&gt;
&lt;p&gt;If you&apos;re a CTO or VP of IT, you need to be rethinking and re-examining your mobile policy, &lt;em&gt;right now&lt;/em&gt;. If you want employees to be able to use mobile devices as part of their job, provide them (and have a very straightforward and strict policy regarding what software can be installed and what networks can be accessed in place). If you have employees using personal mobile devices as part of their day job, make sure you have a memo of understanding in place that lists the specific conditions you (the company) demand their agreement on in order to do so. If you don&apos;t have that memo of understanding, sock away a little extra from the profit line into a savings account marked &amp;quot;Legal Fund&amp;quot;, because you&apos;ll need it someday, I guarantee it.&lt;/p&gt;
&lt;h4&gt;Apple&apos;s customer note covers more than just this one case&lt;/h4&gt;
&lt;p&gt;Apple notes (correctly) that&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[Your] information needs to be protected from hackers and criminals who want to access it, steal it, and use it without our knowledge or permission.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is, I think, without argument.&lt;/p&gt;
&lt;p&gt;What they are not saying, and should, is that the government needs to be included in that collection of parties from which our information is protected. This is a fundamental right of any US citizen, and arguably anyone in the world. &amp;quot;Innocent until proven guilty&amp;quot; and all that.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Compromising the security of our personal information can ultimately put our personal safety at risk.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is also absolutely true, for some more directly than others. Ask any of the battered women whose husbands are under court orders, ask anyone in Witness Protection, but more importantly, ask any woman who has ever had a stalker. But it doesn&apos;t even have to be that exotic---look at your browser history, the bank application on your phone, your email, your Facebook message history, and so on. There&apos;s so much information on these devices that losing one is not just a hassle, in some cases, it&apos;s downright life-paralyzing.&lt;/p&gt;
&lt;p&gt;The same spirit that keeps the US government off of our phone lines (without a warrant), out of our personal mail (without a warrant) and out of our homes (without a warrant) needs to keep them out of our phones (without a warrant).&lt;/p&gt;
&lt;h4&gt;European and other visitors could have their privacy waived&lt;/h4&gt;
&lt;p&gt;Let&apos;s be clear: If the US wins this case, it means that any foreign national traveling in the US would be subject to the same kind of intrusion, regardless of what their government thinks and regardless of where their data is stored. And the various governments that govern those citizens would be really, really pissed off about that. This feels like an escalation of the Safe Harbor incident from last year, and I imagine that other governments would feel much the same---but this is so new that I doubt they&apos;ve had time to formulate a response. Expect to see those statements and responses come in the months to come if this goes through.&lt;/p&gt;
&lt;h4&gt;Apple complying with this one case sets precedent&lt;/h4&gt;
&lt;p&gt;Suppose that, in the face of everything, Apple agrees to do this for this one case. Can you possibly imagine how many requests they will receive from every police department all over the country seeking their technical assistance in doing so for iPhones removed from arrested suspects for everything ranging from burglary to financial malfeasance? It would be a huge nightmare for them.&lt;/p&gt;
&lt;p&gt;On top of that, you can well imagine that Google, Microsoft, Samsung and other manufacturers are watching this whole thing with very keen interest, because if the government can compel Apple to do this, it opens the doors to demanding it of any hardware manufacturer within the US. And none of them want any part of this any more than Apple does.&lt;/p&gt;
&lt;h4&gt;Apple complying with this one case hurts them&lt;/h4&gt;
&lt;p&gt;&amp;quot;Hi, I&apos;m a Mac. (And I&apos;m a PC.) Hey, PC, can you secure your data against government intrusion? (Yup.) Oh.&amp;quot;&lt;/p&gt;
&lt;p&gt;Android devices, particularly those manufactured overseas, would suddenly become a really hot commodity. Apple simply cannot be seen to back down on this, or they will get crucified in the extremely hot shooting war of words that they have with their competitors, Samsung in particular. This could cost them millions, if not billions, in sales. While the various &amp;quot;patriots&amp;quot; will claim that this is somehow just the price of freedom, I don&apos;t see the US government stepping up to provide adequate compensation in the event that this is the case.&lt;/p&gt;
&lt;h2&gt;Technical feasibility&lt;/h2&gt;
&lt;p&gt;Here&apos;s where we get technical. Bear in mind, I write iOS apps, and I teach writing iOS apps to a variety of people, but I&apos;ve never worked for Apple, have no access to any insider information or source code, and have never actually tried to hack an iOS device, so I may be missing some details here.&lt;/p&gt;
&lt;p&gt;As noted &lt;a href=&quot;http://blog.trailofbits.com/2016/02/17/apple-can-comply-with-the-fbi-court-order/&quot;&gt;here&lt;/a&gt;, there&apos;s three things that stand in the way of the FBI (or any other attacker) bypassing the lock screen on an iPhone to obtain access:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;iOS may completely wipe the user’s data after too many incorrect PINs entries&lt;/li&gt;
&lt;li&gt;PINs must be entered by hand on the physical device, one at a time&lt;/li&gt;
&lt;li&gt;iOS introduces a delay after every incorrect PIN entry&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;(By the way, the relevant &lt;a href=&quot;https://www.apple.com/business/docs/iOS_Security_Guide.pdf&quot;&gt;iOS security documentation&lt;/a&gt; describes all of this in much greater detail. I will periodically refer back to this document as we go.)&lt;/p&gt;
&lt;p&gt;Thus, according to the court order, the FBI requested Apple to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;... bypass or disable the auto-erase function whether or not it has been enabled;&lt;/li&gt;
&lt;li&gt;... enable the FBI to submit passcodes to the SUBJECT DEVICE for testing electronically via the physical device port, Bluetooth, Wi-Fi, or other protocol available on the SUBJECT DEVICE; and&lt;/li&gt;
&lt;li&gt;... ensure that when the FBI submits passcodes to the SUBJECT DEVICE, software running on the device will not purposefully introduce any additional delay between passcode attempts beyond what is incurred by Apple hardware.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let&apos;s take these one at a time.&lt;/p&gt;
&lt;p&gt;Bypassing the auto-erase function may or may not be feasible, depending on how it&apos;s implemented. If it&apos;s an API call that Apple invokes under certain conditions, then whatever this &amp;quot;bypass&amp;quot; is either has to prevent that condition (&amp;quot;&lt;em&gt;n&lt;/em&gt; failed login attempts&amp;quot;) from ever being triggered, or it has to somehow replace the code that does the erasing with something more benign. Depending on where and how the device OS code is stored, this can either be trivial or require a custom set of ROMs be plugged in to the device.&lt;/p&gt;
&lt;p&gt;Tapping the PINs on the device screen is the pain, and the FBI sought a way around that by asking that the device accept passcodes via &amp;quot;device port, Bluetooth, Wi-Fi, or other protocol available&amp;quot;. In other words, by any means supported by the device for input. Doing so through the device port requires the device be in the hands of the attacker/FBI, but Bluetooth and Wi-Fi are both wireless protocols---this could be done remotely from a distance.&lt;/p&gt;
&lt;p&gt;&amp;quot;Not purposefully introduce any additional delay between passcode attempts&amp;quot; refers to the delay that iOS deliberately puts in, as described in the Security Guide (p12):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;To further discourage brute-force passcode attacks, there are escalating time delays after the entry of an invalid passcode at the Lock screen.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That same paragraph is where Apple describes the setting to wipe the phone in the event of too many failed login attempts:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If Settings &amp;gt; Touch ID &amp;amp; Passcode &amp;gt; Erase Data is turned on, the device will automatically wipe after 10 consecutive incorrect attempts to enter the passcode.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So again, this basically says that the cracking tool would have to somehow either prevent the conditions (tracking the number of failed logins) or replace the code that wipes the device.&lt;/p&gt;
&lt;p&gt;Could this be done? Potentially, if the device were &amp;quot;flashed&amp;quot; with a new, hacked, operating system:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[Provide] the FBI with a signed iPhone Software file, recovery bundle, or other Software Image File (“SIF”) that can be loaded onto the SUBJECT DEVICE. The SIF will load and run from Random Access Memory (“RAM”) and will not modify the iOS on the actual phone, the user data partition or system partition on the device’s flash memory.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is not rocket science. A SIF is what gets loaded onto your phone every time you do an update of the phone.&lt;/p&gt;
&lt;p&gt;Now, if this were the end of the paragraph, Apple&apos;s concerns about this somehow becoming a &amp;quot;master key&amp;quot; for all iOS devices becomes a huge issue:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;They have asked us to build a backdoor to the iPhone. ...&lt;/p&gt;
&lt;p&gt;Specifically, the FBI wants us to make a new version of the iPhone operating system, circumventing several important security features, and install it on an iPhone recovered during the investigation. In the wrong hands, this software — which does not exist today — would have the potential to unlock any iPhone in someone’s physical possession.&lt;/p&gt;
&lt;p&gt;The FBI may use different words to describe this tool, but make no mistake: Building a version of iOS that bypasses security in this way would undeniably create a backdoor. And while the government may argue that its use would be limited to this case, there is no way to guarantee such control.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The court order does try, at least on the surface, to make sure this doesn&apos;t become the &amp;quot;master key&amp;quot; for all devices that Apple warns against:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The SIF will be coded by Apple with a unique identifier of the phone so that the SIF would only load and execute on the SUBJECT DEVICE.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But Apple points out:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Some would argue that building a backdoor for just one iPhone is a simple, clean-cut solution. But it ignores both the basics of digital security and the significance of what the government is demanding in this case.&lt;/p&gt;
&lt;p&gt;In today’s digital world, the “key” to an encrypted system is a piece of information that unlocks the data, and it is only as secure as the protections around it. Once the information is known, or a way to bypass the code is revealed, the encryption can be defeated by anyone with that knowledge.&lt;/p&gt;
&lt;p&gt;The government suggests this tool could only be used once, on one phone. But that’s simply not true. Once created, the technique could be used over and over again, on any number of devices. In the physical world, it would be the equivalent of a master key, capable of opening hundreds of millions of locks — from restaurants and banks to stores and homes. No reasonable person would find that acceptable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here&apos;s what is under discussion, again from the Security Guide. First of all, as described on p6/7, each device has a &amp;quot;unique device ID&amp;quot; (ECID) and, in a particular chip on the device called the Secure Enclave, a &amp;quot;unique ID&amp;quot; (UID). These are then used as part of the encryption process to secure various things on the device, including files (which we&apos;ll talk about later). More importantly, these aren&apos;t values that can be picked up from casual use of the device (p10, my emphasis):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Every iOS device has a dedicated AES 256 crypto engine built into the DMA path between the flash storage and main system memory, making file encryption highly efficient.&lt;/p&gt;
&lt;p&gt;The device’s unique ID (UID) and a device group ID (GID) are AES 256-bit keys fused (UID) or compiled (GID) into the application processor and Secure Enclave during manufacturing. &lt;strong&gt;&lt;em&gt;No software or firmware can read them directly&lt;/em&gt;&lt;/strong&gt;; they can see only the results of encryption or decryption operations performed by dedicated AES engines implemented in silicon using the UID or GID as a key. Additionally, the Secure Enclave’s UID and GID can only be used by the AES engine dedicated to the Secure Enclave. The UIDs are unique to each device and are not recorded by Apple or any of its suppliers. The GIDs are common to all processors in a class of devices (for example, all devices using the Apple A8 processor), and are used for non security-critical tasks such as when delivering system software during installation and restore. &lt;strong&gt;&lt;em&gt;Integrating these keys into the silicon helps prevent them from being tampered with or bypassed, or accessed outside the AES engine.&lt;/em&gt;&lt;/strong&gt; The UIDs and GIDs are also not available via JTAG or other debugging interfaces.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The UID allows data to be cryptographically tied to a particular device.&lt;/em&gt;&lt;/strong&gt; For example, the key hierarchy protecting the file system includes the UID, so if the memory chips are physically moved from one device to another, the files are inaccessible. The UID is not related to any other identifier on the device.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In other words, the UID being used as keys into AES means that we are now talking about the strength of encryption algorithms somehow being broken without having the key. (For those of you who aren&apos;t crypto-savvy, this is basically the whole point of a crypto algorithm: to prevent enciphered text being reversed to plaintext without the use of the key used to encipher it.)&lt;/p&gt;
&lt;p&gt;Note that the Security Guide points out that these keys are used as part of file encryption (p11):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In addition to the hardware encryption features built into iOS devices, Apple uses a technology called Data Protection to further protect data stored in flash memory on the device. Data Protection allows the device to respond to common events such as incoming phone calls, but also enables a high level of encryption for user data. Key system apps, such as Messages, Mail, Calendar, Contacts, Photos, and Health data values use Data Protection by default, and third-party apps installed on iOS 7 or later receive this protection automatically. Data Protection is implemented by constructing and managing a hierarchy of keys, and builds on the hardware encryption technologies built into each iOS device. Data Protection is controlled on a per-file basis by assigning each file to a class; accessibility is determined by whether the class keys have been unlocked.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And goes on (p12):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Every time a file on the data partition is created, Data Protection creates a new 256-bit key (the “per-file” key) and gives it to the hardware AES engine, which uses the key to encrypt the file as it is written to flash memory using AES CBC mode.&lt;/p&gt;
&lt;p&gt;... The per-file key is wrapped with one of several class keys, depending on the circumstances under which the file should be accessible. Like all other wrappings, this is performed using NIST AES key wrapping, per RFC 3394. The wrapped per-file key is stored in the file’s metadata.&lt;/p&gt;
&lt;p&gt;When a file is opened, its metadata is decrypted with the file system key, revealing the wrapped per-file key and a notation on which class protects it. The per-file key is unwrapped with the class key, then supplied to the hardware AES engine, which decrypts the file as it is read from flash memory. All wrapped file key handling occurs in the Secure Enclave; the file key is never directly exposed to the application processor.&lt;/p&gt;
&lt;p&gt;... The content of a file is encrypted with a per-file key, which is wrapped with a class key and stored in a file’s metadata, which is in turn encrypted with the file system key. The class key is protected with the hardware UID and, for some classes, the user’s passcode.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In other words:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You have to have the per-file key in order to read the file. This is stored in metadata.&lt;/li&gt;
&lt;li&gt;You have to have the file system key in order to read the metadata.&lt;/li&gt;
&lt;li&gt;The file system key is derived from the UID and the user&apos;s passcode.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What this means, then, is that Apple, in order to comply with the FBI&apos;s order, must figure out a way to defeat all this key-based encryption. Since it lacks the keys in question, it would be discovering a way to bypass or defeat AES encryption. Doing that would essentially invaldiate AES for use across all applications, and considering that banks and other high-security folks use AES largely because it hasn&apos;t been broken, doing so (if it&apos;s even technically feasible, and right now most cryptanalysts don&apos;t believe it is, or we wouldn&apos;t be using it) would send a shock wave of enormous proportions across the entirety of the online world.&lt;/p&gt;
&lt;p&gt;And no, that couldn&apos;t be limited to just one device.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;Frankly, the idea that Apple could somehow be compelled to do this is a disturbing one to me. It raises all kinds of bad precedents for other companies, it weakens consumer privacy protection, and frankly it&apos;s not clear to me why the FBI wants or needs this information in the first place.&lt;/p&gt;
&lt;p&gt;This story is not done. Not for a single moment. I will be watching this with some interest, and no small amount of concern.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Parse shutdown lessons</title>
      <link>http://blogs.newardassociates.com/blog/2016/parse-shutdown-lessons.html</link>
      <pubDate>Sat, 30 Jan 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/parse-shutdown-lessons.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Facebook/Parse announced that they are &lt;a href=&quot;http://blog.parse.com/announcements/moving-on/&quot;&gt;shutting down the popular Back-end-as-a-Service&lt;/a&gt;. While opinions are certainly going to vary as to why, I thought it an interesting situation to examine and, upon reflection, comment.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;As I read the post, a couple of things immediately came to mind:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;That&apos;s a very restrained blog post.&amp;quot;&lt;/em&gt;&lt;/strong&gt; Seriously, it says more by what it doesn&apos;t say than what it actually does say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;We have a difficult announcement to make. Beginning today we’re winding down the Parse service, and Parse will be fully retired after a year-long period ending on January 28, 2017. We’re proud that we’ve been able to help so many of you build great mobile apps, but we need to focus our resources elsewhere.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Quite honestly, this has all the sentiment and emotion of a &amp;quot;Dear John&amp;quot; letter. &amp;quot;We understand that this is difficult, but really, it&apos;s not you, it&apos;s me. Please try to move on with your life and in time, you will find that it&apos;s better this way for all of us.&amp;quot; The only real explanation given is that &amp;quot;we need to focus our resources elsewhere.&amp;quot;&lt;/p&gt;
&lt;p&gt;Facebook is how big, and somehow they can&apos;t keep the Parse team focused on doing what they were doing? Sorry, no, I don&apos;t believe it. This isn&apos;t about needing to re-route critical resources (people? servers? office desks?) to other parts of the company, not by a long shot.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The Parse acquisition was always a weird one, to me.&lt;/em&gt;&lt;/strong&gt; Quite frankly, I couldn&apos;t really figure out what Facebook wanted with Parse in the first place. Facebook is not really a developer-facing company, when you get right down to it. Yes, they&apos;re a software comapny, and yes, they&apos;ve recently been tossing some interesting open-source projects out the door---but Facebook, unlike Microsoft, Amazon, or Google, doesn&apos;t really have a business model that incorporates developers at the core. They make money off of people who use Facebook, and buy things from ads displayed in Facebook, and towards that end Facebook certainly wants developers to build applications that make use of Facebook, but Parse really didn&apos;t do any of those things.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The Parse guys had to know this was a possibility.&lt;/em&gt;&lt;/strong&gt; Frankly, it&apos;s always a possibility when there&apos;s a buyout---the acquiring company either changes their strategy, their opinion, or finally reveals that their main goal was to (a) remove you from the playing field, or (b) redirect your &amp;quot;assets&amp;quot; (which usually means the people working for you) to other parts of the company. Sure, it was all wonderfully believable that Facebook admired the plucky startup and wanted to see them continue to support other plucky startups. Also listed in the wonderfully believable category: Santa Claus, the Free-Market Fairy, and the idea that Bill Cosby is just misunderstood.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The companies that bet on Parse on their back end must have mixed feelings right now.&lt;/em&gt;&lt;/strong&gt; To be sure, the Parse guys are bending over backwards to try and make this a smooth transition: not only are they providing a &lt;a href=&quot;http://blog.parse.com/announcements/introducing-parse-server-and-the-database-migration-tool/&quot;&gt;database migration tool&lt;/a&gt;, but they&apos;ve also open-sourced a &lt;a href=&quot;http://blog.parse.com/announcements/introducing-parse-server-and-the-database-migration-tool/&quot;&gt;Parse Server&lt;/a&gt; implementation, which (on the surface, anyway) claims to be API-compatible with the original Parse Server. So, sure, there&apos;s a migration strategy in place, and they&apos;ve given basically a years&apos; notice to people, to give them plenty of time to bail out. But right now, every Parse naysayer is standing up in the conference room and shouting, &amp;quot;SEE?!? I TOLD YOU SO!!&amp;quot;, even if their main objections to Parse were along a completely different axis. Meanwhile, every company that was considering any kind of cloud system is probably having something of a re-think, because if it can happen to Parse, why can&apos;t it happen to Azure, Google Cloud Platform, Bluemix, and so on?&lt;/p&gt;
&lt;p&gt;(And for the record, it&apos;s a stupid comparison, but it does, I think, highlight the difference between betting on a company that provides the cloud hosting directly---a la the people who own the hardware and the dirt it rests on---and those companies that use said hosting to provide some kind of value-add on top of it, which of course includes all the various &amp;quot;aaS&amp;quot; members like Heroku, Mongolab, and a whole gaggle of others. Azure, AWS and Google Cloud are not going away; the massive investment in the physical infrastructure alone means that those companies are in it for the long haul. Anything else, though, I can&apos;t say with absolute certainty---&amp;quot;easy up&amp;quot; can just as quickly become &amp;quot;easy down&amp;quot; when the investment doesn&apos;t seem to be paying off the way upper management thought it should.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The OSS &amp;quot;cloud standards&amp;quot; guys are going to become very annoying, very quickly.&lt;/em&gt;&lt;/strong&gt; In the same vein as the Parse naysayer, every OSS project that tries to hide the underlying cloud platform differences away from the developer is going to be using this as the perfect reason/example for why you should work against their &amp;quot;cloud-standard API&amp;quot; and not trust the actual cloud provider itself. It&apos;s the Java &amp;quot;Write Once Run Anywhere&amp;quot; argument all over again, and frankly, I think it&apos;s a tired old retread that really just needs to die. Write Once, Cloud Anywhere is never going to yield the kind of benefits that its proponents hold up, if you ask me, in the same way that Write Once, Run Anywhere didn&apos;t---it won&apos;t be any one large reason that shuts it down, but a whole host of little pinpricks that ultimately just lead the developer to say, &amp;quot;Ah, screw it&amp;quot; and just work against their cloud provider of choice directly. Yes, in the event that a cloud provider does end up shutting down, a rewrite will be necessary---but the JDBC API argued the exact same thing against the case when you had to change databases mid-stream during development, and in fifteen years of talking to people about JDBC, not to mention all the JDBC-based projects I was part of personally, I never found one project where that actually happened.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;My UW students are going to be very sad.&lt;/em&gt;&lt;/strong&gt; Each quarter that I&apos;ve taught mobile development at UW, I&apos;ve had the students spend three or so weeks on a final project to show off their skills. Most of those projects have required some kind of back-end service for data storage and retrieval, and by far and away the most popular service of choice has been Parse. It&apos;ll be interesting to see what they choose to use once Parse finishes shutting down.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;This is going to ripple through the BaaS market.&lt;/em&gt;&lt;/strong&gt; There&apos;s a number of BaaS offerings available, and Parse shutting down means that (a) all those soon-to-be-ex-Parse customers are going to be looking for a new hosting home, (b) all current and future BaaS customers are going to be looking a LOT more carefully at the terms of service and, particularly, looking for language around what they can expect if the service shuts down, and (c) a new surge in &amp;quot;cloud vs private cloud&amp;quot; articles are about to hit the Internet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;I wonder how long before a Parse look-alike spins up.&lt;/em&gt;&lt;/strong&gt; In many ways, Parse wasn&apos;t just about the API that they offered, but the fairly quick-and-easy ability to stand up a server/service and store data/user information/etc to it. Given that now the data storage component (MongoDB, for all practical intents and purposes) and the server API component (the aforementioned Parse Server) are now entirely in the open-source domain, how long will it take somebody with cloud space to spare to spin up a &amp;quot;Parse-like&amp;quot; service and offer it as an alternative to those customers who don&apos;t really want (or can&apos;t?) host the service themselves?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;I wonder how long it will take Google, Amazon, Microsoft and any other cloud provider to jump all over this.&lt;/em&gt;&lt;/strong&gt; Seriously, if I&apos;m running the Microsoft Azure team, I&apos;m telling somebody in my organization to start working on a &amp;quot;How to Transition from Parse to Azure Mobile Services&amp;quot; as of yesterday. Ditto for every other cloud provider on the planet. (And if it takes your team too long to put said guidance out the door, perhaps you need to rethink your mobile back-end offerings.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;I wonder how many Parse employees are going to survive the purge.&lt;/em&gt;&lt;/strong&gt; If the Parse service as we&apos;ve always known it is shutting down, then there&apos;s likely no longer a need for many of the people who worked at Parse.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;I wonder how Google is going to reassure the Firebase team.&lt;/em&gt;&lt;/strong&gt; &lt;a href=&quot;https://www.firebase.com/&quot;&gt;Firebase&lt;/a&gt; is, without a doubt, one of the more interesting BaaS providers out there, and Google acquired them around the same time that Parse was acquired by Facebook. If I&apos;m on the Firebase team, I&apos;m probably a little nervous that somebody at Google is thinking the same thing (whatever that was) as the Facebook folks, and I&apos;m wondering if my job is safe. (And just to be clear, I think shutting down Firebase would be a Really Bad Idea(tm), for a whole slew of different reasons.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;I kinda wish I&apos;d gotten around to making an app with Parse before now.&lt;/em&gt;&lt;/strong&gt; You know, just to be able to say, &amp;quot;I was there when Parse was still a thing.&amp;quot; Because, you know, hipster.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;I wonder how much money the Parse founders made.&lt;/em&gt;&lt;/strong&gt; I imagine this isn&apos;t how they imagined their service coming to an end, but having millions in the bank probably helps offset the &amp;quot;sting&amp;quot; of having to write that &amp;quot;Dear John Customer&amp;quot; email above.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>How do you learn?</title>
      <link>http://blogs.newardassociates.com/blog/2016/how-do-you-learn.html</link>
      <pubDate>Sun, 24 Jan 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/how-do-you-learn.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; I&apos;ve been asked a number of times over the years how, exactly, I approach learning new stuff, whether that be a new programming language, a new platform, whatever. This is obviously a highly personal (meaning specific to the individual offering the answer) subject, so my approach may or may not work for you; regardless, I&apos;d suggest to anyone that they give it a shot and if it works, coolness.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;The first thing to understand about how I approach learning new stuff is that I agree whole-heartedly with our former Secretary of Defense, Donald Rumsfeld, when he says (said) that there are &amp;quot;three kinds of knowledge&amp;quot;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;That which you know you know.&lt;/strong&gt; In other words, the stuff that you already know. You have empircal knowledge of the subject. I know C++: I know most of the keywords, I know pretty much all of the syntax, I understand the mechanics of how the language compiles and what it compiles to, and so on. Personally, I consider myself to &amp;quot;know&amp;quot; a subject if I&apos;ve made use of it, in some fashion, for a moderately complex task. &amp;quot;Hello world&amp;quot; doesn&apos;t count (if we&apos;re speaking of a programming language), but doing one of the &lt;a href=&quot;http://codekata.com/&quot;&gt;code katas&lt;/a&gt; can, if it&apos;s got some good &amp;quot;range&amp;quot; to it (doing some I/O, a little algorithmic exercise, and so on).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;That which you know you do not know.&lt;/strong&gt; I am aware of the subject, but I have not spent much, if any, time on it. For myself, however, the key distinction between this category and the following one is, &amp;quot;Do I understand what this subject&apos;s purpose is? Do I know it&apos;s &amp;quot;two-sentence story&amp;quot;, and can I tell that story to somebody else?&amp;quot; (I&apos;ll talk more about the two-sentence story in a second.) This usually implies having done a small bit of reading on the subject, or doing that &amp;quot;hello world&amp;quot;/getting-started kind of tutorial. I know enough to have a good idea of where this thing fits in the world, but not enough to get started in it without having to do more reading and research.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;That which you do not know.&lt;/strong&gt; I have no awareness of this subject; I don&apos;t even know it exists. Obviously, this is hard for me to hold up examples, because if I knew of any, I&apos;d be moving them into the second category already. One such possibility is &lt;a href=&quot;https://www.kali.org/&quot;&gt;Kali Linux&lt;/a&gt;, which (from the context of a few articles/books I&apos;ve seen touch on the subject, as well as referencing the website to get its address just now) is apparently a Linux distribution tailor-made for doing security attacks and penetration testing. I have no idea what makes that distribution somehow better than any other, so right now I can&apos;t really formulate a two-sentence story around it other than what you just read. (And even then, one might argue that since I know of it, I am now aware that I don&apos;t know anything about it, and therefore it goes into category 2 as opposed to this one.)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Confused yet? It&apos;s not a hard breakdown, but it turns on the notion of knowledge vs ignorance---I can know a thing, or I can be aware of a thing and not know anything about it, or I can be ignorant of a thing. (And, of course, others will interpret the distinctions differently, and that&apos;s OK, too. This is just how I apply this to the topics that I need to know for work-related discussions/engagements/etc.)&lt;/p&gt;
&lt;p&gt;So, assuming that somebody or something brings a new thing to my attention, here&apos;s (roughly) the process by which I go learn something new:&lt;/p&gt;
&lt;h3&gt;Formulate a two-sentence story on it&lt;/h3&gt;
&lt;p&gt;The term &amp;quot;two-sentence story&amp;quot; dates back to my time at DevelopMentor. When we were working out new class materials, the common refrain was, &amp;quot;What&apos;s the two-sentence story for this thing?&amp;quot; In other words, if you could only describe the thing in two sentences, what would they say? Originally, the TSS was geared more around the class itself---&amp;quot;What&apos;s the two-sentence story for this class?&amp;quot;---which is a little different than coming up with a TSS for a technology as a whole, but I found it a useful mechanism to help identify and isolate the aspects of a new thing that I care about for a given technology. Some examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AspectJ: Aspect-oriented programming is a flavor of &amp;quot;metaobject programming&amp;quot;, a code mechanism that seeks to capture first-class constructs that &amp;quot;cut across&amp;quot; the traditional object-oriented hierarchy, around fields and/or methods, and apply those constructs reusably in multiple cases. AspectJ is a language-based implementation of AOP against the Java language running on the JVM.&lt;/li&gt;
&lt;li&gt;Groovy: Ruby and Java meet up one night in a bar and have a night of passion. Groovy is that love child, exhibiting the linguistic tendencies of Ruby, but with the underlying structure and (more or less) common language heritage of Java.&lt;/li&gt;
&lt;li&gt;Parrot: A register-oriented virtual machine that seeks to be for dynamic languages what the JVM or CLR were for statically-typed object languages (Java and C#). Tied closely at first to the next generation of the Perl language, and as a result more or less died with it.&lt;/li&gt;
&lt;li&gt;MongoDB: A schemaless document-oriented database written to run without any platform dependencies (statically-linked executables). Mongo looks to provide some of the traditional server-based database experience that is familiar and comfortable to those who are used to traditional RDBMS environments, while also channeling the &amp;quot;free-form&amp;quot; experience that those from the NoSQL crowd are expecting, including the ability to &amp;quot;scale up&amp;quot; to large datasets without having to significantly reprogram the code that accesses it.&lt;/li&gt;
&lt;li&gt;Boo: A Python-based language for the CLR that opens up the compiler pipeline for plugins to view and/or modify the AST of the code before execution. Interprets and/or compiles on the CLR.&lt;/li&gt;
&lt;li&gt;CouchDB: A schemaless document-oriented database that embraces HTTP and REST to the n-th degree, simultaneously embracing the same sort of &amp;quot;distributed non-centralized&amp;quot; model that is favored by distributed version control systems. In other words, Couch doesn&apos;t have a single source of truth, but collectively determines what that truth might be through replication and optimistic updates.&lt;/li&gt;
&lt;li&gt;Lua: A dynamically-typed tuple-centric scripting language designed to be easily embedded into native platform environments, most notably from C/C++ code. It is widely used in the gaming industry, and has a very well-designed FFI (foreign function interface) specifically to enable easy interoperability between the &amp;quot;high-level&amp;quot; Lua code and the native implementation underneath it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As you can tell, not all of these are wrapped up in academic language, because in some cases, they are specifically tied to my own understanding of other things. For example, Groovy being &amp;quot;the love child of that one-night stand between Ruby and Java&amp;quot; meme, that tells me a whole lot of things---namely, that Groovy runs on the JVM, and can be seen as &amp;quot;just another Java&amp;quot;, but has lots of genetic influence imparted upon it from Ruby. (Not surprising, considering that James Strachan, when he first started working on the language, wanted very specifically to bring over some of the things he saw in Ruby.)&lt;/p&gt;
&lt;p&gt;The key here is that the two-sentence story is my own story; it&apos;s somewhat personal to me, because it keys off of what other things I know pretty well. I don&apos;t expect that my two-sentence story for any given subject, when viewed alone or outside of my head like this, will actually impart much of anything in terms of actual understanding to anybody else. It&apos;s purely for me.&lt;/p&gt;
&lt;p&gt;But obviously, getting to the point of being able to formulate a TSS on it requires some research.&lt;/p&gt;
&lt;h3&gt;What is this thing like?&lt;/h3&gt;
&lt;p&gt;Like most people, I don&apos;t have a ton of time, so I need to come to grips with a thing fairly quickly. So when I&apos;m first looking at a subject, the goal is to find something I already know to which it is similar and/or from which it descends or is based. Having made that initial connection, though, doesn&apos;t mean that I have enough knowledge on the thing yet---next, I have to start looking for ways that it&apos;s different from the anchor: how is &amp;quot;A&amp;quot; not like &amp;quot;B&amp;quot;? No two things &amp;quot;A&amp;quot; and &amp;quot;B&amp;quot; are ever perfectly alike, so where are the differences? How profound are those differences? And does that mean I need a new anchor upon which to rest my understanding of the new thing?&lt;/p&gt;
&lt;p&gt;For example, when I was first learning Ruby, the obvious thing it was similar to was other object-oriented languages. It&apos;s tempting to see it thus as &amp;quot;another Java&amp;quot; or &amp;quot;another C#&amp;quot;. However, Ruby is a dynamic O-O, whereas Java and C# are statically-typed O-O, so that connection is weak. Even weaker, C++ compiles to native code, whereas Java compiles to bytecode and runs on a virtual machine; Ruby does neither of these things. It is a straight interpreted language, so that&apos;s even less of a comparison. Yes, Java/C# and Ruby both have this notion of &amp;quot;objects&amp;quot; and &amp;quot;fields&amp;quot; and &amp;quot;methods&amp;quot;, but that&apos;s like suggesting that a Ferrari and a Mack truck are similar, in that they both have &amp;quot;engines&amp;quot; and &amp;quot;wheels&amp;quot; and &amp;quot;drivers&amp;quot;.&lt;/p&gt;
&lt;p&gt;As I started hearing more about Ruby from the Rubyists around me, a more accurate connection started to form between Ruby and Smalltalk---both are object languages, but both are dynamically-typed, and both support some very similar kinds of &amp;quot;meta-programming&amp;quot;, most notably the idea of &amp;quot;method_missing&amp;quot;, where an attempt to invoke a method on an object that doesn&apos;t have said method won&apos;t result in a compile-time or runtime error, but instead potentially be handled by routing the request through a well-defined &amp;quot;trap&amp;quot; that can then examine the method call at runtime to determine what to do next. (This is how ActiveRecord works, by the way.)&lt;/p&gt;
&lt;p&gt;Oh, and the syntax of Ruby was originally pretty Perl-based, but has since mellowed out significantly, to the point where most Rubyists of reputable fame avoid the Perl-isms, so that it reads a little more &amp;quot;English-like&amp;quot; now. (With all apologies to those who aren&apos;t native English speakers.)&lt;/p&gt;
&lt;p&gt;Now, obviously, this isn&apos;t a 100% accurate summation of Ruby. JRuby, for example, is an implementation of Ruby that runs on top of the JVM, and as such, would sort of defy what I said earlier about it being interpreted. Fair enough. But at that level of nuance, I&apos;m pretty clearly out of category 2 and into category 1.&lt;/p&gt;
&lt;h3&gt;What is this thing used for?&lt;/h3&gt;
&lt;p&gt;One of the best ways to begin to understand a thing is to see what it is used for. For most of us, Ruby came to prominence because of Rails. (Several people I knew who were talking a lot about Ruby and RoR at the time were fond of saying, &amp;quot;Ruby-on-Rails is a domain-specific language for producing web applications.&amp;quot;) The approach was obvious: Ruby was about building web apps quickly. No wories about fine-tuning, no concerns over performance, the goal was to crank out a new web app quickly.&lt;/p&gt;
&lt;p&gt;Rightly or wrongly, that paints Ruby as a higher-level tool, a paint spray-gun, if you will, that will blast out a ton of stuff quickly, without much concern for the degree of control at the edges. (And that&apos;s OK, by the way, even if it is perhaps a tad misguided in terms of the interpretation of Ruby itself.) That positioning deliberately put it opposite tools like Java and certainly way far away from C++.&lt;/p&gt;
&lt;p&gt;But it also (again, perhaps wrongly) mischaracterized Ruby as &amp;quot;just&amp;quot; a web tool, and as a result Ruby missed out on the &amp;quot;cross-platform&amp;quot; nature that it represents, something which the JavaScript/Node community is trying very hard to cash in on.&lt;/p&gt;
&lt;h3&gt;Use it!&lt;/h3&gt;
&lt;p&gt;Assuming that I now have a better grip on the thing, the next step, to take it out of &amp;quot;known unknown&amp;quot; and bring it into the &amp;quot;known known&amp;quot; is to try and use it on something.&lt;/p&gt;
&lt;p&gt;Contrary to the &lt;a href=&quot;http://www.amazon.com/Great-Myths-Popular-Psychology-Misconceptions/dp/1405131128&quot;&gt;popular myth&lt;/a&gt; that &amp;quot;everybody learns differently&amp;quot;, actually using a thing remains one of the best ways to actually grab hold of a subject and keep it. In this particular case, I don&apos;t mean just going through an existing tutorial and repeating the steps, but creating your own project and slogging your way through it from start to finish. Sometimes, it&apos;s helpful to do the same project over and over again, a la a Code Kata, but sometimes I want to try something new, partly because I want to explore an idea or a concept.&lt;/p&gt;
&lt;p&gt;Case in point: Fifteen years ago, I wanted a blog, and at the time, all of the existing ones were just not what I was looking for. (I don&apos;t remember why---I may have just told myself that because I wanted to write my own, too. I just don&apos;t remember.) More to the point, I had this idea about self-modifying JSP pages: What would the practical implications be, from a coding perspective, if I had a blog implementation that, like a Wiki, would be modifying itself? In other words, creating a new blog post would be writing a new JSP page to disk, and subsequent requests to that page would be simply compiling-on-the-fly that JSP, as per any other JSP page? So I built that implementation (while on vacation with the family at DisneyWorld, actually), and cool! It worked. There were a few issues with it, though---for example, I had to get a little creative with servlet filters and use those as the &amp;quot;controllers&amp;quot; in a traditional MVC model---but that taught me that filters could be just as good, if not better, than servlets as the controller in an MVC model. (Which is in turn what made NodeJS &amp;quot;middleware&amp;quot; make so much sense to me, fifteen years later.)&lt;/p&gt;
&lt;p&gt;Another example: A year or two ago, a buddy of mine came to me and wanted to know how hard it would be to  build a web app that would allow volunteers to track their hours and make it easier to generate the email reports he had to send on. (He was a section leader, responsible for the pacific Northwest section of a volunteer organization, and the owning company wanted monthly emails about which people were doing what work at which locations. He was having to chase after people, then hand-assimilate their emails into a larger email and send that on to the company, which was costing him hours each month that he could be better using.) At the time, I was learning AngularJS, so I thought, &amp;quot;Sure, why not?&amp;quot; I built out a rough prototype for him, AngularJS on the front-end, but (in a daring architectural move!), I decided to try going &amp;quot;no-server&amp;quot;, and instead use the REST API feature offered by &lt;a href=&quot;http://www.mongolab.com&quot;&gt;MongoLab&lt;/a&gt; to a MongoDB instance in the cloud. It worked, but I fought with AngularJS all the damn time, and thank God he never really started using it in any kind of Production-like capacity, because that code was an absolute mess. It wasn&apos;t until the very end of working on it that I started to see &amp;quot;the Angular Way&amp;quot;, and by then, I&apos;d have had to rip it all up and start over. (I kept trying to use it as a kind of bastardized jQuery, and that didn&apos;t work out so well.)&lt;/p&gt;
&lt;p&gt;These &amp;quot;forcing function&amp;quot; projects are generally projects that aren&apos;t anywhere close to production requirements, and usually focused around my own interest and/or issues. The recent &amp;quot;DevOpsing the Blog&amp;quot; projects are a good example of that: I had a problem, I decided to explore how to use TeamCity to fix it, and lo, the results. (That said, a commenter suggested what I think may be &lt;a href=&quot;http://ifttt.com&quot;&gt;a much better solution&lt;/a&gt; to the automated posting to Twitter and LinkedIn, and I&apos;m exploring that now, too. If you got to this post from my Facebook feed, then the Facebook integration---which I&apos;m not sure if I&apos;ll keep, we&apos;ll see---works, and I just have to decide which approach I want to keep.)&lt;/p&gt;
&lt;p&gt;&amp;quot;Forcing function&amp;quot; projects ideally will be projects I can throw away and walk away from, because sometimes, the attempt to use a particular tool or a particular approach will just fail spectacularly, and the resulting mess will be something nobody, particularly me, wants to support. So it&apos;s always better NOT to use a project for which I am getting paid as a forcing function project. (The sole caveat: If the client knows that this is a project that I am using as a &amp;quot;forcing function&amp;quot; project, and they verbally and contractually agree to pay me to explore it, that&apos;s a different story. Anything less is, in my mind, a violation of professional ethics.) But the project will hopefully be non-trivial (no CRUD apps), and should be something a bit larger than what I see in the tool&apos;s tutorial section.&lt;/p&gt;
&lt;p&gt;And in some cases, it can be helpful to reuse a forcing function---for example, the blog. I might re-do that buddy&apos;s volunteer system in something like &lt;a href=&quot;https://www.meteor.com&quot;&gt;MeteorJS&lt;/a&gt;, just to see how well it would work and to compare the two approaches.&lt;/p&gt;
&lt;p&gt;In any event, doing a forcing-function project like this is usually sufficient to take something from category 2 into category 1, and from there, I tend to leave it be.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;There&apos;s probably a few other tricks that I&apos;m forgetting about right this second (or may not even realize I&apos;m doing, until I catch myself doing it), and if something comes up, I&apos;ll append/update the post. But for now, that&apos;s basically where it goes.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Functional Programming, for the Uninitiated (using Java)</title>
      <link>http://blogs.newardassociates.com/blog/2016/functional-java.html</link>
      <pubDate>Mon, 18 Jan 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/functional-java.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; It&apos;s been a few years since I did this particular routine for the NFJS shows, but I found a sequence of demos/explanations that really demonstrated clearly why Java (and other classic O-O) developers should learn a little functional programming style, even if they never pick up an actual functional language. The keystone to that sequence of demos? &lt;strong&gt;&lt;em&gt;&amp;quot;Collections are the gateway drug to functional programming.&amp;quot;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;I have concluded over the last decade or so that the best way to demonstrate a new concept is to &amp;quot;root&amp;quot; it (anchor it) cognitively against something developers already know how to do. With objects, that often entails &amp;quot;business objects&amp;quot; or &amp;quot;domain objects&amp;quot;. I looked for ways to somehow relate functional programming to these business objects through collections (the Java Collections in particular, since Java was the platform of choice for the No Fluff Just Stuff conferences at which I honed a lot of this message, but the story works pretty equally well for .NET---which admittedly has LINQ but for a long time wasn&apos;t recognized as a functional language within it---or C++.)&lt;/p&gt;
&lt;h3&gt;The Domain Type&lt;/h3&gt;
&lt;p&gt;Imagine we have a collection of Person types:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;public class Person {
  public Person(String fn, String ln, int a) {
    this.firstName = fn; this.lastName = ln; this.age = a;
  }
  
  public String getFirstName() { return firstName; }
  public String getLastName() { return lastName; }
  public int getAge() { return age; }
  
  public String toString() {
    return &amp;quot;[Person: &amp;quot; +
      &amp;quot;firstName:&amp;quot; + firstName + &amp;quot; &amp;quot; + 
      &amp;quot;lastName:&amp;quot; + lastName + &amp;quot; &amp;quot; +
      &amp;quot;age:&amp;quot; + age + &amp;quot;]&amp;quot;;
  }
  
  private String firstName;
  private String lastName;
  private int age;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yawn. Pretty boring stuff. Note that my Person type has no mutators/setters; this is both because this demo simply won&apos;t need them, and because in general it&apos;s better to try to work with immutable types anyway.&lt;/p&gt;
&lt;h3&gt;Groups of Persons&lt;/h3&gt;
&lt;p&gt;It&apos;s not uncommon that we will have a group of Persons with which we want to do various domain-ish kinds of things. The typical way to do this is with an array:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;Person[] attendees = new Person[] {
  new Person(&amp;quot;Ted&amp;quot;, &amp;quot;Neward&amp;quot;, 43),
  new Person(&amp;quot;Charlotte&amp;quot;, &amp;quot;Neward&amp;quot;, 39), // and she will ALWAYS be 39
  new Person(&amp;quot;Michael&amp;quot;, &amp;quot;Neward&amp;quot;, 22),
  new Person(&amp;quot;Matthew&amp;quot;, &amp;quot;Neward&amp;quot;, 16),
  new Person(&amp;quot;Carter&amp;quot;, &amp;quot;Wickstrom&amp;quot;, 45),
  new Person(&amp;quot;David&amp;quot;, &amp;quot;Dennison&amp;quot;, 41),
  new Person(&amp;quot;Kristy&amp;quot;, &amp;quot;Overton&amp;quot;, 20),
  new Person(&amp;quot;Hilary&amp;quot;, &amp;quot;Clinton&amp;quot;, 79),
  new Person(&amp;quot;Bernie&amp;quot;, &amp;quot;Sanders&amp;quot;, 129)
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A motley crew if ever there was one.&lt;/p&gt;
&lt;p&gt;Frequently, we find that we need to do various things with a subset of this crowd; for example, it&apos;s often happy hour, and we want to give everybody a nice cold one to top off the day:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;for (Person p : attendees)
  System.out.println(&amp;quot;Have a beer, &amp;quot; + p.getFirstName());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Spot anything particularly wrong with this code?&lt;/p&gt;
&lt;p&gt;Of course you do---you&apos;re like my wife, who has this crazy notion that my 16-year-old shouldn&apos;t actully be drinking. (Actually, neither should Kristy, for that matter.) So, when this bug is pointed out, the natural thing to do is put a guard clause of some form in the &amp;quot;for&amp;quot; loop:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;for (Person p : attendees)
  if (p.getAge() &amp;gt;= 21)
    System.out.println(&amp;quot;Have a beer, &amp;quot; + p.getFirstName());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And, we&apos;re done, right?&lt;/p&gt;
&lt;p&gt;Not really; the next time we want to do something across the entire group, we need to write almost exactly the same code again:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;for (Person p : attendees)
  if (p.getAge() &amp;gt;= 65)
    System.out.println(&amp;quot;Here&apos;s your retirement check, &amp;quot; + p.getFirstName());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;for (Person p : attendees)
  if (p.getAge() &amp;gt;= 16)
    System.out.println(&amp;quot;Here&apos;s your driver&apos;s license, &amp;quot; + p.getFirstName());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or even:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;for (Person p : attendees)
  if (p.getAge() &amp;gt;= 18 &amp;amp;&amp;amp; p.getAge() &amp;lt;= 65)
    System.out.println(&amp;quot;Have you registered for the draft, &amp;quot; + p.getFirstName() + &amp;quot;?&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When viewed this way, it&apos;s easy to see that &lt;em&gt;for loops violate the DRY principle&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;An aside: arrays suck&lt;/h3&gt;
&lt;p&gt;By the way, arrays in Java suck. They&apos;re not quite as bad in .NET, but they really REALLY suck in C++. Basically, the closer your language is to thinking of an array as just a pointer with some sexy pointer math on top of it, the more they suck. It&apos;s far better to use the collection classes that are (now) standard with every language.&lt;/p&gt;
&lt;p&gt;In Java, that usually means using List&lt;T&gt; and ArrayList&lt;T&gt;, and to a lot of developers, that means initializing that set of Persons to start with gets really cumbersome:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;List&amp;lt;Person&amp;gt; attendees = new ArrayList&amp;lt;Person&amp;gt;();
attendees.add(new Person(&amp;quot;Ted&amp;quot;, &amp;quot;Neward&amp;quot;, 43));
attendees.add(new Person(&amp;quot;Charlotte&amp;quot;, &amp;quot;Neward&amp;quot;, 39));
attendees.add(new Person(&amp;quot;Michael&amp;quot;, &amp;quot;Neward&amp;quot;, 22));
attendees.add(new Person(&amp;quot;Matthew&amp;quot;, &amp;quot;Neward&amp;quot;, 16));
attendees.add(new Person(&amp;quot;Carter&amp;quot;, &amp;quot;Wickstrom&amp;quot;, 45));
attendees.add(new Person(&amp;quot;David&amp;quot;, &amp;quot;Dennison&amp;quot;, 41));
attendees.add(new Person(&amp;quot;Kristy&amp;quot;, &amp;quot;Overton&amp;quot;, 20));
attendees.add(new Person(&amp;quot;Hilary&amp;quot;, &amp;quot;Clinton&amp;quot;, 79));
attendees.add(new Person(&amp;quot;Bernie&amp;quot;, &amp;quot;Sanders&amp;quot;, 129));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But as it turns out, the Java Collections library has a better approach to this; they refer to them as &lt;em&gt;algorithms&lt;/em&gt;, but in essence, these are black-box methods that do some pretty simple things:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;List&amp;lt;Person&amp;gt; attendees = Arrays.asList(
  new Person(&amp;quot;Ted&amp;quot;, &amp;quot;Neward&amp;quot;, 43),
  new Person(&amp;quot;Charlotte&amp;quot;, &amp;quot;Neward&amp;quot;, 39), // and she will ALWAYS be 39
  new Person(&amp;quot;Michael&amp;quot;, &amp;quot;Neward&amp;quot;, 22),
  new Person(&amp;quot;Matthew&amp;quot;, &amp;quot;Neward&amp;quot;, 16),
  new Person(&amp;quot;Carter&amp;quot;, &amp;quot;Wickstrom&amp;quot;, 45),
  new Person(&amp;quot;David&amp;quot;, &amp;quot;Dennison&amp;quot;, 41),
  new Person(&amp;quot;Kristy&amp;quot;, &amp;quot;Overton&amp;quot;, 20),
  new Person(&amp;quot;Hilary&amp;quot;, &amp;quot;Clinton&amp;quot;, 79),
  new Person(&amp;quot;Bernie&amp;quot;, &amp;quot;Sanders&amp;quot;, 129)
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;Arrays&lt;/code&gt; class is part of &lt;code&gt;java.util&lt;/code&gt;, and it&apos;s a set of static methods that are &amp;quot;just used&amp;quot;. No class initialization, no objects, just a good-ol&apos; method call. It&apos;s like 1985 called, screamed &amp;quot;Happy Birthday!&amp;quot; into the phone, and left a brand-new laser disc on our doorstep along with the receipt from Blockbuster.&lt;/p&gt;
&lt;p&gt;Still, it works, and there&apos;s a lot to be said for the simplicity and the ease by which we convert from the array form to the Collection form using &lt;code&gt;asList&lt;/code&gt; up there. But while we&apos;re on the subject, let&apos;s not call these &amp;quot;I don&apos;t really do anything on an object&amp;quot; things &amp;quot;methods&amp;quot;; let&apos;s get used to the idea of calling them &amp;quot;functions&amp;quot;, since they modify no object state, don&apos;t live on an instance, and really only use the &amp;quot;class&amp;quot; around them as a lexical scoping mechanism (and because Java has this really annoying rule about everything having to be part of a class because, you know, &amp;quot;globals are bad&amp;quot;. Unless they&apos;re called &amp;quot;singletons&amp;quot;, of course.)&lt;/p&gt;
&lt;h3&gt;Reusing code&lt;/h3&gt;
&lt;p&gt;Stepping back, look at the various loops above; it&apos;s fairly easy to generalize what we&apos;re doing; in each case, we&apos;re testing to see if somebody meets an age criteria, and if so, taking some kind of action. We like reusable code, so let&apos;s do that:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;class Utils {
  public static void happyHour(List&amp;lt;Person&amp;gt; persons) {
    for (Person p : persons)
      if (p.getAge() &amp;gt;= 21)
        System.out.println(&amp;quot;Have a beer, &amp;quot; + p.getFirstName());
  }
  public static void retirement(List&amp;lt;Person&amp;gt; persons) {
    for (Person p : persons)
      if (p.getAge() &amp;gt;= 65)
        System.out.println(&amp;quot;Here&apos;s your check, &amp;quot; + p.getFirstName());
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can actually do better than this pretty quickly, or so we think:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;class Utils {
  public static testGTAndPrint(List&amp;lt;Person&amp;gt; persons, int age, String message) {
    for (Person p : persons)
      if (p.getAge() &amp;gt; age)
        System.out.println(message + p.getFirstName())
  }
  public static void happyHour(List&amp;lt;Person&amp;gt; persons) { 
    testGTAndPrint(21, &amp;quot;Have a beer, &amp;quot;);
  }
  public static void retirement(List&amp;lt;Person&amp;gt; persons) {
    testGTAndPrint(65, &amp;quot;Here&apos;s your check, &amp;quot;);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But the flaws come out pretty quickly---we&apos;re not always going to want to test if the age is greater than the passed value (sometimes it will want to be less-than, like when seeing if anybody qualifies for the kids&apos; menu), and sometimes we will want to do something other than print a message to the console.&lt;/p&gt;
&lt;p&gt;The larger pattern here is obvious, though: test, then act. How do we generalize this?&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;../../patterns/behavioral/Strategy/&quot;&gt;Strategy pattern&lt;/a&gt;, of course!&lt;/p&gt;
&lt;h3&gt;Everybody knows Strategy&lt;/h3&gt;
&lt;p&gt;Java has long had a rich history with patterns, particularly those defined in the &amp;quot;Gang of Four&amp;quot; book, and Strategy is one of the ones that has been with us from the beginning. Most of the time we&apos;re familiar with it from wanting to compare two objects to see if one is &amp;quot;greater&amp;quot; or &amp;quot;lesser&amp;quot; than the other, using the &lt;code&gt;Comparable&lt;/code&gt; interface: one simply implements it on the class that we want to compare, and provide an implementation of it.&lt;/p&gt;
&lt;p&gt;Unless, of course, we want to sort by a different criteria. Then things get a little tricky.&lt;/p&gt;
&lt;p&gt;See, part of the magic of Strategy is that its implementation is supposed to be replaceable at runtime for another implementation, and we can&apos;t do that if we inherit the interface and define the implementaiton as a method. This is not an unreasonable thing to want for comparisons; sometimes we want to arrange people by last name, sometimes by first name, sometimes by age, sometimes by height, and so on. We want to change the implementation used to do the comparison at runtime, so we use a &lt;code&gt;Comparator&lt;/code&gt;; for a &lt;code&gt;Person&lt;/code&gt;, that often looks something like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;class AgeComparator&amp;lt;Person&amp;gt; implements Comparator&amp;lt;Person&amp;gt; {
  // return negative for &amp;quot;less than&amp;quot;, 0 for &amp;quot;equal&amp;quot;, or 
  // positive for &amp;quot;greater than&amp;quot;; easiest way to do that is
  // to just subtract one from the other
  //
  public int compare(Person lhs, Person rhs) {
    return lhs.getAge() - rhs.getAge();
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, when sorting (perhaps using a &lt;code&gt;SortedSet&lt;/code&gt; or the &lt;code&gt;Collections.max&lt;/code&gt; or &lt;code&gt;Collections.min&lt;/code&gt; methods), we simply instantiate and pass in the &lt;code&gt;Comparator&lt;/code&gt; of choice.&lt;/p&gt;
&lt;p&gt;By the way, though, I never liked seeing these guys float around as top-level classes; the &lt;code&gt;AgeComparator&lt;/code&gt; there is specific to Person, so it really should be captured inside the class, if you ask me:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;class Person {
  public class AgeComparator&amp;lt;Person&amp;gt; implements Comparator&amp;lt;Person&amp;gt; {
    // return negative for &amp;quot;less than&amp;quot;, 0 for &amp;quot;equal&amp;quot;, or 
    // positive for &amp;quot;greater than&amp;quot;; easiest way to do that is
    // to just subtract one from the other
    //
    public int compare(Person lhs, Person rhs) {
      return lhs.getAge() - rhs.getAge();
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now that you mention it, we really don&apos;t ever need more than one of them at a time, so we can just instantiate one, make it &lt;code&gt;static&lt;/code&gt; (and make it &lt;code&gt;final&lt;/code&gt; while we&apos;re at it, since we probably don&apos;t want anybody outside of &lt;code&gt;Person&lt;/code&gt; to change what it means to compare two &lt;code&gt;Person&lt;/code&gt;s by age):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;class Person {
  public static final Comparator&amp;lt;Person&amp;gt; BY_AGE = new Comparator&amp;lt;Person&amp;gt;() {
    public int compare(Person lhs, Person rhs) {
      // Notice that now, since we&apos;re inside the class, we can go directly at the
      // fields, which may be faster, depending on how complicatd the internal state
      // of the class is
      //
      return lhs.age - rhs.age;
    }
  };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All boned up on Strategy? Cool.&lt;/p&gt;
&lt;p&gt;By the way, this is where things are going to take a bit of a cognitive leap, so if you need to, you know, grab a coffee or go to the bathroom or something, now&apos;s a good time to do it. Fortunately, this isn&apos;t a conference, so I&apos;ll just stop here and wait for you until you get back. Totally cool---I have a few emails to do anyway.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Hums and fires up email client)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Ready? Let&apos;s keep going.&lt;/p&gt;
&lt;h3&gt;Strategy to the reusable rescue&lt;/h3&gt;
&lt;p&gt;We have two Strategies at work here, actually: one to do the test, and the other to do the action, so let&apos;s create two interfaces, one for each:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;interface Test {
  public boolean test(Person p);
}

interface Act {
  public void do(Person p);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can rewrite &lt;code&gt;Utils&lt;/code&gt; a little bit more... reusably.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;class Utils {
  public static testAndAct(List&amp;lt;Person&amp;gt; persons, Test tester, Act actor) {
    for (Person p : persons)
      if (tester.test(p))
        actor.do(p);
  }
  
  public static class DrinkableAge : Test {
    public boolean test(Person p) { return p.getAge() &amp;gt; 21; }
  }
  public static class RetiredAge : Test {
    public boolean test(Person p) { return p.getAge() &amp;gt; 65; }
  }
  
  public static class HaveABeer : Actor {
    public void do(Person p) { System.out.println(&amp;quot;Have a beer, &amp;quot; + p.getFirstName()); }
  }
  public static class HeresYourCheck : Actor {
    public void do(Person p) { System.out.println(&amp;quot;Here&apos;s your check, &amp;quot; + p.getFirstName()); }
  }
  
  public static void happyHour(List&amp;lt;Person&amp;gt; persons) {
    testAndAct(persons, new DrinkableAge(), new HaveABeer());
  }
  public static void retirement(List&amp;lt;Person&amp;gt; persons) {
    testAndAct(persons, new RetiredAge(), new HeresYourCheck());
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You know what, though? Every time we call either of those methods, we&apos;re creating new objects, when they don&apos;t really need to be new; we can use the same one, over and over again (even across multiple threads, since they don&apos;t hold any state). Let&apos;s make them Singletons:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;class Utils {
  public static testAndAct(List&amp;lt;Person&amp;gt; persons, Test tester, Act actor) {
    for (Person p : persons)
      if (tester.test(p))
        actor.do(p);
  }
  
  public static final Test DRINKER = new Test() {
    public boolean test(Person p) { return p.getAge() &amp;gt; 21; }
  };
  public static final Test RETIRED = new Test() {
    public boolean test(Person p) { return p.getAge() &amp;gt; 65; }
  };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... and in fact, we can generalize the &amp;quot;printers&amp;quot; a little more by getting a little creative:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;class Utils {
  public static testAndAct(List&amp;lt;Person&amp;gt; persons, Test tester, Act actor) {
    for (Person p : persons)
      if (tester.test(p))
        actor.do(p);
  }
  
  public static Actor createPrinterActor(String message) {
    return new Actor() {
      public void do(Person p) {
        System.out.println(message + p.getFirstName());
      }
    };
  }
  
  public static final Actor HAVE_A_BEER = createPrinterActor(&amp;quot;Have a beer, &amp;quot;);
  public static final Actor HERES_CHECK = createPrinterActor(&amp;quot;Here&apos;s your check, &amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... which then makes the other methods even more interesting:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;class Utils {
  public static testAndAct(List&amp;lt;Person&amp;gt; persons, Test tester, Act actor) {
    for (Person p : persons)
      if (tester.test(p))
        actor.do(p);
  }
  
  public static void happyHour(List&amp;lt;Person&amp;gt; persons) {
    testAndAct(persons, DRINKER, HAVE_A_BEER);
  }
  public static void retirement(List&amp;lt;Person&amp;gt; persons) {
    testAndAct(persons, RETIRED, HERES_CHECK);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Interesting, wot?&lt;/p&gt;
&lt;h3&gt;Utilicizing Utils&lt;/h3&gt;
&lt;p&gt;Have a look back at the &lt;code&gt;testAndAct&lt;/code&gt; method again; is there anything really all that specific to the &lt;code&gt;Person&lt;/code&gt; type inside of it? Not a lick, which implies that it can actually be genericized entirely away from &lt;code&gt;Person&lt;/code&gt; itself:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;class Utils {
  // will not compile yet
  public static &amp;lt;T&amp;gt; testAndAct(List&amp;lt;T&amp;gt; items, Test tester, Act actor) {
    for (T t : items)
      if (tester.test(t))
        actor.do(t);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... but in order for that to work, Test and Act have to be made generics, as well. (Note that the method is generic, not the entire Utils class, which necessitates the &amp;quot;generic type argument&amp;quot; at the front of the method signature.)&lt;/p&gt;
&lt;p&gt;Now, it&apos;s time for a bit of an admission: technically, &lt;code&gt;testAndAct&lt;/code&gt; is actually two methods in one. One is a method designed to filter out items that don&apos;t fit a particular criteria, and the other is to perform a specific action against each element in the collection. So let&apos;s rename the interfaces accordigly, and break the two methods out:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;interface FilterFn&amp;lt;T&amp;gt; {
  public boolean apply(T it);
}
interface ActionFn&amp;lt;T&amp;gt; {
  public void apply(T it);
}

class Utils {
  public static &amp;lt;T&amp;gt; List&amp;lt;T&amp;gt; filter(List&amp;lt;T&amp;gt; src, FilterFn&amp;lt;T&amp;gt; criteria) {
    List&amp;lt;T&amp;gt; results = new ArrayList&amp;lt;T&amp;gt;();
    for (T it : src)
      if (criteria.apply(it))
        results.add(it);
    return results;
  }
  public static &amp;lt;T&amp;gt; void map(List&amp;lt;T&amp;gt; src, ActionFn&amp;lt;T&amp;gt; action) {
    for (T it : src)
      action.apply(it);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&apos;ve made a little terminology switch here, too. Each of the methods inside the interface is called &amp;quot;apply&amp;quot;, for historical reasons. (That&apos;s what functional guys call doing something with a method on an object, &amp;quot;applying&amp;quot; it.) And &amp;quot;test&amp;quot; became &amp;quot;filter&amp;quot;, and &amp;quot;action&amp;quot; became &amp;quot;map&amp;quot;. (That last one deserves explanation---the functional crowd says that when you apply a function across each element of a collection, you&apos;re &amp;quot;mapping&amp;quot; the function to each element. Why that particular verb, though, I honestly don&apos;t know.)&lt;/p&gt;
&lt;p&gt;(And yes, all you classic functional programmers, I know that you may disagree with my use of the terminology; hold your criticism for now, please. I&apos;ve heard &amp;quot;map&amp;quot; used several different ways in several different languages, and I don&apos;t want to get into the nuances right now.)&lt;/p&gt;
&lt;p&gt;And while we could go back and rewrite the &lt;code&gt;happyHour&lt;/code&gt; and &lt;code&gt;retirement&lt;/code&gt; methods on Utils, it actually is becoming more clear that &lt;code&gt;Utils&lt;/code&gt; is about a lot more than just people. As a matter of fact, it&apos;s arguable that those are actually things that should be defined on the &lt;code&gt;Person&lt;/code&gt; class itself, since they relate more to Person-hood than anything else:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;public class Person {
  public static final FilterFn&amp;lt;Person&amp;gt; DRINKER = new FilterFn&amp;lt;Person&amp;gt;() {
    public boolean apply(Person it) { return it.getAge() &amp;gt;= 21; }
  };
  public static final FilterFn&amp;lt;Person&amp;gt; RETIRED = new FilterFn&amp;lt;Person&amp;gt;() {
    public boolean apply(Person it) { return it.getAge() &amp;gt;= 65; }
  };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now we can go back to just using them inline, right?:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;Utils.map(
  Utils.filter(attendees, Person.DRINKER),
  new ActionFn&amp;lt;Person&amp;gt;() {
    public void apply(Person it) {
      System.out.println(&amp;quot;Have a beer, &amp;quot; + it.getFirstName());
    }
  });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... because this is so much clearer!&lt;/p&gt;
&lt;h3&gt;Sanity, O Sanity, wherefore art thou, Sanity?&lt;/h3&gt;
&lt;p&gt;It&apos;s usually at about this point in the discussion that even the most open-minded soul starts looking at me a little quizzically, because this really doesn&apos;t seem to have a whole lot of upside to it---it&apos;s longer, it&apos;s much more indirect than a traditional iteration loop, and frankly, using this inline just feels hideous. Part of this is the awkward pre-Java8 syntax. But part of it is that this just doesn&apos;t seem to have much advantage to it.&lt;/p&gt;
&lt;p&gt;Until you get to writing tests.&lt;/p&gt;
&lt;p&gt;Here&apos;s the challenge: how many tests do you need to write each time you write a for loop in your code? Typically, there&apos;s going to need to be a test to exercise every possible combination through that loop, for each for loop in the code. And let&apos;s talk about how many different permutations of collections you need to construct in order to test all of those permutations. This is going to spiral out of control pretty quickly.&lt;/p&gt;
&lt;p&gt;But in my new version, how many tests do you need to write? I count:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Test that &lt;code&gt;Utils.filter()&lt;/code&gt; works&lt;/li&gt;
&lt;li&gt;Test that &lt;code&gt;Utils.map()&lt;/code&gt; works&lt;/li&gt;
&lt;li&gt;Test that &lt;code&gt;DRINKERS&lt;/code&gt; works&lt;/li&gt;
&lt;li&gt;Test that &lt;code&gt;RETIRED&lt;/code&gt; works&lt;/li&gt;
&lt;li&gt;Test that the anonymous &lt;code&gt;ActionFn&lt;/code&gt; works&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And, really, look back at &lt;code&gt;DRINKERS&lt;/code&gt; and &lt;code&gt;RETIRED&lt;/code&gt;; do we really need a test to determine that a simple getter works, or that Java&apos;s math works? I&apos;d argue that we can strike those out completely. And as for the &lt;code&gt;ActionFn&lt;/code&gt;, when&apos;s the last time that &lt;code&gt;System.out.println&lt;/code&gt; failed you? Or String concatenation?&lt;/p&gt;
&lt;p&gt;So we&apos;re down to two methods to test. (And I would argue that they&apos;re also so ridiculously simple, they don&apos;t need testing, either, but maybe that&apos;s pushing it for you, I dunno.) But here&apos;s a nice parting gift for our contestants today: Once those two methods are tested to your satisfaction, they&apos;re tested for everything that might use them---whether it&apos;s a &lt;code&gt;Person&lt;/code&gt; being passed in, or a &lt;code&gt;Pet&lt;/code&gt; or a &lt;code&gt;CheckingAccount&lt;/code&gt; doesn&apos;t matter.&lt;/p&gt;
&lt;p&gt;Hunh. That&apos;s not a bad tradeoff, actually.&lt;/p&gt;
&lt;p&gt;And if we use the &lt;code&gt;static import&lt;/code&gt; to pull in the members on Utils (a la &lt;code&gt;import static Utils.*;&lt;/code&gt;), then &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt; become top-level symbols, so we can leave off the &amp;quot;Utils.&amp;quot; prefix. And heck, if you rename &amp;quot;map&amp;quot; to &amp;quot;for&amp;quot; (oh, if only we could, curse you keywords!), you end up with something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;map(
  filter(attendees, Person.DRINKER),
  new ActionFn&amp;lt;Person&amp;gt;() {
    public void apply(Person it) {
      System.out.println(&amp;quot;Have a beer, &amp;quot; + it.getFirstName());
    }
  });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, all it really takes is to create one of those &amp;quot;printerActor&amp;quot; objects somewhere as a static, and this can simplify down to:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;map(
  filter(attendees, Person.DRINKER),
  HAVE_A_BEER
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It sure as hell doesn&apos;t look like Java much anymore, but is there any question left in your mind as to what is going on here? It almost reads like pseudocode!&lt;/p&gt;
&lt;h3&gt;Now do this a million times...&lt;/h3&gt;
&lt;p&gt;But here&apos;s the kicker: What if there aren&apos;t just ten attendees, but ten million? The &lt;code&gt;filter&lt;/code&gt; and &lt;code&gt;map&lt;/code&gt; implementations in Utils are totally inappropriate for that; they should be parallelized, probably using the ForkJoin framework from inside Java7, or at least breaking up the work into smaller chunks and handing each chunk out to a separate thread for processing, gathering those results up into a final collection, and and and&lt;/p&gt;
&lt;p&gt;And how often do you want to write that?&lt;/p&gt;
&lt;p&gt;In the earlier &amp;quot;for&amp;quot; loop case, you&apos;d have to write that every single time you wanted to do anything with this 10-million-item collection. Every. Single. Time.&lt;/p&gt;
&lt;p&gt;In my Utils-based version, though, the FilterFn and ActionFn implementations remain exactly as they are; we just need a new version of Utils that does all that parallelization stuff, and now the code can take advantage of parallelization by going from this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;map(
  filter(attendees, Person.DRINKER),
  HAVE_A_BEER
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;map(
  filter(attendees, Person.DRINKER),
  HAVE_A_BEER
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See the difference?&lt;/p&gt;
&lt;p&gt;Actually, I lied; we actually need to do it like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;import static Utils.*;

// ...

map(
  filter(attendees, Person.DRINKER),
  HAVE_A_BEER
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;import static ParallelUtils.*;

// ...

map(
  filter(attendees, Person.DRINKER),
  HAVE_A_BEER
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&apos;s not bad. Change one lie of code, and voila! You have a thread pooled set of operations. Twice. Without changing an actual implementation line of code.&lt;/p&gt;
&lt;p&gt;But wait---act now, and we&apos;ll throw in a set of Ginsu knives as well. Or, maybe not. But something just as cool, I promise.&lt;/p&gt;
&lt;h3&gt;Folding universes&lt;/h3&gt;
&lt;p&gt;The functional world is not done with us yet. It&apos;s got another surprise or two up its sleeve.&lt;/p&gt;
&lt;p&gt;First of all, there&apos;s two more generic &amp;quot;function&amp;quot; types that they like to define; one is a &amp;quot;transformation&amp;quot; function that takes an A and turns it into a B, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;interface TransformerFn&amp;lt;R,T&amp;gt;
{
    public R apply(T it);
}

class Utils {
  public static &amp;lt;R,T&amp;gt; List&amp;lt;R&amp;gt; xform(List&amp;lt;T&amp;gt; src, TransformerFn&amp;lt;R,T&amp;gt; transformer)
  {
    List&amp;lt;R&amp;gt; results = new ArrayList&amp;lt;R&amp;gt;();
    for (T it : src)
      results.add(transformer.apply(it));
    return results;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where &amp;quot;R&amp;quot; means &amp;quot;result&amp;quot; and &amp;quot;T&amp;quot; is the traditional input type.&lt;/p&gt;
&lt;p&gt;Using this one is pretty easy to understand---the &lt;code&gt;Person&lt;/code&gt; has several of these kinds of &amp;quot;transformation&amp;quot; methods already defined, in the sense that you can think about &lt;code&gt;getFirstName&lt;/code&gt; as a method that &amp;quot;transforms&amp;quot; a &lt;code&gt;Person&lt;/code&gt; into a &lt;code&gt;String&lt;/code&gt; that happens to hold that person&apos;s first name as its value. So it&apos;s possible to take our list of attendees, and &amp;quot;transform&amp;quot; them into a list of last names (perhaps for sorting reasons), by using a particular Utils method that basically looks like all of the others except for the type signature:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;List&amp;lt;String&amp;gt; lastNames = 
  Utils.xform(attendees, 
    new TransformerFn&amp;lt;String, Person&amp;gt;() {
      public String apply(Person it) { return p.getLastName(); }
    });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other is an &amp;quot;accumulation&amp;quot; function, where we want to accumulate a value while doing something to each element of a collection. Doing this is called &amp;quot;folding&amp;quot;, because it takes a collection of stuff and effectively &amp;quot;folds&amp;quot; it into one value, one element at a time. (These are sometimes called &amp;quot;folding left&amp;quot; or &amp;quot;folding right&amp;quot;, depending on whether it starts at the beginning or the end of the collection.) Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;interface FoldFn&amp;lt;R,T&amp;gt;   // F2&amp;lt;R,T,R&amp;gt;
{
    public R apply(R accum, T it);
}

class Utils {
  public static &amp;lt;R,T&amp;gt; R foldLeft(R seed, List&amp;lt;T&amp;gt; src, FoldFn&amp;lt;R,T&amp;gt; folder)
  {
    R accum = seed;
    for (T it : src)
      accum = folder.apply(accum, it);
    return accum;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The easist example to see here is to &amp;quot;fold&amp;quot; a series of numbers together; perhaps we want to find the average age of all the attendees, so we sum them all up, and then divide by the number of attendees:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;// In other words, instead of doing this:
//
int accum = 0;
for (Person it : attendees)
  accum = accum + it.getAge();
System.out.println(&amp;quot;total age = &amp;quot; + accum);
System.out.println(&amp;quot;average age = &amp;quot; + (accum / attendees.size());

// Now we would do this:
//
Integer totalAge = Utils.foldLeft(0, people, new FoldFn&amp;lt;Integer,Person&amp;gt;() {
  public Integer apply(Integer accum, Person it) {
    return accum + it.getAge();
  }
});
System.out.println(&amp;quot;total age = &amp;quot; + totalAge);
System.out.println(&amp;quot;average age = &amp;quot; + (totalAge / attendees.size());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Seems kinda pointless, ya?&lt;/p&gt;
&lt;h3&gt;The XML factor&lt;/h3&gt;
&lt;p&gt;Oh, by the way, the customer called; they want to see all of those attendees in a SOAP call by Monday. Time to break out your JAXB, or other Reflection-based Java-to-XML library of choice, right?&lt;/p&gt;
&lt;p&gt;While you do that, I&apos;m just going to transform this entire collection of &lt;code&gt;Person&lt;/code&gt;s  into XML with only the use of these two functions:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;String xml = Utils.foldLeft(&amp;quot;&amp;lt;people&amp;gt;&amp;quot;, people, new FoldFn&amp;lt;String,Person&amp;gt;() {
  public String apply(String accum, Person it) {
    return accum + &amp;quot;&amp;lt;person&amp;gt;&amp;quot; + it.getFirstName() + &amp;quot;&amp;lt;/person&amp;gt;&amp;quot;;
  }
}) + &amp;quot;&amp;lt;/people&amp;gt;&amp;quot;;
System.out.println(xml);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And you know what&apos;s even more interesting? Doing it this way, I can actually change the format of how the Person renders into XML without having to chagne a thing inside the Person.&lt;/p&gt;
&lt;p&gt;Oh, and did I mention that this is---still---all ridiculously easy to test? Because all of this code is, when you look at it, made up of entirely idiotically-simple primitives that really require no testing whatsoever. Point to one aspect of any of these functions that isn&apos;t drop-dead, absolutely-the-most-primitive-thing-the-language-can-do kinds of operations. For crying out loud, the &lt;code&gt;FoldFn&lt;/code&gt; is just doing String concatenation and a simple getter call; what the hell is there to test?!?&lt;/p&gt;
&lt;p&gt;Intrigued yet?&lt;/p&gt;
&lt;h3&gt;Wrapping up&lt;/h3&gt;
&lt;p&gt;Don&apos;t get me wrong; there&apos;s a lot more to functional programming than just what I&apos;ve demonstrated here, and Java8&apos;s new labmda support (which, by the way, I&apos;m going to leave to you to use to refactor this code to Java8 syntax, because it&apos;s a good exercise and you need the practice anyway) most certainly does not do all the things that one would expect a modern &amp;quot;functional&amp;quot; language to do. (Talk to me when you know what &amp;quot;currying&amp;quot; is.)&lt;/p&gt;
&lt;p&gt;Oh, and now, is it clear why I think collections are the gateway drug to functional programming?&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Technical Debt: A Definition</title>
      <link>http://blogs.newardassociates.com/blog/2016/technical-debt-definition.html</link>
      <pubDate>Mon, 18 Jan 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/technical-debt-definition.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; A recent post on medium.com addresses the topic of technical debt; I had an intuitive disagreement with the thrust of the post, and wrote this as a way of clarifying my own thoughts on the matter. It raises some interesting questions about what technical debt actually is---and if we can&apos;t define it, how can we possibly understand how to avoid it or remove it, as opposed to our current practice of using it as a &amp;quot;get-out-of-this-codebase-by-blowing-it-all-up&amp;quot; card?&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.com/@kellan/towards-an-understanding-of-technical-debt-ae0f97cc0553#.k5o49zz9r&quot;&gt;@kellan wrote&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Technical debt exists. But it’s relatively rare. When you start arguing with someone about technical debt, you’ll generally encounter a definition like: Technical debt is the choices we made in our code, intentionally, to speed up development today, knowing we’d have to change them later. Hard coding a variable because currently there is no plan to change it is a common example of technical debt. Similarly not modularizing a function.&lt;/p&gt;
&lt;p&gt;This is a fairly clear, succinct, and easy to reason about definition, that describes a phenomena that exists relatively rarely. Relatively rare compared to what? Compared to the amount of technical debt we ascribe to the codebases we work on. How then do we explain the overwhelming prevalence of technical debt we encounter when we talk to people about code?&lt;/p&gt;
&lt;p&gt;The term is being abused, or at least dangerously overloaded.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;He&apos;s certainly right about that! But just prior to that, he says, &amp;quot;Technical debt doesn&apos;t exist&amp;quot;, and sort of wanders around that idea for a bit.&lt;/p&gt;
&lt;p&gt;Here&apos;s the rub: He then tries to define what technical debt actually &lt;em&gt;is&lt;/em&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&amp;quot;Maintenance work.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Features of the codebase that resist change.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Operability choices that resist change.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Code choices that suck the will to live.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Dependencies that resist upgrading.&amp;quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I&apos;ll leave you to read his descriptions of each.&lt;/p&gt;
&lt;h3&gt;Critique&lt;/h3&gt;
&lt;p&gt;Unfortunately, a lot of the definitions he raises there are highly subjective and extremely difficult to understand, except at a base, emotional, almost visceral level. I mean, when you explicitly use the phrase &amp;quot;suck the will to live&amp;quot; as one of your definitions, it&apos;s hard to really put a concrete discussion around that.&lt;/p&gt;
&lt;p&gt;Consider, for example, that particular point: &amp;quot;A significant percentage of what gets referred to as technical debt are the decisions that don’t so much discourage change but rather discourage us from even wanting to look at the code. ... We often describe this code with the suck-the-will-to-live quality as messy (spaghetti), unmaintainable, or amateurish. Often what we’re describing under the surface is fear and confusion. We don’t understand the code, and when we don’t understand things, as human, we tend to get scared, tired, and angry.&amp;quot;&lt;/p&gt;
&lt;p&gt;I&apos;m sure every single person reading this has an immediate reaction, akin to the screams through the Force that Obi-Wan felt when Alderaan was destroyed. Everybody remembers That One Project, or That One Class, or That One File.... Nobody wanted to touch it, it was a mess, and people would look for every reason under the sun to avoid opening it, as if there was some kind of icky black ichor that could ooze out of the screen and keyboard and infect us with its ugliness.&lt;/p&gt;
&lt;p&gt;And yet, if we compare the stories, we will all have very different concrete-terms descriptions of what that thing was. And I&apos;ll even bet that if you cast the net wide enough, and we spend enough time comparing stories, we&apos;ll even find that one man&apos;s &amp;quot;suck the will to live&amp;quot; is another man&apos;s &amp;quot;Whoa, man, that&apos;s actually kind of a cool hack.&amp;quot;&lt;/p&gt;
&lt;p&gt;Case in point: in the earliest days of my career, I was a contractor working on some C/Win16 code at Intuit. A really cool 3-month gig (and in those days, it was way cool to have Intuit on your resume). I was working as part of the &amp;quot;Slickrock&amp;quot; team, which was the code-name for Intuit&apos;s nascent electronic banking section of Quicken 5 for Windows. It was some cool stuff.&lt;/p&gt;
&lt;p&gt;Except....&lt;/p&gt;
&lt;p&gt;Well, first of all, everything was written in C. Not C++, as was the leading-edge of the day, but using Intuit&apos;s home-grown C/Windows library that they&apos;d put together since the earliest days of the product. At the time, I was kinda bleah on the whole idea. (In retrospect, hey, if it still works, you know?)&lt;/p&gt;
&lt;p&gt;And there was this one dialog box to which I was assigned, which had a bunch of bugs in it that needed fixing, that nobody else on the team wanted to touch. Eager to prove to all these grizzled veterans that I was capable of handling the toughest stuff, I leapt at the chance to get into this thing. (If you get this picture of the eager young Private fresh from boot camp, volunteering to go out on that mission that the grizzled old Sargeant knows will just crush the life out of him, you&apos;re probably not too far off the mark.)&lt;/p&gt;
&lt;p&gt;And here&apos;s what I found: this dialog box code was one, giant, four-page-long function, where three-and-three-quarters of it was wrapped in one giant-ass &lt;code&gt;do-while&lt;/code&gt; loop. But not just any &lt;code&gt;do-while&lt;/code&gt; loop; no, this one was the most bizarre thing I&apos;d ever seen. It looked something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;do {
  /* do one thing */
  
  /* do another thing */
  
  /* check that thing */
  
  /* what about the thing over there */
} while (0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It was my own private &amp;quot;WTF?!?&amp;quot; moment. No wonder everybody wanted to stay clear of this thing! This was the craziest code I&apos;d ever seen, and clearly it was because they weren&apos;t using C++!&lt;/p&gt;
&lt;p&gt;(Yeah, I kinda was that stupid back then.)&lt;/p&gt;
&lt;p&gt;But when I showed this to one of the other engineers and said the 90&apos;s equivalent of &amp;quot;Dude, seriously?&amp;quot;, he pointed out that I&apos;d missed an important part of the whole thing:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;int result = -1; /* Not OK! */
do {
  /* do one thing */
  if (!thing-worked)
    break;
  
  /* do another thing */
  if (!another-thing-worked)
    break;
  
  /* check that thing */
  if (!thing-checked)
    break;
  
  /* what about the thing over there */
  if (!thing-over-there-checked)
    break;
    
  result = 0; /* OK! */
} while (0);
return result;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In other words, this incredibly idiotic thing actually served a useful purpose: it obeyed the old C rule of &amp;quot;single entry, single exit&amp;quot;, and more importantly, it was rather elegantly obeying the fail-fast principle. (Why bother doing all these other checks if you&apos;ve already failed at the first step?)&lt;/p&gt;
&lt;p&gt;Now, I grant you, this could&apos;ve been solved using C++ using exceptions; instead of the (not-really-a-)loop, he could just have done a &amp;quot;try&amp;quot;, and then each step could&apos;ve thrown their own new exception type, and there&apos;d have been either a single &amp;quot;catch&amp;quot; to return the appropriate error code (since this block was returning either -1 or 0, depending on success), or even maybe a separate &amp;quot;catch&amp;quot; block to handle each different error condition, and---&lt;/p&gt;
&lt;p&gt;But you know what? Today, looking back at it, I don&apos;t know if that would&apos;ve been much clearer, or much shorter, or what-have-you.&lt;/p&gt;
&lt;p&gt;Is this still life-sucking-code? Or is this an elegant hack? I&apos;ll be honest, I&apos;m not sure anymore, of either position.&lt;/p&gt;
&lt;h3&gt;Technical Debt: A Definition&lt;/h3&gt;
&lt;p&gt;I don&apos;t have one.&lt;/p&gt;
&lt;p&gt;Seriously.&lt;/p&gt;
&lt;p&gt;Not one I particularly like, anyway. Google it, and you get:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Technical debt (also known as design debt or code debt) is a metaphor referring to the eventual consequences of any system design, software architecture or software development within a codebase.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;quot;eventual consequences&amp;quot;? You mean, like &amp;quot;it works&amp;quot;? Seriously, consequences are not always bad, which is why the Gang-of-Four used that same word to describe the results of a particular solution applied to a particular problem within a certain context. Consequences can be positive, and they can also be negative. The use of the Strategy pattern can allow for varying an algorithm at runtime---but with it comes an added cost in complexity of determining which Strategy to load, for example, or the additional cognitive load of having to realize that now the Strategy being executed may be nowhere local to the code actually executing it (which would at some level seem to violate the principle of locality, depending on the situation).&lt;/p&gt;
&lt;p&gt;Wikipedia goes on to say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The debt can be thought of as work that needs to be done before a particular job can be considered complete or proper.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now that&apos;s interesting, because that certainly doesn&apos;t jibe with what @kellan was alluding to earlier---this sounds like things like documentation and tests and such. And yes, that definitely could create a problem, if a company/team/programmer goes off and writes a whole bunch of untested, undocumented code; I&apos;d call that indebted code, probably, sure.&lt;/p&gt;
&lt;p&gt;Unless, you know, it doesn&apos;t really need documentation. Or tests. Like, for example, a module composed of much smaller functions, each of which are effectively small primitives that really don&apos;t need testing, a la:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;def calcuate(lhn, op, rhn)
  return op(lhn, rhg)
end

def add(lhn, rhn)
  return lhn + rhn
end

def sub(lhn, rhn)
  return lhn - rhn
end

puts calculate(1, add, 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do these really require comments? Tests? Wouldn&apos;t it actually &lt;em&gt;add&lt;/em&gt; to the technical debt to put those into place, since now they must be maintained and kept up to date should something change in here?&lt;/p&gt;
&lt;p&gt;I&apos;m obviously reaching here, but I don&apos;t think the point is entirely invalidated by the simplicity of my example---after all, well-written methods are supposed to be small and focused, and we prefer classes not to be large, and so on, for precisely these kinds of reasons.&lt;/p&gt;
&lt;h3&gt;Technical Debt: It&apos;s a metaphor, stupid&lt;/h3&gt;
&lt;p&gt;Go back to Wikipedia for a second; there, they finish the definition&apos;s first paragraph with this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If the debt is not repaid, then it will keep on accumulating interest, making it hard to implement changes later on. Unaddressed technical debt increases software entropy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;See, this is the heart of the matter: technical debt is a metaphor. That&apos;s it. That&apos;s all it is. It&apos;s a literary mechanism designed to help people who are not programmers understand that there are decisions made during the development process of a project, decisions which are deliberate choices to take a shortcut or avoid a more generic solution in the interests of getting past the obstacle quickly.&lt;/p&gt;
&lt;p&gt;Except that nothing ever remains &amp;quot;just&amp;quot; a metaphor in our industry. Inevitably, we have to dissect it, treat as if it were a real, in-the-room-with-us kind of thing, and start crusades &amp;quot;for&amp;quot; or &amp;quot;against&amp;quot; it. Because REASONS.&lt;/p&gt;
&lt;p&gt;And I admit, I&apos;m not immune to this tendency myself. Because in examining a metaphor, so long as we recognize it&apos;s a metaphor and therefore bound to fail at some point (the model is not reality), we can actually find some interesting edge-cases that may or may not apply, and that leads us to some interesting conversations about the concept, even if it doesn&apos;t fit the metaphor anymore.&lt;/p&gt;
&lt;h3&gt;Technical Debt: A Fowlerian Definition&lt;/h3&gt;
&lt;p&gt;Martin Fowler has gone into great detail about the different kinds of technical debt in the form of a &lt;a href=&quot;http://martinfowler.com/bliki/TechnicalDebtQuadrant.html&quot;&gt;debt quadrant&lt;/a&gt;, arranged along two axes of &amp;quot;Deliberate vs Inadvertent&amp;quot; against &amp;quot;Reckless vs Prudent&amp;quot;.&lt;/p&gt;
&lt;p&gt;I like this, simply by virtue of the fact that it captures the mindset of the developer or the team at the time they were making that decision.&lt;/p&gt;
&lt;p&gt;But I &lt;em&gt;don&apos;t&lt;/em&gt; like it because, well, because who cares what they were thinking, or why? Isn&apos;t technical debt just technical debt? I mean, that $50 purchase on your credit card, was it a measured and thoughtful purchase, perhaps some tools at the local hardware store, so that you can perform some home repais, or was it a reckless and idiotic purchase, perhaps some tools at the local hardware store, so that you can pretend to yourself that you&apos;re actually going to take this weekend and perform some home repairs, but deep down you know you&apos;re just fooling yourself, you&apos;ll never get it done, and the tools will now be left to rust in a quiet corner of the garage (or worse, you&apos;ll leave them out in the backyard and it rains and and and)?&lt;/p&gt;
&lt;p&gt;Seriously: the guy who wrote that &lt;code&gt;do-while&lt;/code&gt; loop at Intuit? I have no idea what he was thinking---and did that intent really make a helluvalot of difference to me (or the rest of the team) as I (we) tried to pick it up and extend/modify/debug it? I won&apos;t speak for the rest of the team, but to me, it made not a single whit of difference.&lt;/p&gt;
&lt;p&gt;But here&apos;s the vastly more important thing to realize about debt: At the end of the day, &lt;em&gt;you still owe $50&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Wherever that debt appears on Fowler&apos;s quadrant, you still have to pay it off. Or it will gather interest, and eventually (if you leave it long enough) bankrupt you.&lt;/p&gt;
&lt;p&gt;Granted, this is perhaps where that metaphor starts to wear a little thin. In a codebase, where we perhaps deliberately chose not to use a Strategy pattern, but instead just coded the algorithm by hand directly into the code, because we don&apos;t really see any need for any greater degree of flexibility, we have potentially amassed some (perhaps small) amount of technical debt. The $50 hammer, if you will.&lt;/p&gt;
&lt;p&gt;In a traditional credit card scenario, that $50, compounded at 5% or 10% interest, will, without exception, eventually turn into a monstrous pile of debt that you cannot pay off, assuming you leave it unpaid for that long.&lt;/p&gt;
&lt;p&gt;But that non-Strategized algorithm? So long as the client requirements don&apos;t change, there&apos;s not a thing wrong with it. It can continue to run, and run, and run, until the heat death of the universe, and nothing happens.&lt;/p&gt;
&lt;p&gt;This suggests to me that technical debt isn&apos;t just about what the developers on the team at the time were thinking about. This suggests that technical debt has two more components to it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The thoughts of the developer(s) who have now inherited the code.&lt;/li&gt;
&lt;li&gt;The requirements (or lack thereof) of the project for which the code was written.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See, if the client never changes their requirements, &lt;em&gt;there is no technical debt&lt;/em&gt;. So long as the code continues to run, without problem, then what the code looks like is entirely irrelevant. It&apos;s only when the client says, &amp;quot;OK, now we need to do this other thing with this codebase&amp;quot; that it becomes a problem.&lt;/p&gt;
&lt;p&gt;Although, now that I write this, I realize that&apos;s not entirely accurate, either.&lt;/p&gt;
&lt;p&gt;If the client&apos;s requirements haven&apos;t changed, but the code doesn&apos;t run, or runs into errors while running? Those are bugs, and the code needs to change (to remove the bug). And that&apos;s the other case where now, a developer struggling to understand the code in which the bug may (or may not) live will be running into difficulty. Enter technical debt again.&lt;/p&gt;
&lt;p&gt;Which now suggests that technical debt is essentially &amp;quot;a developer&apos;s cognitive difficulty in understanding and/or modifying a codebase&amp;quot;. Nothing to do with the decisions made at the time of the codebase&apos;s creation, and everything to do with the developer who is attempting to understand what the code is trying to do or how to modify it.&lt;/p&gt;
&lt;h3&gt;Technical Debt: Moving on&lt;/h3&gt;
&lt;p&gt;So does @kellan (and Peter Norvig) have it right, that &amp;quot;code is a liability&amp;quot;?&lt;/p&gt;
&lt;p&gt;On the surface of it, maybe: if I write code, it is &lt;em&gt;potential&lt;/em&gt; technical debt.&lt;/p&gt;
&lt;p&gt;See, it&apos;s not technical debt yet, because it won&apos;t actually be a debt until we trigger the &amp;quot;understanding and/or modifying&amp;quot; clause of the above. The Ruby script I hacked together to transform my old blog&apos;s XML over to Markdown files for the new system, I won&apos;t know whether that code is technical debt until I (or anybody else who wants to use or modify it) go back into it again and face the cognitive load of understanding  it or modifying it. So it&apos;s like the infamous cat in the box, neither debt nor not, until the box is opened.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Logging Hours</title>
      <link>http://blogs.newardassociates.com/blog/2016/logging-hours.html</link>
      <pubDate>Mon, 18 Jan 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/logging-hours.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;tl;dr&lt;/em&gt; A recent DZone post lamented how logging hours makes the author &amp;quot;die a little inside each time&amp;quot;. I used to feel the same way. Then I grew up and got over it.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;As is typical with my posts, I ask you to &lt;a href=&quot;https://dzone.com/articles/why-does-logging-hours-feel-so-offensive&quot;&gt;go read the original&lt;/a&gt; (or in this case, the DZone copy of the original) before proceeding much further; I&apos;ll quote it, but it&apos;s always better to have the source freshly in mind when reading the rebuttal.&lt;/p&gt;
&lt;p&gt;And it is a rebuttal; just not necessarily aimed at him.&lt;/p&gt;
&lt;h3&gt;The act&lt;/h3&gt;
&lt;p&gt;The author, Matthew Casperson, opens with:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Friday afternoon rolls around, and the obligatory call for weekly hours goes out. “Make sure your hours are up to date!” And I die a little inside. In truth, assigning hours to tickets is not actually that much work. As I have been told many times over, logging hours can’t take much more than a few minutes. So why does this simple act of corporate obedience feel like I have just been beaten over the head?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;He then goes on to cite four main reasons why this &amp;quot;simple act of corporate obedience&amp;quot; makes him feel &amp;quot;beaten over the head&amp;quot;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;Because it feels so pointless.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Because it feels like a lack of trust.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Because I don&apos;t know where these numbers go.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Because it feels like a lazy management technique.&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;He goes on to explain each of those four points in some detail, but I think the points pretty well stand for themselves in summary form.&lt;/p&gt;
&lt;p&gt;Truth be told, I have a hard time arguing with him. Or, rather, the version of me from about a decade ago has a hard time arguing with him. Filling out timesheets felt so pointless and stupid, why bother? What if I just totally randomized the numbers and sent that in? Would anybody actually notice? (Nobody ever did, by the way.)&lt;/p&gt;
&lt;p&gt;But the 2016 version of me will, actually, argue this with him. Part of it is simply professionalism---if the client or your employer says to do this thing, you do it, because it&apos;s simply the professional thing to do. (And I have every reason to believe that Matthew is being a professional and doing it, lest there be any doubt there.)&lt;/p&gt;
&lt;p&gt;More importantly, the 2016 version of me will also turn around and argue this for him, because everything he says screams out to me that his management is Failing him.&lt;/p&gt;
&lt;p&gt;Utterly, completely, and totally Failing him.&lt;/p&gt;
&lt;p&gt;With a capital &amp;quot;F&amp;quot;.&lt;/p&gt;
&lt;h3&gt;Management Failures&lt;/h3&gt;
&lt;p&gt;Let&apos;s start with the simple one first: When an employee talks about an act as being a &amp;quot;lack of trust&amp;quot;, usually that suggests that other factors are in play. Matthew writes, &amp;quot;... all this work and effort feels completely undermined by management asking for an hour by hour account of my day. Am I that bad at my job that you really feel the need to know where every hour of it was spent?&amp;quot;&lt;/p&gt;
&lt;p&gt;This is a smell that suggests that there is more at work here than just the logging of hours; employees do not feel  distrusted simply because management wants a time accounting. (There&apos;s good reasons for wanting this, which I&apos;ll get to in a second.)&lt;/p&gt;
&lt;p&gt;This is a smell that suggests that &lt;em&gt;the employees don&apos;t trust management&lt;/em&gt;. It&apos;s really that simple; trust, like most relationships, operates on a &amp;quot;bank account&amp;quot; kind of principle, and if employees are feeling like the trust account is a little low, then it&apos;s really up to managers to (a) recognize that, and (b) work to put some trust back into the account. (Of course, that does go both ways, which is what makes relationships hard.)&lt;/p&gt;
&lt;p&gt;This is emphasized by his last point, about logging hours as being a &amp;quot;lazy management technique&amp;quot;. Listen to what he says next: &amp;quot;Meaningless numbers being interpreted in secret ways by management that never speaks to me....&amp;quot; Wow. Matthew&apos;s management has a serious problem on their hands. &amp;quot;Meaningless&amp;quot;, &amp;quot;secret&amp;quot;, &amp;quot;never speaks to me&amp;quot;, those are three red flags in just the first half of a single sentence. This is a statement of pure opinion, despite the allusion to factual studies about employee disillusionment that follows in that paragraph, but the fact is, &lt;em&gt;employee feelings are just as legit as fact&lt;/em&gt;. The fact that an employee feels disrespected is every bit as important as whether or not they actually ever were. Emotions are real things, and need to be treated as such.&lt;/p&gt;
&lt;p&gt;I think a lot of the management Failure here stems from his third point.&lt;/p&gt;
&lt;p&gt;When an employee sees an act that &amp;quot;feels so pointless&amp;quot;, it&apos;s because they don&apos;t see any value within the act. If it&apos;s an act that doesn&apos;t generate value to them, then management has Failed in a pretty simple way:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Management has not explained what these numbers are for.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Honestly, when I was managing consultants working for the consulting company, it was painfully obvious where the numbers  were going---these were billable consultants, and so their hourly reports were going directly into the invoices that we  were sending to the client for payment. When we asked them to put a little explanation around their time, it was almost  always met with nods of recognition, because they could easily understand why those might be needed.&lt;/p&gt;
&lt;p&gt;But suppose you&apos;re not working for a consulting company---why track the numbers?&lt;/p&gt;
&lt;h4&gt;Velocity&lt;/h4&gt;
&lt;p&gt;As a manager, I can certainly see a desire for those numbers---without those numbers and how they relate to story points or features, I can&apos;t really effectively track my team&apos;s ratio of estimation to actual.&lt;/p&gt;
&lt;p&gt;And that ratio is actually very, very important.&lt;/p&gt;
&lt;p&gt;Because when I&apos;m called into a meeting with other departments (or other clients), and they start tossing off what they want us to work on next, I&apos;m often asked to provide a ballpark estimate for how long this thing might take. &amp;quot;Oh, we know, it&apos;s just a ballpark estimate/SWAG, we won&apos;t hold you to it,&amp;quot; they always say, but truth is, once a number gets named, it tends to &amp;quot;stick&amp;quot; and become the measuring stick against which all other things are discussed.&lt;/p&gt;
&lt;p&gt;At that moment, my goal as a manager is to protect my team from an unachievable schedule---that is, quite frankly, the most important thing I will do all day that day. I can&apos;t just toss off a &amp;quot;oh, sure, whatever, let&apos;s say.... six months?&amp;quot; with a cavalier wave of my hand, because chances are I&apos;m totally underestimating the work on so many different levels. My first reaction must be to stall, distract, and delay, until I can get a reasonable estimate to them.&lt;/p&gt;
&lt;p&gt;(By the way, it&apos;s not unreasonable for them to want an estimate---contrary to the beliefs of the &amp;quot;No Estimate&amp;quot; movement  that is currently making the rounds. Modern budgetary accounting requires some idea of what it will cost up front, before you commit to the purchase. Think about it this way: How many of you would buy a car with no idea of the price, agreeing to send a certain amount of money to the dealership every month until the dealer told you that was enough? It&apos;s a complete and deliberate &amp;quot;head in the sand&amp;quot; rejection of how 99.9% of the world&apos;s corporate budgeting and internal accounting works.)&lt;/p&gt;
&lt;p&gt;Now this doesn&apos;t mean I need to create estimates down to the final story---a SWAG is still appropriate here. But if I have that velocity metric, I can take a couple of hours, do a rough pass over what they want, come up with a number of stories or feature points that are within the same order of magnitude (hopefully) of the actual result, and then multiply that times our velocity to have a first-pass SWAG that at least puts it in the right ballpark.&lt;/p&gt;
&lt;p&gt;But that&apos;s just me.&lt;/p&gt;
&lt;h4&gt;Pulse&lt;/h4&gt;
&lt;p&gt;In some cases, managers use these numbers as a sanity-check, a way of feeling out how the team is doing, without having to tear them away from their actual work with one-on-one meetings. Think about it this way: which is less intrusive to you as a programmer, to spend a few minutes at the end of the week to fill out a simple report that will give me a high-level view of what you&apos;re doing (and by the way, why are you spending so much time debugging? Didn&apos;t we get that super-nasty bug fixed last week? I think I need to follow up with you), or would you rather pull yourself away from your desk for an hour a week so you and I can go over all of that in person, when you will probably forget half of the details that would show up in a report?&lt;/p&gt;
&lt;p&gt;Personally, I don&apos;t like the reporting approach---I would much rather have the one-on-ones, because then we can talk about a bunch of things that wouldn&apos;t normally go into a status report. (Actually, I tend to do both---at the consulting company, I looked at the submitted timesheets, and had one-on-ones with the team leads, so that I could both passively get a feel for what was going on, and then validate---or not---that same feel via an active conversation.)&lt;/p&gt;
&lt;p&gt;Is this an act of lazy management? Maybe. But what developers need to realize is that developing software is not like constructing a building or a house, because 98% of what they do is entirely ephemeral and very difficult for anybody else to see, even other software developers. (Try it sometime---observe what another developer is doing and the progress they are making without talking to them about it directly, and then try to describe what progress you&apos;ve seen them make or not make. Even with rigorous source control practices and team-wide discipline around check-ins and merges, it&apos;s really, really hard.) If you&apos;re not a software developer, trying to understand what your team did today can be almost downright impossible without asking them.&lt;/p&gt;
&lt;p&gt;So they ask them, in the form of a report.&lt;/p&gt;
&lt;h4&gt;Other reasons&lt;/h4&gt;
&lt;p&gt;Perhaps Matthew&apos;s manager isn&apos;t in the same position that I am, or isn&apos;t asked (and held) to estimates that early in the process. Why, then, might the numbers be necessary?&lt;/p&gt;
&lt;p&gt;I could posit a few theories (Accounting needs them in order to know how to charge time against internal budgeting reports, or HR needs them to feed into the payroll system so that they can keep track of your vacation time, or the CTO wants a roll-up report each year of how much time was spent on different activities within his organization because he is convinced they are spending way too much time in debugging and maintenance and he needs those numbers so he can go to the CEO and the board and ask for a larger budget to accomodate their requests for the next fiscal year, or...), but any theory I come up with is entirely just a flight of fancy, and entirely irrelevant; the point is not why &lt;em&gt;I&lt;/em&gt; think the numbers are important, but that Matthew&apos;s management has not said why &lt;em&gt;they&lt;/em&gt; think the numbers are important.&lt;/p&gt;
&lt;p&gt;Of course, the other possibility is that the management Failure occurs much, much higher up, and that this time-tracking was established by the previous (or the previous previous) CTO, and right now those numbers just go into a report that nobody ever reads. Which is its own management Failure.&lt;/p&gt;
&lt;h3&gt;History&lt;/h3&gt;
&lt;p&gt;Napoleon Bonaparte, one of history&apos;s greatest generals, was less fond of the precise marching orders than the various generals (particularly the Prussians) that he faced. His approach was far &amp;quot;looser&amp;quot; (and arguably much more agile); he would split his army into pieces, and to each of his Field Marshals he would give certain tasks.&lt;/p&gt;
&lt;p&gt;But before he turned them loose, he would also make sure that each of the Field Marshals also understood what the overall goal of the campaign was: &amp;quot;We must take that town there before we move on the city, so that we have a place by which to set up the cannons to bombard the walls.&amp;quot;, for example. In this way, when he turned them all loose, they all understood the larger picture. Then, when one saw an opportunity to further the overall strategic goal, they could act on it quickly, without having to send a messenger back to Napoleon himself to find out if that was something they should do. If the town in question lay open and undefended according to their scouting reports, they could dispatch a battalion or two to seize it and hold it. Then, when the rest of the French moved into their various positions, the town was already seized, and Napoleon could advance his plans that much more quickly.&lt;/p&gt;
&lt;p&gt;Management that fails to explain the &amp;quot;Why&amp;quot; of a particular policy is effectively falling into that most heinous of management Failures, that of treating their employees like cogs. No, employees can&apos;t (and shouldn&apos;t) know everything that a manager knows---certain things, for legal and privacy reasons, must remain confidential. Lots of data about the company must remain in the hands of only a certain few.&lt;/p&gt;
&lt;p&gt;But the hours policy is very, very likely not to be one, and it&apos;s even more highly likely that even if there are places where these numbers go that the employees can&apos;t/shouldn&apos;t know about, there&apos;s other reasons that we can talk about, to give them a sense of &amp;quot;why&amp;quot;, and let them see that those few minutes spent every Friday to fill out the damn timesheet actually serves a useful purpose, &lt;em&gt;even if it&apos;s not useful to them personally&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Because being told to do something that serves no useful purpose to anyone simply undermines your credibility as a manager. And that&apos;s probably the worst management Failure of them all.&lt;/p&gt;
&lt;h3&gt;Postscript&lt;/h3&gt;
&lt;p&gt;Just after I posted this, there was an email from the Harvard Business Review entitled, &amp;quot;The Best Bosses Follow These 5 Rules&amp;quot;, and they read like a complete counterpoint to everything Matthew described:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Manage individuals, not just teams.&lt;/strong&gt; When you’re under pressure, you can forget that employees have varying interests, abilities, goals, and styles of learning. But it’s important to understand what makes each person tick so that you can customize your interactions with them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Go big on meaning.&lt;/strong&gt; Inspire people with a vision, set challenging goals, and articulate a clear purpose. Don’t rely on incentives like bonuses, stock options, or raises.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Focus on feedback.&lt;/strong&gt; Use regular (at least weekly) one-on-one conversations for coaching. Make the feedback clear, honest, and constructive.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don’t just talk — listen.&lt;/strong&gt; Pose problems and challenges, and then ask questions to enlist the entire team in generating solutions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be consistent.&lt;/strong&gt; Be open to new ideas in your management style, vision, expectations, and feedback. If change becomes necessary, acknowledge it quickly.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If Matthew&apos;s management adopted these five, particularly #1, #2 and #3, they would immediately seek to manage him as an individual, which would lead them to finding out more about what makes him tick, and that would lead them to following up on the time reports. They would seek to provide a sense of meaning around those silly reports, and his feedback could go into perhaps even making the reports better, depending on what the reports are actually used for.&lt;/p&gt;
&lt;p&gt;Most of all, if they were good bosses, they&apos;d be embracing #5, and we probably wouldn&apos;t have had to have this little conversation.&lt;/p&gt;
&lt;p&gt;Good chat.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Maybe is Selfish</title>
      <link>http://blogs.newardassociates.com/blog/2016/maybe-is-selfish.html</link>
      <pubDate>Fri, 15 Jan 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/maybe-is-selfish.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Don&apos;t hedge your answers when somebody is asking you for a commitment; &amp;quot;Do, or do not. There is no try.&amp;quot; (Yoda) Saying &amp;quot;maybe&amp;quot; is, at best, your way of preserving your ego, and at worst, your way of trying to avoid a commitment.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Michele Leroux Bustamente &lt;a href=&quot;https://twitter.com/michelebusta/status/688165138524798976&quot;&gt;tweeted&lt;/a&gt; her fondness for &lt;a href=&quot;https://leadershipfreak.wordpress.com/2015/12/10/22893/&quot;&gt;this article&lt;/a&gt;, and while I agree with the author&apos;s premise, I disagree with some of the reasoning and rationale, and with some of the proposed recommendations on how to proceed.&lt;/p&gt;
&lt;h3&gt;Critique #1: &apos;Maybe&apos; means ...&lt;/h3&gt;
&lt;p&gt;To start, the author says (complete with snowy-dog meme picture that doesn&apos;t seem to have anything to do with the actual text), &amp;quot;You can’t execute on  maybe. You say maybe because you falsely believe it’s  helpful. In reality, you need to be liked. ... You say maybe because you want to feel included and important without encumbering yourself.&amp;quot;&lt;/p&gt;
&lt;p&gt;Actually, my experience with people who waffle on these answers suggests some far more subtle things are at stake here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Isn&apos;t it kinder?&lt;/em&gt;&lt;/strong&gt; I don&apos;t want to say &amp;quot;no&amp;quot; out loud because, well, &amp;quot;no&amp;quot; just has such a bad reputation. I mean, &amp;quot;no&amp;quot; is the equivalent of rejection, and who really likes rejection, right? Isn&apos;t it &lt;em&gt;kinder&lt;/em&gt; to give them an ambiguous answer so that they can walk away with their pride intact?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;I don&apos;t know if I can.&lt;/em&gt;&lt;/strong&gt; Wow, your request challenges me, and I&apos;m genuinely not sure if I can do it. It&apos;s potentially something I could do, but there&apos;s obstacles, including but not limited to: my time, my skills, and/or my faith that I could really do it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;I KNOW I can&apos;t do it, but I don&apos;t want you to think less of me.&lt;/em&gt;&lt;/strong&gt; My ego&apos;s on the line here, somehow, and while I don&apos;t want to agree, and have you hold me accountable when I fail later, I also don&apos;t want to disagree and then have to explain why I&apos;m saying no. (A lot of software developers fall into this one, it seems.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;I don&apos;t believe in what you&apos;re doing.&lt;/em&gt;&lt;/strong&gt; Yeah, that experiment you&apos;re running that will generate all kinds of money playing the stock market? Yeah, apparently the only one who doesn&apos;t know you&apos;re full of shit is you, and I don&apos;t really want to be the one to tell you.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;I don&apos;t think you&apos;ll actually execute.&lt;/em&gt;&lt;/strong&gt; You&apos;ve had all these requests before, and they never actually amounted to anything, and rather than argue with you about it, it&apos;s easier to just toss off a &amp;quot;maybe&amp;quot; and remain ambiguous.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;I really don&apos;t want to be responsible for this.&lt;/em&gt;&lt;/strong&gt; What you are proposing is a thing that might backfire, and if it does, I don&apos;t want to be in the backdraft when it blows up.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&apos;m sure there&apos;s other reasons, too. Those are what leaped to mind first.&lt;/p&gt;
&lt;h3&gt;Critique #2: &apos;Maybe&apos; is harmful&lt;/h3&gt;
&lt;p&gt;He continues: &amp;quot;Every time you say maybe, you paralyze others. Should we find someone to do the job, or will you? Will you feel offended if you show up and someone else has filled your role?&amp;quot;&lt;/p&gt;
&lt;p&gt;Partial agreement; in some cases, you&apos;re paralyzing the other with your maybe, but in most cases, it&apos;s a far different problem.&lt;/p&gt;
&lt;h3&gt;Interlude: 50 Shades of &apos;Maybe&apos;&lt;/h3&gt;
&lt;p&gt;By the way, there&apos;s more than one way to say &amp;quot;maybe&amp;quot;; the author points out four, but there&apos;s literally thousands:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;If I can.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;I’ll do my best.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;I’d like to, but I’m not sure...&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;If I don’t show up, move forward without me.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;It&apos;s distinctly possible.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;I can see both sides.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;That&apos;s an interesting idea, but...&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Have you gotten approval for this yet?&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;... and so on. One of my favorites, of course, is the classic &amp;quot;Go ask your mother.&amp;quot; Or its corollary, &amp;quot;If it&apos;s OK with (somebody else), it&apos;s OK with me.&amp;quot;&lt;/p&gt;
&lt;h3&gt;Problem: Not committing creates miscommunication&lt;/h3&gt;
&lt;p&gt;It&apos;s been my experience that a &amp;quot;maybe&amp;quot;&apos;s biggest problem is the fact that &lt;em&gt;people will hear whatever they want to hear&lt;/em&gt;, so if you come back with a &amp;quot;maybe&amp;quot;, those who want to hear &amp;quot;yes&amp;quot; will hear it, and those who want to hear &amp;quot;no&amp;quot; will hear it. We learn this very quickly as parents:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Kid&lt;/strong&gt;: &amp;quot;Mommy, can I have a pony?&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mom&lt;/strong&gt;: &amp;quot;Maybe someday, dear...&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kid&lt;/strong&gt;: &lt;em&gt;thinking&lt;/em&gt; That&apos;s not a no! That means yes! Hooray!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What&apos;s even better about it, &amp;quot;maybe&amp;quot;, when interpreted this way as an answer, has the pleasing short-term effect to us of making the questioner go away! Success! Our answer actually accomplished more than what we thought it would do, so internally we reinforce the logic we used from the earlier list above (kinder/don&apos;t know/don&apos;t believe/whatever), and we will start going to it even more often.&lt;/p&gt;
&lt;p&gt;At least, until it blows up on us.&lt;/p&gt;
&lt;h3&gt;Problem: The time bomb of percevied commitment&lt;/h3&gt;
&lt;p&gt;Because that&apos;s the lurking danger: &amp;quot;Maybe&amp;quot; is a ticking time bomb of perceived commitment, and a lurking miscommunication waiting to happen, which will usually end in bad emotional juju between these two people, and potentially a lot more (depending on the situation):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Employee&lt;/strong&gt;: &amp;quot;Hey, boss, can I have that promotion?&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Boss&lt;/strong&gt;: &amp;quot;Maybe somebody, Bob...&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Employee&lt;/strong&gt;: &lt;em&gt;thinking&lt;/em&gt; Wow! He thinks I could do it! I mean, he didn&apos;t say &amp;quot;yes&amp;quot;, but he can&apos;t really commit to it right now since there&apos;s all this HR nonsense he has to go through, but if he didn&apos;t think I was right for it, he&apos;d have just said so, right?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Employee&lt;/strong&gt;: (later that night at home) &amp;quot;Honey, guess what? My boss thinks I&apos;m good for that promotion! Go ahead and book the expensive vacation to Hawaii, we&apos;re going to celebrate!&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then, when the miscommunication becomes clear, Really Bad Things come to roost. I don&apos;t have to draw an example---I&apos;m sure each reader has their own story they can draw on.&lt;/p&gt;
&lt;h3&gt;Problem: Honesty and reputation&lt;/h3&gt;
&lt;p&gt;&amp;quot;Maybe&amp;quot; has another nasty side effect---when that time bomb finally does go off, and you are presented with the need to clarify your &amp;quot;maybe&amp;quot;, usually in the opposite result than what the requestor assumed, you will develop a reputation in their mind for being dishonest.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Employee&lt;/strong&gt;: &amp;quot;Hey, boss, can I have that promotion?&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Boss&lt;/strong&gt;: &amp;quot;Maybe somebody, Bob...&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;(Three months pass...)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Boss&lt;/strong&gt;: &amp;quot;And I&apos;m proud to announce that Janet has received the promotion.&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Employee&lt;/strong&gt;: &lt;em&gt;thinking&lt;/em&gt; THAT DICK! He promised it to ME! OK, boss-man, you want to play it that way? Fine, two can play at that game, you back-stabbing liar.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the conversation ever goes to a verbal one, you will be on the defensive immediately, and you will have to remember that you said &amp;quot;maybe&amp;quot;, first of all, and then, be placed in the unenviable position of having to explain---now, while emotions are running high---what you &amp;quot;really meant&amp;quot; by that &amp;quot;maybe&amp;quot;.&lt;/p&gt;
&lt;p&gt;These conversations generally don&apos;t end well.&lt;/p&gt;
&lt;h3&gt;Solution: Commit&lt;/h3&gt;
&lt;p&gt;Frankly, the answer to the problem lies in the realization that not committing is not acceptable. And &amp;quot;committing&amp;quot; here doesn&apos;t mean &amp;quot;yes&amp;quot;; yes, there&apos;s a group of people out there who believe you should say &amp;quot;yes&amp;quot; to everything because then your life is far more interesting and challenging than if you didn&apos;t (and they even made a move out of it), and frankly, yes, you should take a few chances here and there, I agree.&lt;/p&gt;
&lt;p&gt;But what I&apos;m talking about here is more fundamental: &lt;strong&gt;commit&lt;/strong&gt; to either a &amp;quot;yes&amp;quot; or a &amp;quot;no&amp;quot;. It&apos;s harder, but it&apos;s more honest, and yes, sometimes it requires you to face that argument up front that might get pushed off to later if you just do a &amp;quot;maybe&amp;quot;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Kid&lt;/strong&gt;: &amp;quot;Mommy, can I have a pony?&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mom&lt;/strong&gt;: &amp;quot;No, dear. Horses are expensive, you&apos;re too young, and we live in an apartment.&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kid&lt;/strong&gt;: &amp;quot;WAAAAAH!&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Having said that, though, sometimes we can actually get to a better result by being honest this way:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Kid&lt;/strong&gt;: &amp;quot;Mommy, can I have a pony?&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mom&lt;/strong&gt;: &amp;quot;No, dear. Horses are expensive, you&apos;re too young, and we live in an apartment.&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kid&lt;/strong&gt;: &amp;quot;WAAAAAH! You think I&apos;m not old enough to have a pet!&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mom&lt;/strong&gt;: &amp;quot;Oh, dear, is that what this is about? Tell you what---let&apos;s start with a goldfish, and if you take good care of it for a year, we can talk about getting a kitten or puppy after that, OK?&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kid&lt;/strong&gt;: &lt;em&gt;sniffling&lt;/em&gt; &amp;quot;But why can&apos;t I have a kitten or puppy NOW?&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mom&lt;/strong&gt;: &amp;quot;I need you to show me you&apos;re responsible enough to remember your chores before I can feel good about getting you something that will depend on you more.&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now we&apos;re getting somewhere. The communication is clear, unambiguous, and direct. And what&apos;s better, you don&apos;t have the uncomfortable situation of being forced to explain a miscommunication later.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Employee&lt;/strong&gt;: &amp;quot;Hey, boss, can I have that promotion?&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Boss&lt;/strong&gt;: &amp;quot;Wow, Bob, I didn&apos;t know you were interested. Hmm. Here&apos;s the thing: you&apos;re missing some of the key skills that promotion would require, and I&apos;m not certain you&apos;d have a chance to demonstrate those skills before the promotion date closes. As it stands right now, no, I wouldn&apos;t give it to you.&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Employee&lt;/strong&gt;: &amp;quot;Oh. Wow.&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Boss&lt;/strong&gt;: &amp;quot;That said, Bob, I like that you&apos;re interested in growing your career, and &lt;a href=&quot;https://rework.withgoogle.com/guides/managers-care-professionally-personally-for-team/steps/introduction/&quot;&gt;that&apos;s part of what I&apos;m here for&lt;/a&gt;, so let&apos;s you and I start talking about how we can get you those skills so that you&apos;re primed for the next opportunity that arises. Would that work for you?&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Employee&lt;/strong&gt;: &amp;quot;Oh! Wow! Yeah, that&apos;s great!&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Net result: positive progress, and crystal-clear perspective.&lt;/p&gt;
&lt;h3&gt;Solution: How to Commit&lt;/h3&gt;
&lt;p&gt;The original author offers a list of very New-Age-ish &amp;quot;Follow your energy&amp;quot; stuff that I don&apos;t find particularly helpful. (And I find his &amp;quot;Execute on compassion&amp;quot; to be particularly dangerous, since---as mentioned above---most people think the compassionate thing to do is to say &amp;quot;maybe&amp;quot; rather than &amp;quot;no&amp;quot;.)&lt;/p&gt;
&lt;p&gt;Here&apos;s my list of suggestions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Don&apos;t answer right away.&lt;/em&gt;&lt;/strong&gt; These questions often come out of nowhere, and most of us don&apos;t wake up in the morning and contemplate all the answers to the questions we might be asked today. So give yourself a moment to think about it first. &amp;quot;Wow Bob, I didn&apos;t know you were intersted. Hmmm.&amp;quot; Then, just shut up and think.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;What does your intuition tell you?&lt;/em&gt;&lt;/strong&gt; Our intuition is pretty often accurate, so at least take a moment to reflect on what it&apos;s telling you. It&apos;s not the complete answer, but it&apos;s a good sign that this is where your heart wants to go.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Spend a few minutes weighing pro and con.&lt;/em&gt;&lt;/strong&gt; What would be the result if you said yes? What would be the result if you said no? How does this decision actually affect anything? If we discover that the answer is pretty trivial, then &lt;em&gt;pffft&lt;/em&gt; who cares? Go with yes. (Why yes? Because of that earlier &amp;quot;always answer yes&amp;quot; thing---it turns out that if there&apos;s not much downside, your life will probably be more interesting if you go with &amp;quot;yes&amp;quot; than &amp;quot;no&amp;quot;. &lt;em&gt;Carpe diem&lt;/em&gt;, man.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Express your commitment clearly.&lt;/em&gt;&lt;/strong&gt; The words &amp;quot;yes&amp;quot; or &amp;quot;no&amp;quot; should show up there somewhere. Forcing yourself to say &amp;quot;yes&amp;quot; or &amp;quot;no&amp;quot; makes your communication that much more clear, and that much less ambiguous. It will not always go over well, but it&apos;s far better to just take the bitter medicine now than let it fester, ferment, and get that much more bitter (and that much larger!) in the future.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Be willing to express your rationale.&lt;/em&gt;&lt;/strong&gt; Notice that I say &amp;quot;rationale&amp;quot; there, instead of &amp;quot;reasons&amp;quot;. &amp;quot;Reason&amp;quot; is something that implies logic and fact, and sometimes, you just simply don&apos;t &lt;em&gt;want&lt;/em&gt; to do this. That&apos;s OK! Sometimes, we don&apos;t want to do things. I don&apos;t want to eat broccoli. My kids don&apos;t want to do homework. Heck, &lt;em&gt;I&lt;/em&gt; don&apos;t want to do homework. And those are legitimate feelings, so long as they&apos;re taken into consideration appropriately. &amp;quot;Honey, Daddy just hates horses. Can&apos;t stand them. If you want to get a horse when you move out of the house, that&apos;s up to you, but that&apos;s just not something I&apos;m going to let in while I&apos;m living here.&amp;quot; They may disagree with it, and want to claim that your feelings are misplaced or that you should be able to set those aside for the good-of-whatever, but now at least we&apos;re being clear about what&apos;s going on, and that allows the conversation to move to a new level of communication.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;&apos;Maybe&apos;s are for emotional wimps&lt;/h3&gt;
&lt;p&gt;In the end, really, the use of a &amp;quot;maybe&amp;quot; is your way of wimping out of something you don&apos;t want to do, and not only are you trading off pain now for pain later, but you&apos;re also not being honest with anybody---not the questioner, and not with yourself. You&apos;re selling your own feelings and decision-making process short, and you&apos;re setting yourself up for a harder process later.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Do, or do not. There is no try.&amp;quot;&lt;br /&gt;
---Yoda&lt;/p&gt;
&lt;p&gt;&amp;quot;Do, or do not. There is no maybe.&amp;quot;&lt;br /&gt;
---Me&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Just commit.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>A Good TechBlog Read</title>
      <link>http://blogs.newardassociates.com/blog/2016/a-good-tech-blog.html</link>
      <pubDate>Thu, 14 Jan 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/a-good-tech-blog.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; I&apos;ve found a new blog that I&apos;m enjoying reading so far, and thought readers might want to browser-bookmark for future consumption.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Twitter sometimes dumps some good stuff into my face, and in this case, this comes to me via James Ward over Facebook. (I think he posted it to Twitter and it echoed to his Facebook feed, but details, details. I saw it through Facebook, so Facebook gets the credit.)&lt;/p&gt;
&lt;p&gt;Meet &lt;a href=&quot;http://techblog.realestate.com.au&quot;&gt;TechBlog&lt;/a&gt;. I have no idea who they are other than what I see on the website---my guess is that they&apos;re an online real-estate system of some fashion, but whether that&apos;s as a competitor to &lt;a href=&quot;http://www.redfin.com&quot;&gt;Redfin&lt;/a&gt; or something, I really can&apos;t say. But their blog is a very nice mix of technical topics, and the writing is quite well-done. Consider this list of posts that I flagged just browsing the first three pages of the site:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://techblog.realestate.com.au/how-we-used-category-theory-to-solve-a-problem-in-java/&quot;&gt;&amp;quot;How We Used Category Theory To Solve A Problem In Java&amp;quot;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://techblog.realestate.com.au/business-friendly-functional-programming-part-1-asynchronous-operations/&quot;&gt;&amp;quot;Business-Friendly Functional Programming Part 1: Asynchronous Operations&amp;quot;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://techblog.realestate.com.au/painless-javascript-testing-surely-you-jest/&quot;&gt;&amp;quot;Painless Javascript Testing? Surely You Jest&amp;quot;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://techblog.realestate.com.au/static-analysis-whats-it-good-for/&quot;&gt;&amp;quot;Static Analysis: What&apos;s It Good For?&amp;quot;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://techblog.realestate.com.au/devopsdays-2015-as-a-graduate/&quot;&gt;&amp;quot;DevOpsDays2015 As a Graduate&amp;quot;&lt;/a&gt;. This one deserves a little more explanation as to why I flagged it, and that explanation comes right away in the second paragraph, which I thought was a great &amp;quot;catch&amp;quot;: &amp;quot;So what is DevOps? Nobody really knows yet, not even the engineers supposedly belonging to this group can concisely explain what it is. The scope of the word has grown unwieldy, despite its state of infancy. In fact, the crowd seem to hate the very use of the word. Everyone pauses and takes time to punctuate each mention of the phrase DevOps with a facetious “air-quotes” gesture.&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://techblog.realestate.com.au/minimising-build-time-with-recursive-containers/&quot;&gt;&amp;quot;Minimising Build Time With Recursive Containers&amp;quot;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In particular, James linked to the first post (the category theory one), and it&apos;s a good read. I still don&apos;t claim to completely understand the mojo and mystery around monads, monoids, category theory, endofunctors and all that other jazz, but the author does a great job of setting up the real-world business problem, then talking about the abstract stuff (the basics of monoids and functors), then talking about how this can be used to solve their problem, complete with Java interface examples, and builds up from there. It&apos;s a very well-written piece, and maybe finally I begin to understand the ideas here better.&lt;/p&gt;
&lt;p&gt;I don&apos;t know who these folks are, but damn, I&apos;m impressed. Not that the random musings of a longhaired geek in Seattle makes all that much difference to them, I imagine, but well done, folks, and I&apos;ll be looking to consume more of your posts over the next several months, so keep &apos;em coming!&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Death to Technical Monoculture</title>
      <link>http://blogs.newardassociates.com/blog/2016/the-death-of-the-monoculture.html</link>
      <pubDate>Wed, 13 Jan 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/the-death-of-the-monoculture.html</guid>
      	<description>
	&lt;p&gt;It&apos;s really starting to appear like the &amp;quot;technical monoculture&amp;quot; that so pervaded the 90&apos;s and 00&apos;s is finally starting to die the long-deserved ugly death it was supposed to. And I couldn&apos;t be happier.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;I was sitting with a buddy of mine in a sports bar.&lt;/p&gt;
&lt;p&gt;(Yes, it was &lt;a href=&quot;http://canyonsrestaurant.com/&quot;&gt;Canyons&lt;/a&gt;. For those who don&apos;t know me too well, it&apos;s one of my favorites here in town---not that I really use it for a sports bar, &lt;em&gt;per se&lt;/em&gt;, but because they are a good group of folks who have nice large wall-mounted TVs that we can remote into using GoogleCast from a laptop, which means, combined with their WiFi, copious outlets and a nice space in the back where we&apos;re more or less isolated from the rest of the crowd, I have a perfect place to host the &lt;a href=&quot;www.meetup.com/SeaLang&quot;&gt;SeaLang meetups&lt;/a&gt;, yay. What&apos;s better than learning about new programming languages? Why, learning about new programming languages with beers, nom-noms, and Diet Coke!)&lt;/p&gt;
&lt;p&gt;He happens to work for Microsoft, and we were commenting on how Microsoft really seems to be getting their mojo back, and a lot of it stems from the fact that Microsoft internally is really starting to embrace things outside of the traditional Microsoft sphere of influence. Case in point: Azure. If you&apos;re running on Azure, you have your choice of just about anything you can name as your programming language of choice (C# and Visual Basic, of course, but also Java---which will include pretty much anything that compiles to JVM bytecode, so throw in Scala, Groovy, Clojure, Kotlin, and a few more---and PHP and NodeJS, and ...) to use. They&apos;re embracing different data stores, too. And---and be honest, how many of you ever thought you&apos;d see this---you can run Linux VMs on Azure to host all of this stuff if you want, so anything that Azure doesn&apos;t host &amp;quot;natively&amp;quot; can always be running inside of a VM.&lt;/p&gt;
&lt;p&gt;The interesting thing about this conversation was that it really became apparent to us that the traditional &amp;quot;Microsoft shop&amp;quot; (of which, not surprisingly, Microsoft has long been one) is essentially an endangered species. No longer will it really be acceptable for a developer to &amp;quot;just&amp;quot; know Windows, C#, and SQL Server. You&apos;re going to need to know a whole lot more than that, because frankly, there&apos;s a lot of tools out there that are actually better than anything Microsoft offers natively. Redis, for example; there&apos;s no equivalent that I&apos;ve found to Redis in the &amp;quot;Microsoft world&amp;quot;, and frankly, why should I have to settle for an equivalent? If I like Redis, and it seems useful, why in Heaven&apos;s name shouldn&apos;t I be able to use it? Just host it in Azure in a Linux VM, and keep going.&lt;/p&gt;
&lt;p&gt;But this street isn&apos;t entirely one-way. When the Pandora&apos;s box on the JVM got blown off (thanks to  AspectJ, which not only suggested that &amp;quot;objects are everything&amp;quot; was a fallacy, but also that one could run multiple languages on top of this virtual machine, and it could be a Good Thing), it opened a lot of Java developers&apos; eyes to the fact that Java wasn&apos;t, perhaps, the last programming language they would ever use. And now, with the CoreCLR migrating to other platforms, coupled with the fact that the C# language is actually kind of a nice language to use....&lt;/p&gt;
&lt;p&gt;Couple that with &lt;a href=&quot;www.xamarin.com&quot;&gt;Xamarin&lt;/a&gt; being able to cross-compile to different mobile platforms, or &lt;a href=&quot;www.rubymotion.com&quot;&gt;RubyMotion&lt;/a&gt; being able to do the same, and....&lt;/p&gt;
&lt;p&gt;Oh, and toss in that recent announcement about Apple and Android for good measure...&lt;/p&gt;
&lt;p&gt;Yeah. It&apos;s something of a new world.&lt;/p&gt;
&lt;p&gt;As someone who&apos;s spent a decade and a half talking about interoperability across platforms, it&apos;s somewhat gratifying to see all of this starting to take shape. Scary, too, I&apos;ll grant you, if you&apos;re one of those people who&apos;s always felt that they could just learn the one thing and then go out and be emplyable forever.&lt;/p&gt;
&lt;p&gt;But this is coming, and you have essentially only a few choices: Fight it (and essentially lose, since there&apos;s no signs that this is ever going to change), ignore it (and essentially become obsolete over time), or embrace it.&lt;/p&gt;
&lt;p&gt;I think it fairly clear which path &lt;em&gt;I&lt;/em&gt; choose. And to the best of my ability, I will help you if you choose it, too.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Happy People Still Do Quit</title>
      <link>http://blogs.newardassociates.com/blog/2016/happy-people-still-do-quit.html</link>
      <pubDate>Fri, 8 Jan 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/happy-people-still-do-quit.html</guid>
      	<description>
	&lt;p&gt;Twitter leads me to some interesting blog entries sometimes, and this time, it led to me to &lt;a href=&quot;https://twitter.com/rands&quot;&gt;@rands&lt;/a&gt;&apos;s entry entitled&lt;a href=&quot;http://randsinrepose.com/archives/shields-down/&quot;&gt;Shields Down&lt;/a&gt;, which appears to have the subtitle &amp;quot;Happy People Don&apos;t Leave the Jobs They Love&amp;quot;. In it, he&apos;s got some good discussion about being a manager and the realization that by the time of the exit interview, it&apos;s already way too late for him to &amp;quot;save&amp;quot; his employee from leaving. Or that, in fact, it starts much, much earlier than that.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;He begins by essentially pointing out that when you get that email from your friend, who says, &amp;quot;Hey, dude, you should totally come check out this place where I&apos;m working right now&amp;quot; and you agree to it, your &amp;quot;shields are down&amp;quot;. This is his code-phrase for &amp;quot;you are now considering leaving your place of employment&amp;quot;.&lt;/p&gt;
&lt;p&gt;Umm.... yeah.&lt;/p&gt;
&lt;h3&gt;Shields down! Oh noz!&lt;/h3&gt;
&lt;p&gt;Here&apos;s my first disagreement with him:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Technology employees are always considering leaving their place of employment.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Seriously. If you&apos;re in this industry for any length of time, you&apos;ve done the math, and realized that there&apos;s far more jobs out there than people to fill them, particularly if you&apos;re a programmer and have just a few precious years of experience under your belt--those with zero years have a harder time of it, for sure, but it&apos;s still a lot easier than people with zero years of experience and an Ancient Languages degree, even if it&apos;s a Master&apos;s or something.&lt;/p&gt;
&lt;p&gt;This is not a hard rationale to follow: These are highly analytical people we&apos;re talking about, and they are fully capable of looking around and seeing their co-workers jump out of one thing and land into another. Couple with that the fact that most programmers are paid far better than anyone of equivalent experience in other industries--all the lawyers who are making six digits immediately within two years of graduation of law school, please raise your hand?--and you begin to realize that for the average tech employee, &lt;em&gt;their shields were already down&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;All that email from their buddy did is make them realize that there was maybe an option a little closer to home than they might have thought otherwise; all that means is that they are simply one step closer to a new gig than they thought they&apos;d be, and they don&apos;t even have to engage with a recruiter if they don&apos;t want to.&lt;/p&gt;
&lt;p&gt;(By the way, how incredibly arrogant is it of us as an industry to be all up in arms over recruiters calling us--dare I say &lt;em&gt;pestering&lt;/em&gt; us--about finding a new job? Seriously, folks, sure, it&apos;s a PITA when they&apos;re spamming your Inbox, but it&apos;s really no worse than Viagra ads, and FFS, quit being such primma donnas. You really want to be in an industry where there &lt;em&gt;aren&apos;t&lt;/em&gt; recruiters constantly chasing you? Go take up a job working in Ancient Languages for a while, or maybe Astronomy or some other academically-dominated field, where the ratio of jobs to candidates is like 1-to-10. You&apos;re like the hot girl in high school who is constantly complaining to all of her friends how all these cute boys just won&apos;t leave her a-LONE, for crying out loud. Cry me a river.)&lt;/p&gt;
&lt;h3&gt;The Algorithm of Job Switching +3, vorpal blade&lt;/h3&gt;
&lt;p&gt;Rands goes on to suggest that upon shields-down status, people start going through a pretty complex set of questions:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When you are indirectly asked to lower your shields, you immediately parse, place a value, and aggregate your opinions on the following:&lt;br /&gt;
* Am I happy with my job?&lt;br /&gt;
* Do I like my manager? My team?&lt;br /&gt;
* Is this project I’m working on fulfilling?&lt;br /&gt;
* Am I learning?&lt;br /&gt;
* Am I respected?&lt;br /&gt;
* Am I growing?&lt;br /&gt;
* Do I feel fairly compensated?&lt;br /&gt;
* Is this company/team going anywhere?&lt;br /&gt;
* Do I believe in the vision?&lt;br /&gt;
* Do I trust the leaders?&lt;/p&gt;
&lt;p&gt;... you use that blend and ask yourself one final question as you consider lowering your shields. &lt;em&gt;What has happened recently or in the past that either supports or detracts from what I value?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The answer to that question determines whether your shields stay up or go down.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here&apos;s the thing: that is a hell of a list to end up with an all-yes set of answers. Honestly, I don&apos;t think there&apos;s ever been a job, ever, that would yield a 100% &amp;quot;yes&amp;quot; rate. Particularly when we start with &amp;quot;Am I happy with my job?&amp;quot;; that&apos;s sort of the roll-up question that is the sum total of all of the other answers. You&apos;re happy with your job if you like your team, your manager, you&apos;re doing fulfilling work, and so on.&lt;/p&gt;
&lt;p&gt;Were I to take this checklist to anyone--and I do mean anyone--I suspect the answers will inevitably come to some percentage of &amp;quot;yes&amp;quot;, and some percentage of &amp;quot;no&amp;quot;. (And that&apos;s assuming all of the answers are intrinsically binary, which I don&apos;t really believe to be the case.) It&apos;s like trying to go up against a windmill with a lance, or an orc trying to win a battle against a warrior (of any level) wielding a +3 longsword, vorpal blade.&lt;/p&gt;
&lt;p&gt;When faced with such staggering odds, the answer is a foregone conclusion. So, again, &lt;strong&gt;employees&apos; shields are already down&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;The Interrogation&lt;/h3&gt;
&lt;p&gt;He goes on to do the human thing: &amp;quot;Each time [a co-worker leaves] I work to understand two things: Why are they leaving? When did their shields go down?&amp;quot;&lt;/p&gt;
&lt;p&gt;He points out that #1 is the smooth, practiced answers that they use to convince themselves that this is the right thing for them to do. But he wants to drill into the successor: When did their shields go down? What was the critical moment?&lt;/p&gt;
&lt;p&gt;I can answer #2 for you. Matter of fact, I already have: &lt;strong&gt;their shields were always down&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;What follows, though, is best left in his own words:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To find and understand this shields-down moment, I ask, “When did you start looking?” Often the answers are a vague, “It kind’a just happened. I wasn’t really looking. I’m really happy here.”&lt;/p&gt;
&lt;p&gt;Bullshit.&lt;/p&gt;
&lt;p&gt;If I’m sitting here talking with you it means two things: I don’t want you to leave and, to the best of my knowledge, you didn’t want to leave either but here you are leaving. It didn’t just happen. You chose. Maybe you weren’t looking, but once your shields dropped, you started looking. Happy people don’t leave jobs they love.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;He&apos;s spot-on with this assessment: you made a choice to interview somewhere else, you made a choice to evaluate their offer, you made a choice to accept the offer and all the &amp;quot;transitions&amp;quot; that are involved (changing your daily routine, changing your work friends, working to discover what the new lunch options are, and so on), so it didn&apos;t &amp;quot;just kinda &lt;em&gt;happen&lt;/em&gt;&amp;quot; any more than that Hollywood starlet &amp;quot;just kinda happened&amp;quot; to be naked in bed with her co-star while her boyfriend was a continent away. Choices are choices.&lt;/p&gt;
&lt;p&gt;What sort of concerns me the most, though, is his conclusion:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The reason this reads cranky is because I, the leader of the humans, screwed up. Something in the construction of the team or the company nudged you at a critical moment. When that mail arrived gently asking you about coffee, you didn’t answer the way you answered the prior five similar mails with a brief, &amp;quot;Really happy here. Let’s get a drink some time!&amp;quot; You think you thought &lt;em&gt;Hmmm… what the hell. It can’t hurt.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;What you actually thought or realized was:&lt;br /&gt;
* You know, I have no idea when I’m going to be a tech lead here.&lt;br /&gt;
* Getting yelled at two days ago still stings.&lt;br /&gt;
* I don’t believe a single thing senior leadership says.&lt;/p&gt;
&lt;p&gt;Often you’ve forgotten this original thought in your subsequent intense job deliberations, but when I ask, when I dig, I usually find a basic values violation that dug in, stuck, and festered. Sometimes it’s a major values violation from months ago. Sometimes it’s a small violation that occurred at the worst possible time. In either case, your expectations of your company and your job were not met and when faced with opportunity elsewhere, you engaged.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Rands, I&apos;m going to pop a bubble here for a second: &lt;em&gt;It&apos;s not you, man.&lt;/em&gt; (Or, maybe, perhaps, it&apos;s just &lt;em&gt;just&lt;/em&gt; you, man.)&lt;/p&gt;
&lt;h3&gt;The Contract&lt;/h3&gt;
&lt;p&gt;When somebody comes to work for me, there&apos;s an implicit--and I try to make it explicit--contract that we establish: You tell me what you want, and I will do everything in my power, within the boundaries of my authority and what&apos;s practical for the company, to help you get it.&lt;/p&gt;
&lt;p&gt;That first part is where things need to be more clear: you need to tell me. You want that tech lead promotion? OK, let&apos;s talk about what that means, what skills you need to have in order to take that job, and what of those skills you currently lack or need to brush up on. More importantly, if we don&apos;t have room for a new tech lead, no matter how badly you wnt it, no matter how skilled you are at being a tech lead, I can&apos;t give you that promotion.&lt;/p&gt;
&lt;p&gt;Shields down? Of course. So what? Employees&apos; shields are always down, remember? They were down yesterday, and the day before that.&lt;/p&gt;
&lt;p&gt;(Don&apos;t believe me? Quick, all you technical types: hands up if you&apos;ve &lt;strong&gt;NEVER&lt;/strong&gt; thought, &amp;quot;Damn, that guy from Vietnam &lt;a href=&quot;http://blogs.marketwatch.com/themargin/2014/02/10/iphone-with-killed-flappy-bird-reaches-80000-on-ebay/&quot;&gt;made like a million dollars making Flappy Bird&lt;/a&gt;, and I&apos;m still here writing code for the TPS reports. I wonder....&amp;quot;)&lt;/p&gt;
&lt;p&gt;So your shields are down? Well, it &lt;em&gt;is&lt;/em&gt; a Friday. So what?&lt;/p&gt;
&lt;p&gt;Rands seems to treat this moment with fear, as something to be avoided.&lt;/p&gt;
&lt;p&gt;I don&apos;t fear that moment. Matter of fact, I personally embrace it.&lt;/p&gt;
&lt;h3&gt;Managing a shields-down team&lt;/h3&gt;
&lt;p&gt;I admit, I&apos;m fairly new to this management thing. But there&apos;s a few things I&apos;m pretty sure about, and so far (2 years, and running) it&apos;s worked out pretty well.&lt;/p&gt;
&lt;p&gt;If the place for which I work doesn&apos;t currently have the opportunities for you, then I think it&apos;s my job as your manager--an individual who should be responsible for not just making sure you get your work done on time, but is also interested and responsible in your job and career growth--to help you find the challenges you want and/or need.&lt;/p&gt;
&lt;p&gt;Yes, this means it&apos;s my job as your manager to help you find something outside of the current workplace sometimes. Or, at the very least, not stand in your way.&lt;/p&gt;
&lt;p&gt;Because, to be really blunt about it, I can&apos;t do the kinds of constant scrutiny that Rands holds himself accountable for:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;I’ve been here for three years and I’m looking for a change of scenery.&lt;/strong&gt; It happens. Two months ago, someone told them their project was likely to be canceled. It wasn’t.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I have no idea what I as their manager was supposed to do: cancel the project anyway? The business makes decisions based on the business&apos; needs, not the needs of the individual contributors on those projects. Any business that didn&apos;t make decisions that way would very quickly be out of business.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;You know, I have no idea when I’m going to be a tech lead here.&lt;/strong&gt; At the end of last month, she heard via the grapevine that she wasn’t going to be promoted. When she got the promotion she deserved, it was too late.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Did she ask about the promotion? Did she come to me and say, &amp;quot;Hey, Ted, I&apos;m really interested in taking that tech lead role?&amp;quot; Did we discuss her current qualifications and how she could put herself into the best possible position to take it? Was I responsible for choosing who received that position? And did I communicate to her why she didn&apos;t receive it, if she didn&apos;t get it?&lt;/p&gt;
&lt;p&gt;I&apos;m in the enviable position right now of having a dozen people working for me, most of whom are easily tech leads. They&apos;re sharp, they&apos;re self-directed, they can see the forest for the trees, and I don&apos;t have enough teams on which to make them all leads. We&apos;ve rotated a few around, and we&apos;re trying to grow the firm, but if one of them comes to me and says, &amp;quot;Dude, I am &lt;em&gt;really&lt;/em&gt; ready to be a tech lead, and I won&apos;t take no for an answer&amp;quot;, then the only option is to help them find that role, outside of the firm if need be.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Getting yelled at two days ago still stings.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You know what? If I yelled at you, then yeah, that means something really went south. Don&apos;t get me wrong, I&apos;ll hold you accountable if you screw up, but there&apos;s really no reason for any one adult human being to be yelling at another one unless somebody&apos;s life is on the line. And if I didn&apos;t come to you afterwards to apologize and clear the elephant out of the room, then that&apos;s on me. I would &lt;em&gt;like&lt;/em&gt; if you would come to me and say, &amp;quot;Hey, Ted? The other day, when things got a little heated, I thought you were a little harsh and I didn&apos;t appreciate it&amp;quot; so we can sort that out, but that&apos;s only going to happen if you&apos;re comfortable doing so, and if you&apos;re not, then our work relationship was already in jeopardy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;I don’t believe a single thing senior leadership says.&lt;/strong&gt; At the last All Hands, I blew off a question with a terse answer because I didn’t want to dignify gossip. I forgot there is signal even in gossip.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Rands, give yourself a pass here. Employees don&apos;t reach that level of distrust based on one blow-off. (Not unless they were significantly cynical to begin with, anyway, which is its own problem.) If you have a continuous history of blowing people off, that&apos;s another problem entirely. And they may trust you, but not your management--and there&apos;s not a damn thing in the universe you can do about that.&lt;/p&gt;
&lt;p&gt;More importantly, you can&apos;t dignify gossip, but you can&apos;t stop it, either. When I do a one-on-one with my folks, I even explicitly ask them, &amp;quot;Are there any myths, legends, lore or gossip you want me to confirm or deny?&amp;quot;, because employees talk, and I want to give them a chance to air that stuff out and get an answer from me. But, again, I&apos;ll have my limits--sometimes I don&apos;t know the answer, and sometimes I can&apos;t say the answer. Case in point:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;Are we going to land that new client?&amp;quot; Frankly, I don&apos;t know. Things may look good (or they may look bad, or they may not look like anything at all), but nothing&apos;s a given until paper is signed. I&apos;ll let you and everybody else know when I do. If you want my personal opinion, though, it sounds relatively positive (or negative, or the conversation went way south when they started talking bill rates in the pennies per hour, or...),  but that&apos;s just my opinion. &lt;em&gt;[UPDATE 2021: Note that this does not take into account that there are always some topics I simply cannot speak to, for legal and/or liability reasons. I usually try to make it clear when we&apos;ve hit one of those topics by saying, &amp;quot;I can&apos;t speak to that because of legal and/or liability reasons&amp;quot; and I&apos;ve never had an employee disblieve me when I do.]&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&amp;quot;What happened to Bob? Why isn&apos;t he here anymore?&amp;quot; Ah, that&apos;s an HR thing, and I can&apos;t really comment on it, sorry. Suffice it to say we had an issue, and we (the leadership) felt it necessary to take that step. (Assuming Bob was fired, of course, and didn&apos;t leave of his own accord.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&apos;m a manager, not God.&lt;/p&gt;
&lt;h3&gt;The Contract, Redux&lt;/h3&gt;
&lt;p&gt;If you work for me, it&apos;s simple: You tell me what makes you happy, and if I can make it happen for you, I will make it happen. But:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;... you have to tell me.&lt;/strong&gt; Ask my wife, I am not a very good mind reader.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;... you have to accept that I am not a miracle worker.&lt;/strong&gt; Giving you what you want has to be within the company&apos;s and my boundaries to grant. I can&apos;t let you work from home on a regular basis if we have needs that require you to be in the office (whatever those may be). I can&apos;t get you onto a project using F# (no matter how much I may want to!) if we don&apos;t have any projects that are using F#. I can&apos;t get you a pony. I have my limitations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;... you have to keep up your end of the deal.&lt;/strong&gt; We have &lt;a href=&quot;http://www.pluralsight.com&quot;&gt;Pluralsight&lt;/a&gt; subscriptions for all of our employees--you can&apos;t tell me you don&apos;t feel like you&apos;re not getting enough learning in your job if you&apos;re not taking advantage of that. Sorry.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And in return for all that, it is my job to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Give you autonomy.&lt;/strong&gt; I hired you because you&apos;re a professional, and you&apos;ll get the job done. So it&apos;s my job to stay out of your way, until you need me to get into the fray and clear out an obstacle before you that you can&apos;t clear out yourself (or would cost exponentially more to handle than if I did it).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Grow your competency.&lt;/strong&gt; You&apos;re not a fixed &amp;quot;resource&amp;quot; (Lord how I hate that word), you&apos;re a human being, and no matter how competent you are currently, you can be better. Part of my job is to help you grow your own competency, even if it far surpasses my own.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Help you relate.&lt;/strong&gt; You&apos;re not an island, and you&apos;re not a cog. You are part of a team of people working on a project, even if you&apos;re working alone for a while. If you &amp;quot;fit&amp;quot; within the team, and the team is &amp;quot;connected&amp;quot;, that&apos;s going to be a huge factor in your willingness to stay and contribute. If you don&apos;t fit, then it&apos;s my job to do what I can to help find a way for you to fit, whether that&apos;s helping you adjust to the team, or helping the team adjust to you.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If I&apos;m not doing these things, then I&apos;ve broken my end of the contract, and you should be out looking for other places to work.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE 2021:&lt;/strong&gt; Netflix recently has come out saying that they tell their employees that if a recruiter calls, take the call, so that Netflix can use that as a way to judge what the market looks like. I like it, and I&apos;ve adopted it. It&apos;s the best way to make sure your employees are comfortable, by making it clear that you trust our relationship enough to not only freak out about them interviewing--but encourage it.&lt;/p&gt;
&lt;p&gt;And honestly, if they find a place that&apos;s ultimately going to be better for them, I wouldn&apos;t want to stand in their way of taking it up. Would you want to work for somebody who would?&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Clausewitz on Policy (Software Craftsmanship)</title>
      <link>http://blogs.newardassociates.com/blog/2016/software-policy.html</link>
      <pubDate>Wed, 6 Jan 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/software-policy.html</guid>
      	<description>
	&lt;p&gt;As many readers know, I didn&apos;t spend my collegiate years studying algorithms; instead, I obtained my degree from &lt;a href=&quot;http://admissions.ucdavis.edu/majors/major_view.cfm?major=lire&quot;&gt;UCDavis in International Relations&lt;/a&gt; with an emphasis on military strategy and history. That meant a tremendous amount of study in history, pyschology, a little philosophy, and military affairs.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;One of the great books on strategy, &lt;a href=&quot;http://www.amazon.com/Strategy-Meridian-B-Liddell-Hart/dp/0452010713/ref=sr_1_1&quot;&gt;Strategy&lt;/a&gt;, written shortly after the end of World War Two, was widely considered to be Hart&apos;s best work on the subject, though he had plenty to say before the book&apos;s publication; the great German general Guderian was quoted as having studied Hart prior to the war&apos;s outbreak. He&apos;s a pretty easy read, too, by the way, as historians and military advisory goes.&lt;/p&gt;
&lt;p&gt;Recently (for a variety of reasons) I picked it back up again. The first 75% of the book is about war throughout history, as a means of establishing Hart&apos;s backdrop for the theory that he advocates in the latter quarter of the book. The closer he gets to WW2, the more detailed his analysis and history, so it&apos;s not really a comprehensive study of military history by a long shot, but it&apos;s still more than most students of American education have ever received.&lt;/p&gt;
&lt;p&gt;The last quarter, though, is where he expounds on &amp;quot;The Theory of Strategy&amp;quot;, and in the opening paragraphs, he makes a very salient point about war, strategy, and one of its finest writers (Clausewitz) and how a misinterpretation of writing can lead to all kinds of problems.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Let us first be clear as to what is strategy. Clausewitz, in his monumental work, &lt;em&gt;On War&lt;/em&gt;, defined it as &apos;the art of the employment of battles as a means to gain the object of war. In other words strategy forms the plan of the war, maps out the proposed course of the different campaigns which compose the war, and regulates the battles to be fought in each.&apos;&lt;/p&gt;
&lt;p&gt;One defect of this definition is that intrudes on the sphere of policy, or the higher conduct of the war, which must necessarily be the responsibility of the government and not of the military leaders it employs as its agents in the executive control of operations. Another defect is that it narrows the meaning of &apos;strategy&apos; to the pure utilization of battle, thus conveying the idea that battle is the only means to the strategical end. It was an easy step for Clausewitz&apos;s less profound disciples to confuse the means with the end, and to reach the conclusion that in war every other consideration should be subordinated to the aim of fighting a decisive battle. (&lt;em&gt;Strategy&lt;/em&gt;, p. 319)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&apos;s been a while since I read Hart, but as soon as I read it, my mind did a double-take. Substitute &amp;quot;information technology strategy&amp;quot; for &amp;quot;policy&amp;quot;, &amp;quot;software project&amp;quot; for &amp;quot;war&amp;quot;, &amp;quot;sprints&amp;quot; for &amp;quot;battles&amp;quot;, &amp;quot;executive team&amp;quot; for &amp;quot;government&amp;quot;, &amp;quot;software craftsmen&amp;quot; for &amp;quot;military leaders&amp;quot;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Let us first be clear as to what is strategy. Clausewitz, in his monumental work, &lt;em&gt;On Software Projects&lt;/em&gt;, defined it as &apos;the art of the employment of battles as a means to gain the object of a software project. In other words strategy forms the plan of the software project, maps out the proposed course of the different campaigns which compose the software project, and regulates the sprints to be fought in each.&apos;&lt;/p&gt;
&lt;p&gt;One defect of this definition is that intrudes on the sphere of information technology strategy, or the higher conduct of the software project, which must necessarily be the responsibility of the executive team and not of the software craftsmen it employs as its agents in the executive control of operations. Another defect is that it narrows the meaning of &apos;IT strategy&apos; to the pure utilization of sprints, thus conveying the idea that sprints are the only means to the IT strategical end. It was an easy step for Clausewitz&apos;s less profound disciples to confuse the means with the end, and to reach the conclusion that in war every other consideration should be subordinated to the aim of fighting a decisive sprint. (&lt;em&gt;Strategy&lt;/em&gt;, p. 319)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Get where I&apos;m going with this? The construction of software is simply a tool--and not, by any stretch, the &lt;em&gt;only&lt;/em&gt; tool--by which a company can achieve its ends. Yes, bespoke software is often a powerful and useful tool for doing so, but so is a US Army Mobile Division. Sometimes, &amp;quot;sending in the troops&amp;quot; is an appropriate tool for use in a political situation, and sometimes, you have to hold back and try something else.&lt;/p&gt;
&lt;p&gt;Similarly, not all IT effort is around custom software development. There can be much utility in a small shell script that accomplishes a goal as there is in an &amp;quot;enterprise-scale&amp;quot; software project that comes complete with unit tests, continuous integration, and automated deployment.&lt;/p&gt;
&lt;p&gt;Certainly, the analogy isn&apos;t perfect--the insertion of a small SEAL team behind enemy territory requires a metric crap-ton of planning in the same way that loading up the US 5th Infantry and shipping them off to Korea requires. But, relatively speaking, it&apos;s a lot easier to dispatch SEAL Team Six to a hotspot to engage in a sharp, focused mission, than to dispatch even just one US regiment; the logistics are simply night-and-day different.&lt;/p&gt;
&lt;p&gt;During the &lt;a href=&quot;http://www.history.com/topics/korean-war&quot;&gt;Korean war&lt;/a&gt;, Gen MacArthur was vehement and loud that the US Army, after its incredibly successful amphibious landing at Inch&apos;on. MacArthur very clearly wanted to prosecute the war deep into Chinese territory, since that was the only way to win the war, and claimed that refusing to engage in this wider war was &amp;quot;appeasement&amp;quot;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As President Truman looked for a way to prevent war with the Chinese, MacArthur did all he could to provoke it. Finally, in March 1951, he sent a letter to Joseph Martin, a House Republican leader who shared MacArthur’s support for declaring all-out war on China–and who could be counted upon to leak the letter to the press. “There is,” MacArthur wrote, “no substitute for victory” against international communism.&lt;/p&gt;
&lt;p&gt;For Truman, this letter was the last straw. On April 11, the president fired the general for insubordination.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is an important moment in American history; there was serious concern that MacArthur would return home and stage a &lt;em&gt;coup d&apos;etat&lt;/em&gt;, seeking to replace Truman and secure his &amp;quot;no substitute&amp;quot;. Instead, MacArthur did what any professional does: he accepted the termination as Truman&apos;s right, and delivered one of the most moving speeches in American history.&lt;/p&gt;
&lt;p&gt;The point here was that MacArthur was one of Clausewitz&apos;s &amp;quot;less profound disciples&amp;quot;: he failed to understand that Truman&apos;s policy was NOT to seek a wider war with the communists, since that meant potentially taking on both China and the USSR, with a nation that had just emerged from a half-dozen years of armed conflict around the world, with not much in the way of allied support to do so. It would very likely have proven to be conclusively a massive disaster.&lt;/p&gt;
&lt;p&gt;There were very good reasons Truman and his Adminstration had that policy in place; MacArthur, however, sought to be the craftsman at his profession, and demanded that &amp;quot;if we&apos;re going to do this, we&apos;re going to do it &lt;em&gt;right&lt;/em&gt;&amp;quot;.&lt;/p&gt;
&lt;p&gt;Again, I laud and applaud the goals of the Software Craftsmanship movement, with its emphasis on quality and focus on &amp;quot;doing the right thing&amp;quot;. But then some of its leadership says things like &lt;a href=&quot;https://twitter.com/unclebobmartin/status/684778768196612098&quot;&gt;&amp;quot;Always remember that you, as a software developer, are also a stakeholder. You have a stake that you need to safeguard.&amp;quot;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m sorry, but no. You are not a stakeholder. You may have a vested interest, but those are different terms. You do not own the software you are creating. You are producing this for the use of people who are not you. You will walk away from this at some point, and never worry about this again. A stakeholder, on the other hand, according to &lt;a href=&quot;http://dictionary.reference.com/browse/stakeholder&quot;&gt;Dictionary.com&lt;/a&gt;, is &amp;quot;the holder of the stakes of a wager&amp;quot;.&lt;/p&gt;
&lt;p&gt;Unless that is your money you&apos;re paying yourself with, you are not a stakeholder.&lt;/p&gt;
&lt;p&gt;Now, I&apos;m pretty sure the Craftsmanship movement is going to jump on the second definition there, &amp;quot;a person or group that has an investment, share, or interest in something, as a business or industry&amp;quot;, and key in on that word &amp;quot;interest&amp;quot;, and say &amp;quot;We have an interest! That&apos;s OUR blood, sweat and tears, and that gives us an investment into it!&amp;quot;&lt;/p&gt;
&lt;p&gt;And by that definition, every person who works as a janitor in the Trump Towers has an investment in the building. So therefore they can sell off their share of that investment, right?&lt;/p&gt;
&lt;p&gt;Sorry, your blood, sweat, and tears were paid for. Your employer, your client, whomever it was that paid you to write this thing, &lt;em&gt;they&lt;/em&gt; have the investment, not you.&lt;/p&gt;
&lt;p&gt;You may have a sense of professional pride, and that&apos;s a good thing.&lt;/p&gt;
&lt;p&gt;But never conflate your professional pride with what it means to be the actual stakeholder in the project.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Story of the Chimps</title>
      <link>http://blogs.newardassociates.com/blog/2016/chimpanzees.html</link>
      <pubDate>Tue, 5 Jan 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/chimpanzees.html</guid>
      	<description>
	&lt;p&gt;Or, why passwords must be eight characters.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;This just crossed my Facebook feed:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Take five chimpanzees. Put them in a big cage. Suspend some bananas from the roof of the cage. Provide the chimpanzees with a stepladder. BUT also add a proximity detector to the bananas, so that when a chimp goes near the banana, water hoses are triggered and the whole cage is thoroughly soaked.&lt;/p&gt;
&lt;p&gt;Soon, the chimps learn that the bananas and the stepladder are best ignored.&lt;/p&gt;
&lt;p&gt;Now, remove one chimp, and replace it with a fresh one. That chimp knows nothing of the hoses. He sees the banana, notices the stepladder, and because he is a smart primate, he envisions himself stepping on the stepladder to reach the bananas. He then deftly grabs the stepladder... and the four other chimps spring on him and beat him squarely. He soon learns to ignore the stepladder.&lt;/p&gt;
&lt;p&gt;Then, remove another chimp and replace it with a fresh one. The scenario occurs again; when he grabs the stepladder, he gets mauled by the four other chimps -- yes, including the previous &amp;quot;fresh&amp;quot; chimp. He has integrated the notion of &amp;quot;thou shallt not touch the stepladder&amp;quot;.&lt;/p&gt;
&lt;p&gt;Iterate. After some operations, you have five chimps who are ready to punch any chimp who would dare touch the stepladder -- and none of them knows why.&lt;/p&gt;
&lt;p&gt;Originally, some developer, somewhere, was working on an old Unix system from the previous century, which used the old DES-based &amp;quot;crypt&amp;quot;, actually a password hashing function derived from the DES block cipher. In that hashing function, only the first eight characters of the password are used (and only the low 7 bits of each character, as well). Subsequent characters are ignored. That&apos;s the banana.&lt;/p&gt;
&lt;p&gt;The Internet is full of chimpanzees.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I first heard this story from Dave Thomas (&amp;quot;RubyDave&amp;quot;) at a NFJS show.&lt;/p&gt;
&lt;p&gt;Thing of it is, it applies to soooo much more than just the passwords-must-be-eight-characters rule. Dave used it to illustrate why &amp;quot;if&amp;quot; statements in so many languages require parentheses around the boolean condition they are testing -- until Ruby came along, anyway. Turns out it was a parser issue with an ancient predecessor to C, and nobody asked &amp;quot;why&amp;quot; ever since.&lt;/p&gt;
&lt;p&gt;The unwillingness to ask &amp;quot;why&amp;quot; certain things are the way that they are -- or perhaps the &amp;quot;shut up and sit down&amp;quot; reaction from the rest of the dev team when the question is asked -- is what leads to situations like this.&lt;/p&gt;
&lt;p&gt;It reminds me of another of my favorite stories:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A young couple are just married, and the starry-eyed husband, being in a delightfully pensive mood, decides to simply watch his new bride fix dinner one night. As she is preparing the roast, she slices off about an inch from either side of the roast and throws the perfectly good meat away.&lt;/p&gt;
&lt;p&gt;A little taken aback, the husband asks, &amp;quot;Honey, why do you do that?&amp;quot;&lt;/p&gt;
&lt;p&gt;She replies, &amp;quot;Because it makes the roast taste better, and besides, my mother always did it that way.&amp;quot;&lt;/p&gt;
&lt;p&gt;Intrigued, the husband calls his new mother-in-law and asks her if she does the same thing. When she says yes, he asks why, and she replies, &amp;quot;Because it makes the roast taste better, and besides, my mother always did it that way.&amp;quot;&lt;/p&gt;
&lt;p&gt;Now &lt;em&gt;really&lt;/em&gt; intrigued, he calls his grandmother-in-law, and asks her. When she says yes, he asks why.&lt;/p&gt;
&lt;p&gt;&amp;quot;Beacuse my pan is too small.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sorta makes you wonder: what does your team do because &amp;quot;it&apos;s always been done that way&amp;quot;?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE(2021):&lt;/strong&gt; Subsequent iterations of telling this story have led me to understand that, as with most great fairy tales, this didn&apos;t quite happen as written. &amp;quot;A quick search revealed there was a real experiment that seems to be the basis of the story, though that research didn&apos;t prove much. It was a small study in 1966 titled &lt;a href=&quot;http://www.scribd.com/doc/73492989/Stephenson-1966-Cultural-Acquisition-of-a-Specific-Learned-Response-Among-Rhesus-Monkeys&quot;&gt;&lt;em&gt;“Cultural acquisition of a specific learned response among rhesus monkeys”&lt;/em&gt;&lt;/a&gt; by Stephenson et al.&amp;quot; (from &lt;a href=&quot;https://www.linkedin.com/pulse/five-monkeys-experiment-john-stepper/&quot;&gt;https://www.linkedin.com/pulse/five-monkeys-experiment-john-stepper/&lt;/a&gt; ) In fact, &lt;a href=&quot;https://www.throwcase.com/2014/12/21/that-five-monkeys-and-a-banana-story-is-rubbish/&quot;&gt;this article&lt;/a&gt; suggests that it&apos;s not even close to true:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This story has been doing the rounds since 1996, and it has never been verified. It seems to have first appeared in a book called Competing For The Future by Gary Hamel and C. K. Prahalad, and by “appeared” I mean it was just made up. The authors never provided a source. None of the authors who have referred to the experiment in the past eighteen years have provided a source either. None of the appealing memes or infographics that describe the story now provide a source. Suffice to say, there is no source, because the experiment never happened.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;... and even quotes the first article in this paragraph as being partly responsible for the spread of false information:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A blogger by the name of John Stepper writes about how amazing the Talk was and how Eddie [Obeng] was able to bring this untrue story to life [in a TED talk]. He then asks if it really happened, and says: &amp;quot;A quick search reveals it did happen though the details are quite different.&amp;quot; ... This is perfectly true, if by “quite different” he really means “not the same at all, in any way.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sadly, the absence of anybody citing another study where this was done, conclusively, leads me to agree, &lt;strong&gt;&lt;em&gt;this experiment never, in fact, happened.&lt;/em&gt;&lt;/strong&gt; Which is both heartening and sad--sad, because it&apos;s a great story and tugs at the heartstrings, and heartening, because it suggests that the nature of &amp;quot;herd mentality&amp;quot; that we all fear so much may not be quite so much to fear.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2016 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2016/2016-tech-predictions.html</link>
      <pubDate>Mon, 4 Jan 2016 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2016/2016-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;As has become my tradition now for nigh-on a decade, I will first go back over last years&apos; predictions, to see how well I called it (and keep me honest), then wax prophetic on what I think the new year has to offer us.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2&gt;In 2015...&lt;/h2&gt;
&lt;p&gt;As per previous years, I&apos;m giving myself either a &lt;strong&gt;+1&lt;/strong&gt; or a &lt;strong&gt;-1&lt;/strong&gt; based on a purely subjective and highly-biased evaluational criteria as to whether it actually happened (or in some cases at least started to happen before 31 Dec 2015 ended).&lt;/p&gt;
&lt;p&gt;In 2015, I said:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;Big data&amp;quot;, &amp;quot;Big data&amp;quot;, &amp;quot;Big data&amp;quot;. You will get sick of this phrase.&lt;/strong&gt; I can&apos;t speak for everybody, but I can tell that the end is near for the term, because suddenly everybody is using the term, and they&apos;re using it to mean anything and everything. &amp;quot;Big data&amp;quot; is not just about doing deep data science analysis on petabytes of data; it&apos;s about any analysis (even simple reporting) on any collection of data (no matter how large or small) for any reason. &lt;strong&gt;+1&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;Internet of Things&amp;quot;. You will get sick of this phrase, too.&lt;/strong&gt; This hasn&apos;t quite happened yet, but we&apos;re close. IoT is also starting to fray at the edges as a definition, and when that happens, it&apos;s immediately ripe for abuse and marketing. More importantly, though, lots of people are starting to realize that IoT is neither the huge &amp;quot;automatic win&amp;quot; that we all sort of assumed it would become. &lt;strong&gt;+1&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;Internet of Medicine&amp;quot; or &amp;quot;Big Med&amp;quot;.&lt;/strong&gt; Well, nobody&apos;s started using the term yet, but certainly they&apos;re spending a lot of time in this space. They just don&apos;t like my term yet. I&apos;m pouting over it, but it&apos;s still a &lt;strong&gt;-1&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;Tech bubble&amp;quot; becomes a &amp;quot;thing&amp;quot;.&lt;/strong&gt; Oh, this one came down to the very wire, but as December of 2015 rolled in, concerns over the actual valuations of the so-called &amp;quot;unicorns&amp;quot; were starting to show up, and lots of people were beginning to openly wonder if Silicon Valley and Wall Street were experiencing a falling-out. It took a hail-mary pass to do it, but I&apos;m claiming my &lt;strong&gt;+1&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;C# and Java will both make big announcements.&lt;/strong&gt; C#6 shipped, but Java9 didn&apos;t, leaving me sort of confused as to how to score this one. However, I did say, &amp;quot;Those who care will  take note, those who don’t, won’t. Really, we’re kind of past the point where either of  those languages are going to be interesting to anyone who’s not already in that space&amp;quot;, and frankly, if you weren&apos;t a C# or Java developer, you probably didn&apos;t even hear a whisper about either one (pro/shipping or con/not-shipping), either way. &lt;strong&gt;+1&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Go is going to either take off, or crash and burn.&lt;/strong&gt; The point of this one was that Go was reaching an inflection point, and while I think it&apos;s gathering some momentum (including with me personally--this new blog is using Go to do the site generation), I can&apos;t really tell if it reached an inflection point, so &lt;strong&gt;-1&lt;/strong&gt; to me.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Microsoft acquires Xamarin.&lt;/strong&gt; Oh, as much as I thought (and still think) that it would be a great story for both sides, it didn&apos;t happen, and probably never will. &lt;em&gt;sigh&lt;/em&gt; &lt;strong&gt;-1&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Amazon just quietly keeps churning.&lt;/strong&gt; I dunno how I would measure this one, but in some ways, as long as Amazon just keeps churning out new feature after new feature on AWS, and keeps making money selling stuff on their main web property--which they continue to do--then I think pretty much anything here qualifies as a &lt;strong&gt;+1&lt;/strong&gt;. But it was kind of a lame prediction to begin with, now that I re-read it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Google continues to throw sh*t against the wall, looking for their Next Big Thing.&lt;/strong&gt; I believe the exact phrase I used was, &amp;quot;Expect a lot of announcements, a lot of &amp;quot;beta&amp;quot;s, and none of it with any kind of realistic or even well-planned business model behind it--including the Google Car.&amp;quot; And, sure enough, we&apos;ve heard a ton about the Google Car, among other initiatives, but nothing has stepped up as a product yet to even come close to acting as a second line of income for the firm. I call it an easy &lt;strong&gt;+1&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Web use on mobile devices decreases in favor of apps.&lt;/strong&gt; In particular, I said,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is going to happen whether the public wants it or not, because companies have figured out that it behooves them to have you &amp;quot;trapped&amp;quot; inside their app (where they can control all the content) rather than on their website. More and more websites are going to try and redirect you to inside their app, rather than allow you to casually browse on their site, because then they think they &amp;quot;own&amp;quot; your eyeballs. The only way this changes is if/when some firm gets crushed in the court of public opinion by doing something really stupid... and that won&apos;t happen in 2015. Wait for it in 2016.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Various &amp;quot;clickbait&amp;quot; sites were the ones I was thinking about in particular, and while some of them (I&apos;m looking at you, Uberfacts) have floated a mobile app out there, the apps themselves don&apos;t seem to be lighting any fires in the mobile marketplaces. I&apos;ll talk more about this in a bit, but for now, I&apos;m giving myself a &lt;strong&gt;-1&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Hipster &amp;quot;Uber for X&amp;quot; apps will be all the rage.&lt;/strong&gt; Have you been to San Francisco recently? Talked to anybody on the street there? This one was a slam-dunk &lt;strong&gt;+1&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mark Zuckerberg grows up a little.&lt;/strong&gt; Zuckerberg will never admit it, but now that he&apos;s married and starting a family and all, he&apos;s starting to grow up. His paternity leave step was a big one, and signals that maybe he&apos;s finally ready to &amp;quot;adult&amp;quot; now. If so, he&apos;s in good company--it took Bill Gates getting married and having kids to come in out of the rain, too, and ever since that time, Bill&apos;s become a philanthropist of the highest order. &lt;strong&gt;+1&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Larry Ellison buys a sports team.&lt;/strong&gt; Didn&apos;t happen yet. &lt;strong&gt;-1&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Perl makes one final gasp at relevancy, fails, and begins to decompose.&lt;/strong&gt; Oh, this one is funny; how could I be so right, and so wrong at the same time? Wrong, because Perl 6 actually&lt;br /&gt;
&lt;a href=&quot;https://perl6advent.wordpress.com/2015/12/25/christmas-is-here/&quot;&gt;finally shipped&lt;/a&gt;. And yet, so right because... well, how many people do you know using it? Or were even paying attention when it came out? Or.... Yeah. &lt;strong&gt;+1&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nine up, four down. Not bad.&lt;/p&gt;
&lt;p&gt;That was the easy part. Now, on to the....&lt;/p&gt;
&lt;h2&gt;2016 Predictions&lt;/h2&gt;
&lt;p&gt;In no particular order:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Microsoft will continue to roll out features on Azure, and start closing the gap between it and AWS.&lt;/strong&gt; This one is not hard to imagine. Microsoft is committed to making Azure a core part of their company success and survival, and Amazon has a list of features that Azure lacks, so it really boils down to &amp;quot;take one down, cross it off the list, lather, rinse, repeat&amp;quot;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;(X)-as-a-Service providers will continue to proliferate.&lt;/strong&gt; We&apos;re seeing a huge surge in these various companies that are providing some vertical thing as a service, and for most of those they&apos;re tech-related (such as Database-as-a-Service, Container-as-a-Service, and so on). Part of that is because if it&apos;s one thing software developer geeks know what to do, it&apos;s what they wish they had when they were working that last project and really wished they could have when they were working it. This coming year will mark the high-water mark of companies that provide *aaS products to the developer community, and then they&apos;ll all start cannibalizing each other and some shutdowns, acquisitions and partnerships will kick in.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple will put out two, maybe three new products, and they&apos;ll all be &amp;quot;meh&amp;quot; at best.&lt;/strong&gt; Let&apos;s be frank, folks, the luster is off the shiny Apple logo on the site of the building. Tim Cook is no Steve Jobs, and Apple of 2015 was not the Apple of 2005 or 2010. The Apple Watch is interesting, but it certainly hasn&apos;t taken off. No watch seems to have, in fact, become the &amp;quot;it&amp;quot; thing. I don&apos;t see many of them (or their Android competitors, to be fair) at tech conferences, and casually glancing around the airport doesn&apos;t show a ton of them in use. I don&apos;t think this is going to change any time soon, either. For most people, the wearable just hasn&apos;t really offered up that compelling reason yet, and I don&apos;t think 2016 is going to see one, either.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;iOS 10 will be called iOSX.&lt;/strong&gt; Just because they can, and because it would confuse the hell out of people, and because Steve Jobs is not here anymore to tell that VP of Marketing to sit down, shut up, and let the grown ups do this.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Android N will be code-named &amp;quot;Nougat&amp;quot;.&lt;/strong&gt; They might go with &amp;quot;Nutella&amp;quot;, but that would involve copyright and trademark issues, which I imagine they&apos;d want to avoid.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Java9 will ship.&lt;/strong&gt; This is a &amp;quot;no-duh&amp;quot; prediction, but I&apos;m not above claiming a few of those. Really, the bigger question there will be &lt;em&gt;what&lt;/em&gt; will ship that Oracle calls &amp;quot;Java9&amp;quot;, and my personal feeling is that modules/Jigsaw/whatever-we&apos;re-calling-them-now won&apos;t be in it. Slamming a module mechanism on top of a platform that&apos;s a decade old, millions of programmers wide and a billion lines of code high is not easy, and I don&apos;t think Oracle really has the energy, motivation or need to push them through the morass of headaches that will stem from imposing a module system into place. &lt;strong&gt;UPDATE&lt;/strong&gt;: @olivergierke &lt;a href=&quot;https://twitter.com/olivergierke/status/684642273561329664&quot;&gt;points out&lt;/a&gt; that Java9 had already slipped to 2017, so this one is automatically going to be a &amp;quot;miss&amp;quot; next January. &lt;a href=&quot;http://www.infoworld.com/article/3011445/java/java-9-delayed-by-slow-progress-on-modularization.html&quot;&gt;The article he cites&lt;/a&gt; says that Oracle &amp;quot;blamed the delay on complexities in developing modularization&amp;quot;, a la Project Jigsaw. Honestly, I&apos;m going to stand by this prediction, because it would not surprise me in the slightest if Oracle comes back at some point in 2016 and says, &amp;quot;You know what? Fuck it.&amp;quot; and ships Java9 without modularization in place--I don&apos;t really think Java9 needs it at this point, and I&apos;m not entirely sure that shipping &lt;em&gt;with&lt;/em&gt; it will make Java all that much better. Time will tell...&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Facebook will start looking for other things to do.&lt;/strong&gt; Yes, Facebook has been ridiculously successful to date; it claims more population than most nations on Earth, in fact. But the company is led by a classic Type-A personality, and the softening of his character by the birth of his firstborn notwithstanding, this is when Zuckerberg comes back from leave and says, &amp;quot;OK, boys and girls, it&apos;s time to take us down a new path!&amp;quot; and charges off into who-the-Hell-knows-what. I won&apos;t hinge the prediction on &lt;em&gt;what&lt;/em&gt; that would be, I just think it&apos;ll be something outside of the social media realm (or tied to it just a little bit).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google will continue to quietly just sort of lay there.&lt;/strong&gt; Google, for all that they are on the top of everybody&apos;s minds since that&apos;s the search engine most of us use, hasn&apos;t really done much by way of software product invention recently. Google+, Google Hangouts, yeah, sure, that was so 2013, but what have you done for us lately? And honestly, what have they done recently, in 2015? Casting back through my memory (and setting Android off to the side, since I consider that more or less an independent effort in a lot of ways), I came up with nothing. I suspect the same will be true of 2016--they will continue to do lots of innovative things, but it&apos;ll all be &amp;quot;big&amp;quot; and &amp;quot;visionary&amp;quot; stuff, like the Google Car, that won&apos;t have immediate impact or be something we can use in 2016 (or 2017).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Oracle will quietly continue to work on Java.&lt;/strong&gt; Oracle took a bit of a PR hit this year when they fired/let go a number of &amp;quot;Java evangelists&amp;quot;, and that set the newsstands aflame with hints and rumors that Oracle was getting ready to abandon Java. Frankly, if I&apos;m Larry Ellison (or the VP that has Java under my umbrella), I&apos;m asking a very fundamental question: What the hell does Java need with evangelists at this point? Everybody more or less knows what it is already, there&apos;s nothing to sell in of itself, and that money could probably be put to better use hiring people to work on the codebase itself, or putting the cash back into the rest of the firm to hire a few more Oracle Database salespeople. Oracle didn&apos;t acquire Java because they saw it as a way to inflict the Oracle Database upon the world--quite the opposite. Oracle acquired Java because they &lt;em&gt;use&lt;/em&gt; Java, all over the place, and this way they had control over a technology that they had &amp;quot;bet the farm&amp;quot; on in a variety of ways. They&apos;re not going to kill it, but there&apos;s really not a whole lot of need to go around preaching its message, either. So they let the evangelists go, and they&apos;ll just keep on keepin&apos; on.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C# 7 will be a confused morass.&lt;/strong&gt; Microsoft is now striding boldly into that open-source world it timidly courted just a few years ago. But in a lot of ways, this is highly uncharted territory for the software giant, and for the OSS world as well. Sure, Linus has been releasing Linux kernel after Linux kernel for years, but with himself as the autocrat in charge of it all. Microsoft wants to make use of the open source man-hours to help advance the cause of C# 7, but whether they&apos;ve smoothed out what that process will look like and/or how they will deal with the inevitable conflicts between committers and company isn&apos;t yet clear. (Oracle is in this same boat, in a lot of ways, and there&apos;s a lot of people who think that Java is too much Oracle, not enough OSS, so to speak.) I think the C# 7 release will be one of the first that the world gets to see take shape in a purely public forum, and they will be a bit confused and surprised at how chaotic a product release can really be. (Yes, C# 6 was sort of in that same boat, but only a handful of folks were really paying attention.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Another version of Visual Basic will ship, and nobody will really notice.&lt;/strong&gt; Actually, that already happened--remember when C# 6 shipped? They shipped a new version of VB then, too. Alas, the ship has sailed on VB, and frankly, at this point, it&apos;s really just a husk of its former self. Most of the VB luminaries are all speaking and/or writing in C# these days, and only staunch loyalty to their fond memories of the language is what keeps it at all in the conversation anymore. Sad, but... Oh, well.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple will now learn the &amp;quot;joys&amp;quot; of growing a language in the public as well.&lt;/strong&gt; Swift is now open-source, and that will bring with it the same pains as what Oracle and Microsoft are feeling. Enjoy, guys!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ted will continue to layer in a few features into the blog engine.&lt;/strong&gt; For example, right now I have no comments feature, and I suspect people will want to start telling me how incredibly &lt;strong&gt;wrong&lt;/strong&gt; I am about so many of these. So, on the docket already, Disqus or Discourse or some other JavaScript-based comment-engine integration. Plus, I want to tweak the template I&apos;m using for the blog&apos;s look and feel a little (although keeping it way simple, especially compared to what I had before), so there&apos;s likely to be more than a few tweaks here and there. (Again, not really a hard prediction to make, but I always like to close on a prediction that I have a relatively .9 probability chance of hitting.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Happy Holidays, and thanks for reading!&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Your Job is Not to Write Code</title>
      <link>http://blogs.newardassociates.com/blog/2015/your-job-is-not-to-write-code.html</link>
      <pubDate>Mon, 12 Jan 2015 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2015/your-job-is-not-to-write-code.html</guid>
      	<description>
	&lt;p&gt;An open letter to software developers all across the world.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Dear Software Consultants,&lt;/p&gt;
&lt;p&gt;I hate to be the one to break this to you, but you were lied to when we hired you. Your job isn&apos;t about code at all.&lt;/p&gt;
&lt;p&gt;The interview process was kind of a train wreck (and, yeah, about that, sorry, but we really don&apos;t know how to hire folks, so we kind of tested you on what we thought was easily testable--you know, binary trees and all that stuff--even though your day-to-day is about moving an image on a web page over a few pixels), but you&apos;re here now, sitting in front of the customer, talking about writing code, so it&apos;s pretty easy to understand how you&apos;d be mixed up.&lt;/p&gt;
&lt;p&gt;See, the thing of it is this: if you get right down to it, I (your boss) don&apos;t really care if you write code or not. The clients don&apos;t really care if you write code or not. (They say they do, but hear me out on this.) And the clients&apos; customers and users, they don&apos;t really care if you write code or not.&lt;/p&gt;
&lt;p&gt;What they care about is the result: Did you make their life better today somehow?&lt;/p&gt;
&lt;p&gt;In a consulting gig, we get paid to solve clients&apos; problems. That&apos;s it. Nothing else. Frequently, writing code solves those problems, and when that&apos;s the case, then boo-yeah, write, test, ship! Everybody is happy.&lt;/p&gt;
&lt;p&gt;But when writing code gets in the way of solving those problems, then we have a problem. Which is to say, the clients have a problem, which makes it our problem, which makes it... you guessed it... your problem.&lt;/p&gt;
&lt;p&gt;Here&apos;s some of what we mean.&lt;/p&gt;
&lt;p&gt;You have a MacBookPro with 16GB of RAM and a full tera of SSD disk space, tied to a phat pipe that streams full gigs of data down to the office. That&apos;s awesome. That makes you productive.&lt;/p&gt;
&lt;p&gt;But that can mask certain problems--if your code thrashes the network for some reason, making dozens or hundreds of round trips to the server, when it all runs on your laptop, that&apos;s going to seem totally acceptable. When it goes out into production in a cloud data center that&apos;s only as close as the nearest mountain range (which kinda sucks for those living in the Midwest), those minimal trips back and forth on your laptop suddenly turn into long-haul calls across the country. Not such a great experience.&lt;/p&gt;
&lt;p&gt;And you&apos;re using Google Chrome, with all the latest updates and security patches. Perfect! Except that the clients&apos; users are running Firefox, IE, Safari, and Opera. And probably versions dating a few years back, too, because consumers just don&apos;t upgrade their software nearly as often as developers do.&lt;/p&gt;
&lt;p&gt;And we--remember this, because this is important--we are in the &apos;solutions&apos; business. So no matter how amazing your code is, if it doesn&apos;t solve the clients&apos; customers&apos; problem, then it is a waste.&lt;/p&gt;
&lt;p&gt;You heard about similar kinds of situations in college; the term &amp;quot;gold plating&amp;quot; refers to the effort that engineers will sometimes put in on parts that nobody but themselves will ever know exist. But this is a slightly different problem: You are putting in effort building something that doesn&apos;t actually solve the client&apos;s customers&apos; problems. So, in many respects, it&apos;s a waste.&lt;/p&gt;
&lt;p&gt;This is going to require some adjustments.&lt;/p&gt;
&lt;p&gt;First off, the question around any particular feature or story is simple: Does this make the client&apos;s life better? In many cases, the answer will be, &amp;quot;Yes, but only because it makes their customers&apos; lives better&amp;quot;, which is a totally acceptable answer. If the answer is, &amp;quot;I don&apos;t know&amp;quot;, then your next task is to find out the answer to that. Bear in mind, the client often doesn&apos;t know the answer to that. Which is part of the solution we are supposed to be bringing to them, when you think about it.&lt;/p&gt;
&lt;p&gt;Second, you need to ensure that whatever you build, it meets the client&apos;s customer halfway: Does it run on their target environment? If you don&apos;t know what their target environment is, by the way, you have just identified something you need to know, stat.&lt;/p&gt;
&lt;p&gt;Third, is there better value you can bring in another way? Is there a simpler change in business process that would obviate the need for this code? Suggest it. Is the client doing something &amp;quot;stupid&amp;quot; that you think should be fixed? Bring it up. Is the client trying to put square peg in round hole? Point it out. But....&lt;/p&gt;
&lt;p&gt;Fourth, remember that at all times, the client&apos;s right is to ignore us completely. Yes, it&apos;s frustrating, but you would feel the same way were it you talking to the doctor or to a mechanic about changes to your life or repairs made to your car. &amp;quot;You&apos;re charging me $15,000 for an engine overhaul that YOU thought needed to be done, without checking with me first?!?&amp;quot; is not a great way to collect repeat business.&lt;/p&gt;
&lt;p&gt;Look, consultants, it&apos;s not all that hard to understand: Most of the time, you will deliver value to our clients by writing code. But that means that your ultimate product here is not the code, but the value.&lt;/p&gt;
&lt;p&gt;Your job is not to write code.&lt;/p&gt;
&lt;p&gt;Your job is to deliver value. In whatever form that may take.&lt;/p&gt;
&lt;p&gt;Which reminds me, while we&apos;re here, remember to embrace the &lt;a href=&quot;http://blogs.tedneward.com/2007/01/27/Programming+Promises+Or+The+Professional+Programmers+Hippocratic+Oath.aspx&quot;&gt;the Oath of the Conscientious Programmer&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I swear to fulfill, to the best of my ability and judgment, this covenant:&lt;/p&gt;
&lt;p&gt;I will respect the hard-won scientific gains of those programmers and researchers in whose steps I walk, and gladly share such knowledge as is mine with those who are to follow. That includes respect for both those who prefer to keep their work to themselves, as well as those who seek improvement through the open community.&lt;/p&gt;
&lt;p&gt;I will apply, for the benefit of the customer, all measures [that] are required, avoiding those twin traps of gold-plating and computing nihilism.&lt;/p&gt;
&lt;p&gt;I will remember that there is humanity to programming as well as science, and that warmth, sympathy, and understanding will far outweigh the programmer&apos;s editor or the vendor&apos;s tool.&lt;/p&gt;
&lt;p&gt;I will not be ashamed to say &amp;quot;I know not,&amp;quot; nor will I fail to call in my colleagues when the skills of another are needed for a system&apos;s development, nor will I hold in lower estimation those colleagues who ask of my opinions or skills.&lt;/p&gt;
&lt;p&gt;I will respect the privacy of my customers, for their problems are not disclosed to me that the world may know. Most especially must I tread with care in matters of life and death, or of customers&apos; perceptions of the same. If it is given me to save a project or a company, all thanks. But it may also be within my power to kill a project, for the company&apos;s greater good; this awesome responsibility must be faced with great humbleness and awareness of my own frailty. Above all, I must not play at God, and remain open to others&apos; ideas or opinions.&lt;/p&gt;
&lt;p&gt;I will remember that I do not create a report, or a data entry screen, but tools for human beings, whose problems may affect the person&apos;s family and economic stability. My responsibility includes these related problems, if I am to care adequately for those who are technologically impaired.&lt;/p&gt;
&lt;p&gt;I will actively seek to avoid problems that are time-locked, for I know that software written today will still be running long after I was told it would be replaced.&lt;/p&gt;
&lt;p&gt;I will remember that I remain a member of society, both our own and of the one surrounding all of us, with special obligations to all my fellow human beings, those sound of mind and body as well as the clueless.&lt;/p&gt;
&lt;p&gt;If I do not violate this oath, may I enjoy life and art, respected while I live and remembered with affection thereafter. May I always act so as to preserve the finest traditions of my calling and may I long experience the joy of the thanks and praise from those who seek my help.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You&apos;re smart. You&apos;ll figure it out. Just remember, code is not the goal. It is merely the means to the end, which is to &amp;quot;make the (client&apos;s) pain go away&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(&lt;strong&gt;UPDATE&lt;/strong&gt;: The original author of &amp;quot;Your Job is Not To Write Code&amp;quot; was not happy at my unauthorized derivative work of her post--it violates her no-reprint policy--and has asked that I remove it. I liked the original intent, however, so I am rewriting/editing this post to reflect the same sentiment but without the derivation. My apologies.)&lt;/em&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2015 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2015/2015-tech-predictions.html</link>
      <pubDate>Mon, 5 Jan 2015 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2015/2015-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;It&apos;s that time of year again....&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;First, as always, we revisit the predictions &lt;a href=&quot;http://blogs.tedneward.com/2014/01/03/Tech+Predictions+2014.aspx&quot;&gt;I made last year&lt;/a&gt;, and see how well they stacked up. (Because, as I&apos;ve said before, anybody can make predictions without going back to measure your accuracy; I believe in accountability, even to my own silly blog predictions.)&lt;/p&gt;
&lt;p&gt;On 3 January, 2014, I said:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;iOS, Android and Windows8 start to move into your car.&lt;/strong&gt; Ehhhh.... Yeah, sort of, but not nearly as much as I thought they would. There&apos;s a few folks experimenting with this, but frankly, after a big splash announcement, the idea pretty much went nowhere. I don&apos;t think the idea is &amp;quot;done&amp;quot;, per se, but I do think we&apos;re looking at a three-to-five year quiescience while the industry figures out what to do with this (and do it in such a way that it doesn&apos;t kill somebody). (And no, by the way, I don&apos;t count Google&apos;s self-driving car as a point for me under this item--that&apos;s a wholly different thing.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wearable tech hypes up (with little to no actual adoption or innovation).&lt;/strong&gt; I said, &amp;quot;There&apos;ll be absolutely zero reason for anyone to get one for calendar year 2014&amp;quot;, and frankly, I stand by that. The Samsung smart watch, the Google Glass, all of the third-party wearables... none of them have really &amp;quot;wow&amp;quot;ed anybody with their &lt;i&gt;raison d&apos;etre&lt;/i&gt;. Sure, get text messages on your watch, or place a call (on your phone) from the watch.... But nobody&apos;s doing that. I see hardly any of the wearables out in the wild, with the sole exception of those who are wearing a FitBit or something similar. (The Microsoft Band looked like a cool device, but again... nobody&apos;s using them in the wild for anything but exercise stat tracking. That&apos;s hardly a &amp;quot;gotta have it&amp;quot; kind of reason.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple&apos;s gadgets will be more of the same.&lt;/strong&gt; Basically, I said, &amp;quot;iPhone, iPad, iPod, MacBook, they&apos;re all going to be incremental refinements on what we see already.&amp;quot; And sure enough, the iPhone got a little bigger, there was no real MacBookPro refresh, and the iWatch is still pretty much vapor at this point (and it&apos;s not clear what compelling reason it would have even if it did ship). Sure, the image is there on the Apple website, slated for &amp;quot;early 2015&amp;quot;, but frankly... it&apos;s a watch. One that I&apos;ll have to recharge every night or two. Yawn. Not impressed, so far. I said, &amp;quot;Apple is clearly the market leader, and they are clearly in the grips of the Innovator&apos;s Dilemma, and they have no clear challenger (yet) that threatens to dethrone them, leaving them with no reason to shake up the status quo&amp;quot;, and I stand behind that 100%.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Android market consolidates further around Samsung and Motorola.&lt;/strong&gt; I&apos;m sorry, Moto-who? They&apos;ve all but disappeared from the Android marketplace in a lot of ways, leaving it to be a two-horse race: Samsung/Android vs Apple/iOS. In fact, I think Google is spinning Motorola back off again into its own entity, and the industry collectively... Meh&apos;ed. Given how much angst there was when Google acquired Motorola, I would&apos;ve thought this would&apos;ve had a bigger impact, but I think Google figured out fairly quickly that they&apos;re not really a hardware company, and don&apos;t want to be.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;We&apos;ll see one iOS release, two minor Android releases, and maybe two Windows8 minor releases.&lt;/strong&gt; &amp;quot;I can&apos;t see the mobile market getting any kind of major surprise this year.&amp;quot; Yep. One iOS release (8), two minor Android releases... well, Android 5 isn&apos;t a minor release, but until it ships on hardware, it&apos;s hard to call it a &amp;quot;major&amp;quot; release, either. I&apos;d almost call it vaporware, except it&apos;s the opposite--it&apos;s there, anybody can build for it, you just can&apos;t... &lt;i&gt;run&lt;/i&gt;... it anywhere.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Windows 8/8.1/9/whatever gains a little respect, but not market share gains.&lt;/strong&gt; Surface 3 is an awesome device--not because it runs Windows8/9/whatever, but in spite of it, for a lot of people. But beyond the Surface, are any tablets/mobiles running Win8/9/whatever getting much traction? I don&apos;t see it. Sadly, Windows remains a laptop-bound OS, though the traditional definition of &amp;quot;laptop&amp;quot; is clearly getting a makeover as PC manufacturers try to muscle in on the iPad space from the other direction.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UI/UX emphasis is going to start moving to &amp;quot;alternate&amp;quot; input streams.&lt;/strong&gt; Yeah, would&apos;ve been nice, but it&apos;s not there yet. Kinect has kind of faded into a whimper. &lt;i&gt;Minority Report&lt;/i&gt;-style interfaces are still the stuff of science fiction for the time being, and probably will be, again, for the rest of the decade.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Java-the-language starts to see a resurgence of &amp;quot;mojo&amp;quot;.&lt;/strong&gt; Oh, my, yes. Devoxx this year was quite all abuzz about Java8, and it really feels (to many in the Java community) that Java&apos;s got its &amp;quot;buzz&amp;quot; back, at least at the language level. JavaEE is basically shot/fragmented to all hell, but JavaSe is definitely turning a few peoples&apos; eyes in the Java space. Language creators for the JVM that just want to create &amp;quot;a better Java&amp;quot; by taking basic C/C++-style syntax and adding anonymous functions are basically consigning themselves to &amp;quot;this is a fun side research project that I expect to go nowhere&amp;quot; status.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Meanwhile, this will be a quiet year for C#.&lt;/strong&gt; Yeah... kind of. It&apos;s hard to call this one; on the one hand, nothing officially shipped, but on the other hand, Roslyn and its ilk got open-sourced, which is kind of a big deal... if you like dabbling with langauges and/or using language tools directly as part of your toolchain... which really is just a small percentage of developers. I dunno--hard to say.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Functional languages will remain &amp;quot;hipster&amp;quot; tools that most people can&apos;t use.&lt;/strong&gt; Yeah... &lt;em&gt;sigh&lt;/em&gt;. I wish this weren&apos;t the case, but 2014 was not the &amp;quot;year of the FP&apos;er&amp;quot;, by any stretch. Scala is making strides and getting some folks really excited... but those folks were the ones already excited. I don&apos;t see it making its way &amp;quot;down&amp;quot; the &amp;quot;programmer hipster ladder&amp;quot;, so to speak, to reach &amp;quot;regular&amp;quot; line-of-business developers, and tools like sbt are &lt;i&gt;not&lt;/i&gt; helping. (sbt&apos;s syntax is really something only its mother could love... and she&apos;d only admit it if it were in the hospital or something.) I get that it&apos;s cool that you can use operators like ~&amp;gt;&amp;gt;= in your language, guys, but in a build tool? Seriously? That is not lowering the barrier to entry.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dynamic languages will see continued growth and success.&lt;/strong&gt; Well, Node got forked. Dunno what that means. Ruby seemed to actually lose a little steam, and &lt;a href=&quot;http://rubini.us/2014/12/31/matz-s-ruby-developers-don-t-use-rubyspec/&quot;&gt;some cynicism and frustration seems to be setting in&lt;/a&gt;, particularly among the different &amp;quot;breeds&amp;quot; of Ruby developers. Python still just sort of... hangs out there... with a dedicated community that seems to be getting no larger and no smaller. And Apple&apos;s Swift... well, it&apos;s not really a dynamic language, per se, but it&apos;s not exactly a statically-typed one, either... Oh, hell, I give up. You tell me whether this is continued growth or success. On the other hand, I did say, &amp;quot;I&apos;m becoming more and more convinced that having a language that supports both static and dynamic typing capabilities represents the best compromise between those two poles of software development languages&amp;quot;, and boy does that seem to be happening, with Swift just being the largest-splash of the examples so far.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTML 5 &amp;quot;fragmentation&amp;quot; will start to echo in the industry.&lt;/strong&gt; Not happening, unless you call the different browsers&apos; different levels of support for HTML 5 &amp;quot;fragmentation&amp;quot;. Wait--that&apos;s exactly what that looks like. So... is it any worse than before? Folks, any time a website tells you &amp;quot;This site best viewed in...&amp;quot; or &amp;quot;This page optimized for...&amp;quot;, that&apos;s exactly what that looks like. And it&apos;s happening now: Chrome is the most egregious of the lot, with most developers choosing to optimize for it, but the fact that anybody&apos;s doing it for any browser tells you that the &amp;quot;standard&amp;quot; really isn&apos;t.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;Mobile browsers&amp;quot; become just &amp;quot;browsers&amp;quot;.&lt;/strong&gt; Open your phone browser. Browse to a page. Aside from the smaller screen, is there anything the browser doesn&apos;t support that your desktop does? Didn&apos;t think so. As a matter of fact, Android finally just up and admitted it, and now ships with Chrome as an app on their Samsung/Android devices. Let the &amp;quot;mobile browser&amp;quot; be done, and it&apos;s eulogy written here: &amp;quot;Farewell, mobile&lt;br /&gt;
browser, and take your crappy disadvantages with you; we missed you not at all.&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;Mobile web&amp;quot; starts a slow, steady slide into irrelevancy. ... sites optimized for &amp;quot;mobile&amp;quot; browsing experiences--which represents a non-trivial development effort in most cases--will start to drop away, mostly due to neglect.&lt;/strong&gt; Yep.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;Responsive web&amp;quot; becomes the new black. ... we&apos;ll see web sites using CSS frameworks (among other tools) to build user interfaces that adjust themselves to the physical viewsizes and input capabilities of the target browser.&lt;/strong&gt; Yep. This is becoming a necessary skill for web designers, and any new Web-facing application that ships without some level of responsiveness may as well just write at least half of its potential market off.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microsoft fails to name a Ballmer successor.&lt;/strong&gt; Helloooooo, Satya Nadella. I&apos;m not a Microsoft Insider, I had no idea who this guy was when he got announced. But so far, I&apos;m pleased with what he&apos;s done. Granted, &lt;a href=&quot;http://www.geekwire.com/2014/microsoft-ceo-fire-saying-women-trust-hr-systems-deliver-raises/&quot;&gt;he hasn&apos;t been perfect&lt;/a&gt;, but he&apos;s doing the right things from a company perspective--embracing other languages and platforms, and providing clear direction for the company as a whole... for the most part. Jury&apos;s still out, and will be for at least the next half-decade, but he came out clearly wanting to make his mark, and he did. Now let&apos;s see how far Microsoft employees will follow him and his guidance, and then let&apos;s see how the market does. The first is a lot easier than the second, but the second doesn&apos;t happen without the first.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;Programmable Web&amp;quot; becomes an even bigger thing, leading companies to develop APIs that make no sense to anybody.&lt;/strong&gt; Have you seen &lt;a href=&quot;https://zapier.com/&quot;&gt;Zapier&lt;/a&gt;? It&apos;s like the DOS batch file language of the Internet. And if that&apos;s too much, try &lt;a href=&quot;https://ifttt.com/&quot;&gt;IFTTT&lt;/a&gt;. It&apos;s the... I dunno, what&apos;s higher-level than DOS batch files? Seriously, Web APIs are becoming so expected that any day now I expect to see a Web API that allows you to create a Web API on demand. (And we&apos;re actually &lt;a href=&quot;http://raml.org/projects.html&quot;&gt;closer than you think...&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Five new single-page JavaScript MVC application frameworks will ship and gather interest.&lt;/strong&gt; You count--I&apos;m getting tired. AngularJS 2.0 is going to take a different direction from 1.x, which almost makes it a new framework. Famo.us is getting close to ship. Ionic. And that&apos;s just off the top of my head. The JavaScript ecosystem is rapidly spinning into that open-source freefall that the Java-Web world turned into, and didn&apos;t climb out of for more than a half-decade.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple&apos;s MacPro machine inspires dozens of knock-off clones.&lt;/strong&gt; Nope. Not a peep. Oh, well.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Desktop machine sales creep slightly higher.&lt;/strong&gt; I don&apos;t have the numbers handy, and it&apos;s 1AM as I write this, so I&apos;m not looking. Even if it&apos;s not happening in 2014, I think over the next half-dozen years we&apos;re going to see that 80/20 mobile/desktop split, in time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dozens of new &amp;quot;cloud&amp;quot; platforms will be introduced, and most of them will remain entirely irrelevant behind the &amp;quot;Big Three&amp;quot;.&lt;/strong&gt; Well, dozens are coming out, depending on which flavor of &amp;quot;*aaS&amp;quot; you consider to be &amp;quot;Cloud&amp;quot;, and what seems to be happening is that the Big Three are picking them up and incorporating them as part of their offering (a la what happened with &lt;a href=&quot;https://www.firebase.com/index.html&quot;&gt;FireBase&lt;/a&gt;). This is probably only going to rise--Heroku got picked up by SalesForce somewhere along the way, for example, and I fully expect Parse to do the same before long. As for the big players (Oracle, HP, etc) that aren&apos;t one of the Big Three... yeah, they&apos;ll quietly fade and die.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;We will never see any kind of official announcement, much less actual working prototypes, around Amazon&apos;s &amp;quot;Drone Delivery&amp;quot; program ever again.&lt;/strong&gt; Anybody? Anybody? Lots of discussion around drones, but nothing from Amazon, and certainly nothing shipped.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Overall.... &lt;em&gt;shrug&lt;/em&gt; About par for the course, 50/50 by my count.&lt;/p&gt;
&lt;p&gt;So what do I see for 2015? Here goes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;Big data&amp;quot;, &amp;quot;Big data&amp;quot;, &amp;quot;Big data&amp;quot;. You will get sick of this phrase.&lt;/strong&gt; What I didn&apos;t say last year was anything about big data, and frankly, the hype machine is not even remotely close to being done with this. EVERYTHING will be made into a &amp;quot;big data&amp;quot; play before 2015 is over, to the point where nobody knows what &amp;quot;big data&amp;quot; really means anymore... except for the people quietly doing it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;Internet of Things&amp;quot;. You will get sick of this phrase, too.&lt;/strong&gt; Look, let&apos;s just call it right now: IoT is clearly in the overestimate-in-5-years/underestimate-in-10-years Bill Gates quote territory. We have no idea what IoT will end up looking like, practically speaking, and yet billions will be spent on people who claim to know exactly that. Save your money. Or, if you really want to give a smart-sounding consulting some cash to tell you what you already know, send it my way, and I&apos;ll show up at your place of business, look wise and distinguished, and tell your boss, &amp;quot;It depends&amp;quot; in fifty pages and with two-hundred PowerPoint slides. Everybody wins.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;Internet of Medicine&amp;quot; or &amp;quot;Big Med&amp;quot;.&lt;/strong&gt; I&apos;m calling this one right here: with all the health-related big data plays going on right now, it&apos;s only a matter of time before some chirpy journalist or press agent coins this. It&apos;s a fascinating opportunity--there&apos;s a lot of really interesting and cool ideas around the intersection of big data-about-your-health, the wearables world, medical AI/data-analysis, and mobile devices, and just about every entrepreneur and VC is going after it. So within the next year or two, many of those are going to ship in some form, and then... I have no idea, but it&apos;ll be big/catastrophic, whatever happens.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;Tech bubble&amp;quot; becomes a &amp;quot;thing&amp;quot;.&lt;/strong&gt; Internet- and technology-related firms are getting ridiculous valuations, and those of us who were in the industry in the years leading up to 2000 know what this means. I&apos;m sorry, but when &lt;a href=&quot;http://www.businessinsider.com/pluralsight-is-worth-almost-a-billion-dollars-2014-8&quot;&gt;a technology-training company gets valued at &lt;i&gt;$1 billion&lt;/i&gt;&lt;/a&gt;, which is more than some Fortune-5000 firms that&apos;ve been around for a half-century or more.... this is clearly &amp;quot;bubble&amp;quot; territory. Trust me, I don&apos;t want this bubble to pop, particularly since I&apos;m supposed to be releasing a few courses through them, but I remember when everybody was certain that &amp;quot;Pets.com&amp;quot; was a multi-million Web property, too... and I remember when I worked for a company that thought technology training was a &amp;quot;recession-proof&amp;quot; industry. These numbers are ridiculous, and it&apos;s only going to take one high-value collapse to start pulling the rest of the house of cards down. Before 2020, you mark my words. In 2015, though, the warnings and arguments against those warnings are only going to intensify.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;C# and Java will both make big announcements.&lt;/strong&gt; C# 6 will probably ship somewhere in 2015 (they called the product &amp;quot;Visual Studio 2015&amp;quot;, after all), and Java9 will probably start to make some news towards the end of 2015, though I don&apos;t expect it to ship. Those who care will take note, those who don&apos;t, won&apos;t. Really, we&apos;re kind of past the point where either of those languages are going to be interesting to anyone who&apos;s not already in that space.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Go is going to either take off, or crash and burn.&lt;/strong&gt; Go seems to be approaching an inflection point, and while I&apos;m not smart enough to know what&apos;s going to happen there, I think this will be a year of decision for them.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Microsoft acquires Xamarin.&lt;/strong&gt; Microsoft seems to be coyly flirting with the idea, and really, it makes a ton of sense for them to do so: it gives them a way to be relevant on the two major mobile platforms without abandoning .NET or their own platform. Really, the only question that remains is what kind of cash it would take to do the buyout, and does Microsoft have that money available to it after its rather (IMHO) ill-advised acquisitions of the past (&lt;em&gt;cough&lt;/em&gt; Nokia &lt;em&gt;cough&lt;/em&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Amazon just quietly keeps churning.&lt;/strong&gt; Really, this seemed like a pretty quiet&lt;br /&gt;
year for Microsoft&apos;s cross-Sound neighbor, and I don&apos;t know that&apos;ll change in 2015. Kindle seems pretty successful, but the Fire doesn&apos;t seem like it&apos;s gone far as a full-fledged mobile device. Amazon is fighting some brush fires on its borders over licensing and royalties, and that&apos;s probably distracting them in some major ways. (They&apos;re also developing a reputation as a firm that burns employees out fast, which also isn&apos;t helping, I imagine.) I don&apos;t think 2015 is a year of huge developments for them, but in a lot of ways, they don&apos;t need them--AWS is, as near as I can tell, the gold standard of &amp;quot;cloud&amp;quot;, and as long as they just keep pace with whatever Azure comes out with, they&apos;re in good shape there.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Google continues to throw sh*t against the wall, looking for their Next Big Thing.&lt;/strong&gt; What I mean by that is this: Among wine snobs, there is a story (possibly apocryphal) of a wine-tasting expert who had a wall in his house painted a very particular shade of white. Then, when tasting a red wine, he would throw the contents of the glass against that wall, to observe the color and the way the wine beaded and ran down the wall as part of his evaluation. Frankly, that kind of feels like what Google is doing: throwing idea after idea &amp;quot;against the wall&amp;quot; of public opinion, trying to see what stands out and looks great and garners interest. If I didn&apos;t know better, I&apos;d say they&apos;re desperately trying to find a new line of revenue beyond AdWords, just as Microsoft a decade ago was desperately trying to find a new line of revenue beyond Windows. Expect a lot of announcements, a lot of &amp;quot;beta&amp;quot;s, and none of it with any kind of realistic or even well-planned business model behind it--including the Google Car.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Web use on mobile devices decreases in favor of apps.&lt;/strong&gt; This is going to happen whether the public wants it or not, because companies have figured out that it behooves them to have you &amp;quot;trapped&amp;quot; inside their app (where they can control all the content) rather than on their website. More and more websites are going to try and redirect you to inside their app, rather than allow you to casually browse on their site, because then they think they &amp;quot;own&amp;quot; your eyeballs. The only way this changes is if/when some firm gets crushed in the court of public opinion by doing something really stupid... and that won&apos;t happen in 2015. Wait for it in 2016.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Hipster &amp;quot;Uber for X&amp;quot; apps will be all the rage.&lt;/strong&gt; Every technology event is going to be filled with 20- and 30-somethings who are convinced that the world wants/needs an app that will allow customers to get X (service or good) delivered right to wherever-they&apos;re-standing, without doing one iota of business research as to whether that model makes any sense anywhere outside of New York or San Francisco. They will get millions in VC, confidently proclaim themselves the next Facebook, and then implode. (This might actually be what starts the tech bubble implosion.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mark Zuckerberg grows up a little.&lt;/strong&gt; Remember his &amp;quot;You&apos;re washed up when you&apos;re 30&amp;quot; crack? He turns 30, and I suspect he doesn&apos;t think he&apos;s &amp;quot;done&amp;quot; quite yet. As he tries to become more of a &amp;quot;technology statesman&amp;quot; (which is really the next step for him), however, he&apos;s going to get caught up on that remark over and over again from people who just want to see him fail or be embarrassed, until he either admits, &amp;quot;Yeah, OK, I was wrong&amp;quot; or gets so frustrated he buys a small island in the South Pacific, screams &amp;quot;I hate you all!&amp;quot; and flees the country. (Hopefully he remembers to update his status before he goes.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Larry Ellison buys a sports team.&lt;/strong&gt; Yeah, he&apos;s got a yacht, but now Ballmer owns the Clippers. Paul Allen has the World Champion Seattle Seahawks. If either of the Google boys puts in for the Buffalo Bills or St Louis Rams, this is a given.... and I think he buys the Golden State Warriors.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Perl makes one final gasp at relevancy, fails, and begins to decompose.&lt;/strong&gt; C&apos;mon, when&apos;s the last time the Perl community made a &amp;quot;This time we mean it! Perl 6 is going to ship!&amp;quot; announcement? They&apos;re like the &lt;a href=&quot;http://en.wikipedia.org/wiki/Daikatana&quot;&gt;Daikatana&lt;/a&gt; or &lt;a href=&quot;http://en.wikipedia.org/wiki/Duke_Nukem_Forever&quot;&gt;Duke Nukem Forever&lt;/a&gt; of programming languages by this point. If you&apos;re still using Perl, just accept fate, switch to Python, Ruby, or even Node. Nobody can take your memories from you.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;... annnnnnnd I&apos;m spent.&lt;/p&gt;
&lt;p&gt;Happy New Year, everyone. May your 2015 be everything you want it to be, and a few more things beyond that. Be kind to yourself, generous to others, humble in the spotlight and lavish in your praise of those around you. Cheers!&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Recruiting the Right Way</title>
      <link>http://blogs.newardassociates.com/blog/2014/recruiting-the-right-way.html</link>
      <pubDate>Wed, 3 Dec 2014 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2014/recruiting-the-right-way.html</guid>
      	<description>
	&lt;p&gt;There&apos;s been a fair amount of conversation around how to recruit software developers effectively. &lt;a href=&quot;http://blogs.tedneward.com/2013/08/20/Programming+Interviews.aspx&quot;&gt;I&apos;ve participated in some of it.&lt;/a&gt; But just today, a blog post crossed my desk(top) and finally prompted me enough to get around and blog about it.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;In &amp;quot;&lt;a href=&quot;http://blog.alinelerner.com/resumes-suck-heres-the-data/&quot;&gt;Resumes Suck. Here&apos;s the Data&lt;/a&gt;&amp;quot;, Aline Lerner talks about a scientific process she used to actually try to gauge the efficacy of resumes in the hiring process. (I probably should say &amp;quot;pseudo-scientifically&amp;quot;, only because while it looks pretty legit to me, and frankly it&apos;s more legit science than most companies will engage around hiring, it probably has a few statistical/scientific holes in it that could lead to some misleading data; that said, it&apos;s better than the traditional answer of &amp;quot;Well, &lt;em&gt;I&lt;/em&gt; know how to interview people, so....&amp;quot;, which to me is an outright so-you-buy-into-your-own-bullshit answer.)&lt;/p&gt;
&lt;p&gt;Her conclusion?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;... it may not be a matter of being good or bad at judging resumes but rather a matter of the task itself being flawed — at the end of the day, the resume is a low-signal document. ... Very smart people, who are otherwise fantastic writers, seem to check every ounce of intuition and personality at the door and churn out soulless documents expounding their experience with the software development life cycle or whatever... because they’re scared that sounding like a human being on their resume or not peppering it with enough keywords will eliminate them from the applicant pool before an engineer even has the chance to look at it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yeah. I can relate.&lt;/p&gt;
&lt;p&gt;If you combine her findings here with my anecdotal evidence around how most companies&apos; interview process is fundamentally broken (which Google seems to have confirmed), what you come to realize is that for most companies, the entire recruiting process is just one giant coin-flip based on equal parts intuition, mutual fakery with the best of intentions (&amp;quot;This company is great!&amp;quot; &amp;quot;I&apos;m an amazing candidate!&amp;quot;), and almost no science--or accountability, or independent verification of the results, or testing--involved.&lt;/p&gt;
&lt;p&gt;So here&apos;s what we do at &lt;a href=&quot;http://www.itrellis.com&quot;&gt;iTrellis&lt;/a&gt; (the company where I&apos;m currently the CTO):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Our recruiters are instructed to look at much more than the resume.&lt;/strong&gt; Quite frankly, if you have a Github profile, a BitBucket profile, a blog, or God-help-us-all just your own domain, we take all of that into account. As Aline points out, resumes suck. No resume has ever accurately captured what somebody did on the job: either they exaggerate for effect, or they totally misrepresent (both positively and negatively) what they did. And quite frankly, any employment history, technology, project or customer you helped more than ten years ago is really not going to matter much, unless that&apos;s exactly what we&apos;re hiring you for. But forking a project to play with it, contributing a pull request, commenting on a blog about something interesting you discovered... folks, that&apos;s a more accurate representation of who you are than any resume you could possibly hand me. And if you have your own domain, and you built your own blog... Nice.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Once identified, our recruiter calls you to make sure you pass the Bozo Test.&lt;/strong&gt; Seriously. The phone call is a pleasant ten- to thirty-minute chat to find out if you have a pulse, you&apos;re actually looking for a job, and that you&apos;re not some wingnut out of left field who thinks that C++ is a better grade than a B-. More importantly, &lt;em&gt;they are doing no technical evaluation of the candidate&lt;/em&gt;. Seriously, think about that: you&apos;re going to ask somebody whose specialty is Human Resources to make a call on whether this person has the chops to write code? All they&apos;re going to be able to do is look to see if they have the &lt;em&gt;credentials&lt;/em&gt; (degree, certifications, etc), and we all know how accurate those are. No way. Don&apos;t ask me to put together a pension program, and don&apos;t ask the HR guy to evaluate a technologist.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Once you&apos;ve agreed that you&apos;re looking for a job, and you passed the Bozo Gate, we tell you to go write some code.&lt;/strong&gt; Seriously. No, you&apos;re not going to talk to any of our people. No, there&apos;s no &amp;quot;preliminary screening&amp;quot;. We have code to write. And frankly, the best screen we can put in place to determine if you have technical chops is to have you write some code. Specifically, we ask you to spend no more than 10 hours on &lt;a href=&quot;https://bitbucket.org/itrellis&quot;&gt;one of these projects&lt;/a&gt;. Notice how there&apos;s both Java and C# versions? If you wanted to do it in Ruby or Node, I&apos;d be OK with that. Hell, if you wanted to take a wild stab in the dark and do it in a language you&apos;ve never written before, I&apos;d take that, too. (Shows moxie. Gumption! Dare I say, chutzpah!) We don&apos;t even care if you finish it. We just want to have a pile of code that you wrote specifically for this purpose, because then we can use it (free of any IP restrictions) for the next stage.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Once you&apos;ve written the code, you send it to us.&lt;/strong&gt; Zip it up, or better yet, point us to the pull request, or, even better, your version of the project on your own source control system public server of choice. This is where we evaluate your technical chops: what tools did you use, what results did you get, how closely did you adhere to our requests/&amp;quot;requirements&amp;quot;, and so on. Did you ask us questions around the ambiguities? Did you make assumptions about what we wanted without checking with us first? Did you remember to unit test? (We said, right there in the README, &amp;quot;Unit tests are very important to us&amp;quot;. If you didn&apos;t unit test, you gonna have some &apos;splainin&apos; to do....) And so on.&lt;/p&gt;
&lt;p&gt;By the way, take note: other than ten to thirty minutes of our recruiters&apos; time for the phone call (and whatever time the recruiter spent looking at your profile/resume/whatever, and I&apos;ve told them to keep that bar pretty low!), no iTrellis time has been consumed as part of this process so far. Your code is what we care about at this point, why should we even talk to you yet?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;We evaluate your code sample.&lt;/strong&gt; Can we build it? Can we run it? Can we run the tests? This step is pretty straightforward.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Assuming your code passes muster, we bring you in.&lt;/strong&gt; But not to interview--oh, no. The human brain is a deeply flawed instrument, and we don&apos;t want to give in to its accidental prejudices and flaws. No, instead, we want you to &amp;quot;pair&amp;quot; with three of our existing employees, over your code. This has a couple of parts to it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We want to find out if you fit with our existing staff. Hey, let&apos;s face it, you could be the best coder in the world, but if you manage to piss off all three of your pairs, you are Not Going To Work.&lt;/li&gt;
&lt;li&gt;We want to find out if we can put you in front of a client. We are a consulting company. We can&apos;t afford to have people that can&apos;t stand the light of day.&lt;/li&gt;
&lt;li&gt;We want to see how mentally nimble you are.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And by that last part, what I do is I ask my three pairs to specifically work with you on three different things, from a list of things like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;Can you explain your code to me? Why did you choose to do this? Why didn&apos;t you do that?&amp;quot; You need to be able to explain your decisions without getting defensive or angry. I may sometimes ask the pair-er to deliberately disagree with the decision, to see what your reaction is. Disagreement happens. How you handle it is what matters.&lt;/li&gt;
&lt;li&gt;&amp;quot;The customer has now changed their requirements; they need the project to do (whatever) different.&amp;quot; The ToDo list now needs &amp;quot;categories&amp;quot;. The ToDo list now needs to be able to sort by dates. Whatever. How does this break your domain model? More importantly, what changes do you identify that need to be made? Let&apos;s write some of that code now. How does this change your tests?&lt;/li&gt;
&lt;li&gt;&amp;quot;We now need to store to a database&amp;quot; or &amp;quot;to a different database&amp;quot; or &amp;quot;to several different databases (sharding)&amp;quot;. Ideally, we&apos;ll pick something you&apos;ve never seen before. I want to see how you&apos;ll approach using something or doing something you&apos;ve never done before: where do you start? How do you start?&lt;/li&gt;
&lt;li&gt;&amp;quot;How would you put a DevOps pipeline around this thing?&amp;quot; What&apos;s your tools, how would you relate it back to stories, the whole nine yards.&lt;/li&gt;
&lt;li&gt;&amp;quot;Oh, my! We need to secure this thing, stat!&amp;quot; What&apos;s insecure? What&apos;s already secure? Where do you begin doing the security analysis?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;... and so on. The goal here is to push your boundaries a little, and yes, maybe pile on a little stress to see how you react. But at every step, something that is what you&apos;ll actually have to deal with, every day, when working for a consulting company.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Assuming you have the chops we&apos;re looking for, we hire you.&lt;/strong&gt; This part is pretty simple, if you ask me. But my CFO, now he takes over. :-)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&apos;s our recruiting process.&lt;/p&gt;
&lt;p&gt;By the way, I say all of this here because none of this is Secret Sauce(TM). We want the entire process to be entirely transparent. No &amp;quot;hidden agenda&amp;quot;. Yes, I&apos;ll admit, right up front, what each stage is designed to do, and why. I&apos;ll even tell you, right from the beginning, if you ask. Yes, it&apos;s a little longer than your average &amp;quot;one-hour interview with the hiring manager&amp;quot;; but if you notice, the time commitment on the iTrellis side is 30 minutes (recruiter call) + code evaluation time, probably not more than 30 minutes (my or an engineer&apos;s time) + pairing time, not more than 30 - 45 minutes per pair (of an engineer&apos;s time), which is actually pretty comparable to your average &amp;quot;stand at the whiteboard and code&amp;quot; interview time. Yes, you&apos;ve put in 10 or so hours into the coding project--but it&apos;s &lt;em&gt;coding&lt;/em&gt;, and tell me right now, which would you rather do: a full eight-hour &amp;quot;interview loop&amp;quot; in front of people at a whiteboard, or snuggled up with the cat in front of the TV, gloriously hacking using your favorite IDE and your favorite libraries with your favorite tunes blasting through your favorite headphones?&lt;/p&gt;
&lt;p&gt;Yeah, I thought so. (So do most of the candidates who come through, whether we accept them or not. Of course, they could be trying to just brown-nose me, hard to say. )&lt;/p&gt;
&lt;p&gt;How do I know it works? A couple of reasons. One, we&apos;ve gotten some great hires out of it. (OK, yes, that could be just luck--random luck could give you that, too.) Two, we&apos;ve had no &amp;quot;bozo&amp;quot; hires. (OK, we&apos;ve only been around a year, so again, we could just be lucky.) Three, we&apos;ve had more than a few candidates that looked great on paper either walk away from the coding challenge entirely (buh-bye!) or turn in some pretty weak results. Sure, they might&apos;ve been great, but frankly, if your audition tape is bad, your band is not going to get gigs, either.&lt;/p&gt;
&lt;p&gt;But mostly, I have faith in this process because it lends itself well to unit-testing; at some point (haven&apos;t done it yet, but this is in my plans for 2015), I&apos;m going to slip a few &amp;quot;known quantities&amp;quot; into the system and see how they do: I&apos;m going to slip a complete newbie with great confidence and a few buzzwords into the process to see if they can get all the way through, and I&apos;m going to slip an amazing coder with a crappy cover resume in as well, just to see how we do. And, by the way, note that I&apos;m not part of the recruiting process: as soon as I could get myself out of the way of it, I did, because I didn&apos;t want to create a company of Ted-clones. (Which is also something that we tend to do intuitively: prefer the familiar, and nothing is more familiar than the self. This is part of the reason why a team of white men tends to stay a team of white men.)&lt;/p&gt;
&lt;p&gt;If you&apos;ve made it this far, thanks for reading. Two more important points, then I&apos;m out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Did I mention we&apos;re hiring? We&apos;re hiring. At this exact moment we&apos;re looking for Java folks who love writing automated tests and working in the DevOps pipeline; and we&apos;re hiring for people who have good C# skills and want to work with a client who&apos;s building a modern (DurandalJS, Azure, etc) web app. &lt;a href=&quot;mailto:hr@itrellis.com&quot;&gt;Contact our recruiters&lt;/a&gt; or contact me if you&apos;re interested.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This process is licensed &amp;quot;Creative Commons&amp;quot; (if a process can be so licensed, that&apos;s just to make the lawyers happy), so if you want to take it and use it for your own company&apos;s hiring process, go for it. Nothing would make me happier than for the industry to reject the coding-at-the-whiteboard nonsense for something like this or derived from this. (Because, in truth, this is in turn derived from lots of different hiring processes I went through over my 25 years.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Peace, out, y&apos;all.&lt;/p&gt;
&lt;p&gt;(&lt;strong&gt;UPDATE 2021:&lt;/strong&gt; Hey, I no longer work for iTrellis, but I think the process is still interesting. I&apos;ve updated the post accordingly.)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2014 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2014/2014-tech-predictions.html</link>
      <pubDate>Fri, 3 Jan 2014 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2014/2014-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;Here we go again: the annual review of last year&apos;s predictions, and a set of new ones for the new year.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h3&gt;2013 Retrospective&lt;/h3&gt;
&lt;p&gt;Without further ado, first we examine last year&apos;s Gregorian prognostications:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    &amp;lt;ul&amp;gt;
      &amp;lt;li&amp;gt;
        &amp;lt;p&amp;gt;
          &amp;lt;b&amp;gt;THEN:&amp;lt;/b&amp;gt;
          &amp;lt;i&amp;gt;&amp;quot;Big data&amp;quot; and &amp;quot;data analytics&amp;quot; will dominate the enterprise landscape.&amp;lt;/i&amp;gt;
        &amp;lt;/p&amp;gt;
        &amp;lt;p&amp;gt;
          &amp;lt;b&amp;gt;NOW:&amp;lt;/b&amp;gt; Yeah, it was a bit of a slam dunk breakaway kind of call, but it clearly
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;counts. Vendors and consulting companies were climbing all over themselves to talk&lt;br /&gt;
about &amp;quot;big data&amp;quot;, and startups basing their existence on gathering, analyzing, displaying&lt;br /&gt;
and (theoretically) offering insight from &amp;quot;big data&amp;quot; were all the rage in the startup&lt;br /&gt;
community, such as local startup &lt;a href=&quot;http://www.predixion.com&quot;&gt;Predixion&lt;/a&gt; (CTO&apos;ed&lt;br /&gt;
by a buddy of mine). If you live anywhere in the Pacific Northwest, chances are there&apos;s&lt;br /&gt;
a similar kind of startup within spitting distance of you right now. 1-0.&lt;/p&gt;
&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;b&gt;THEN:&lt;/b&gt;
              &lt;i&gt;NoSQL buzz will start to diversify.&lt;/i&gt;
            &lt;/p&gt;
            &lt;p&gt;
              &lt;b&gt;NOW:&lt;/b&gt; It didn&apos;t happen quite as much as I&apos;d expected, but the various vendors
are, in fact, starting to use terms other than &quot;NoSQL&quot; to define themselves. In particular,
we&apos;re seeing database vendors (MongoDB, Neo4J, Cassandra being my principal examples)
talking about being a &quot;document database&quot; or a &quot;graph database&quot; instead of being a
&quot;NoSQL&quot; database, though they&apos;re fairly quick to claim the NoSQL tag when it comes
to differentiating against the traditional relational database. Since I said &quot;start&quot;
to diversify, I&apos;m going to take the win. 2-0.
&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;b&gt;THEN:&lt;/b&gt;
              &lt;i&gt;Desktops increasingly become niche products.&lt;/i&gt;
            &lt;/p&gt;
            &lt;p&gt;
              &lt;b&gt;NOW:&lt;/b&gt; Well, this one is hard to call. Yes, desktop sales have plummeted, but
it&apos;s hard to see what those remaining sales are being used for. I will point out that
the Mac Pro, with it&apos;s radically-different internal construction, definitely puts
a new spin on the desktop, but I&apos;m not sure that this counts. Since I took the benefit
of the doubt on the last one, I&apos;ll forgot it on this one. 2-1.
&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;b&gt;THEN:&lt;/b&gt;
              &lt;i&gt;Home servers will start to grow in interest.&lt;/i&gt;
            &lt;/p&gt;
            &lt;p&gt;
              &lt;b&gt;NOW:&lt;/b&gt; I wish I had sales numbers to go with some of this stuff, as hard evidence,
but the fact that many people are using their console devices (XBox, XBoxOne, PS3,
PS4, etc) as media servers means I missed the boat on this one. I think we may still
see home servers continue to rise, but the clear trend has been to make the console
gaming device into a server, and not purchase servers on their own to serve as media
servers. 2-2.
&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;b&gt;THEN:&lt;/b&gt;
              &lt;i&gt;Private cloud is going to start getting hot.&lt;/i&gt;
            &lt;/p&gt;
            &lt;p&gt;
              &lt;b&gt;NOW:&lt;/b&gt; Meh. I see certain cloud vendors talking about private cloud, but for
the most part the emphasis is still on public cloud. 2-3. Not looking good for the
home team.
&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;b&gt;THEN:&lt;/b&gt;
              &lt;i&gt;Oracle will release Java8, and while several Java pundits will decry
&quot;it&apos;s not the Java I love!&quot;, most will actually come to like it.&lt;/i&gt;
            &lt;/p&gt;
            &lt;p&gt;
              &lt;b&gt;NOW:&lt;/b&gt; Well, let&apos;s start with the fact that Java8 actually didn&apos;t ship this year.
And even that, what I would have guessed would be a hugely-debated and hotly-contested
choice, really went by without much fanfare or complaint, except from some of the
usual hard-liner complaint sources. Which means one of two things: either (a) it&apos;s
finally come to pass that most of the people developing on top of the JVM really don&apos;t
care about the Java language&apos;s growth anymore, or (b) the community felt as Oracle&apos;s
top engineering brass did, that getting this release &quot;right&quot; was far better than getting
it out on the promised deadline. And while I agree with the (b) group on that, it
still means that the prediction was way off. 2-4.
&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;b&gt;THEN:&lt;/b&gt;
              &lt;i&gt;Microsoft will start courting the .NET developers again.&lt;/i&gt;
            &lt;/p&gt;
            &lt;p&gt;
              &lt;b&gt;NOW:&lt;/b&gt; Quite frankly, this one got left in dust almost the moment that Ballmer&apos;s
retirement was announced. Whatever emphasis the company as a whole might have put
into courting .NET developers back into the fold was immediately shelved, at least
until a successor comes in to take Ballmer&apos;s place and decide what kind of strategy
the company as a whole will pursue. Granted, the individual divisions within Microsoft,
most notably DevDiv, continue to try and woo the developer community, but that was
always going to be the case. However, the lack of any central &quot;push&quot; from the company
effectively meant that the perceived &quot;push&quot; against .NET in favor of WinRT was almost
immediately left behind, and the subsequent declaration of the Surface&apos;s failure (and
Surface was by far the most public and prominent of the WinRT-based devices) from
most corners meant that most .NET developers who cared about this breathed a sigh
of relief and no longer felt those Microsoft cyclical Darwinian crosshairs (the same
ones that claimed first C programmers, then C++ programmers, then COM programmers)
on their back. Still, no points. 2-5.
&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;b&gt;THEN:&lt;/b&gt;
              &lt;i&gt;Samsung will start pushing themselves further and further into the
consumer market.&lt;/i&gt;
            &lt;/p&gt;
            &lt;p&gt;
              &lt;b&gt;NOW:&lt;/b&gt; And boy, howdy, did they. Samsung not only released several new versions
of their various devices into the market, but they&apos;ve also really pushed their consumer
electronics in other form factors, too, such as their TVs and such. If there is a
rival to Apple in the consumer electronics department, it is clearly Samsung, and
the various court cases and patent violation filings are obvious verification of that.
3-5.
&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;b&gt;THEN:&lt;/b&gt;
              &lt;i&gt;Apple&apos;s next release cycle will, again, be &quot;more of the same&quot;.&lt;/i&gt;
            &lt;/p&gt;
            &lt;p&gt;
              &lt;b&gt;NOW:&lt;/b&gt; Can you say &quot;iPhone 5c&quot;, and &quot;iPad Air&quot;, boys and girls? Even iOS7 is
basically the same OS, with a skinnier font and--oh, wow, innovation!--nested folders.
4-5.
&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;b&gt;THEN:&lt;/b&gt;
              &lt;i&gt;Visual Studio 2014 features will start being discussed at the end of
the year.&lt;/i&gt;
            &lt;/p&gt;
            &lt;p&gt;
              &lt;b&gt;NOW:&lt;/b&gt; Microsoft tossed me a major curve ball with their announcement of quarterly
releases, and the subsequent release of Visual Studio 2013, and as a result, we haven&apos;t
really seen the traditional product hype cycle out of the Microsoft DevDiv that we&apos;re
used to. Again, how much of that is due to internal confusion over how to project
their next-gen products out into the world without a clear Ballmer successor, and
how much of that was planned from the beginning isn&apos;t clear, but either way, we ain&apos;t
heard a peep outta nobody about C# 6 at all in 2013, so... 4-6.
&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;b&gt;THEN:&lt;/b&gt;
              &lt;i&gt;Scala interest wanes.&lt;/i&gt;
            &lt;/p&gt;
            &lt;p&gt;
              &lt;b&gt;NOW:&lt;/b&gt; If anything, the opposite took place--Typesafe, Scala&apos;s owner/pimp/corporate
backer, made some pretty splashy headlines within the JVM community, and lots of people
talked a lot about it in places where Scala wasn&apos;t being discussed before. We can
argue about whether that indicates just a strong marketing effort (where before Typesafe&apos;s
formation there really was none) or actual growth in acceptance, but either way, I
can&apos;t claim that it &quot;waned&quot;, so the score becomes 4-7.
&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;b&gt;THEN:&lt;/b&gt;
              &lt;i&gt;Interest in native languages will rise.&lt;/i&gt;
            &lt;/p&gt;
            &lt;p&gt;
              &lt;b&gt;NOW:&lt;/b&gt; Again, this one is hard to judge. There&apos;s been some uptick in interest
in those native languages (Rust, Go, etc), and certainly there&apos;s been some interesting
buzz around some kind of Phoenix-like rise of C++, but none of it has really made
waves within the mainstream that I can see. (Then again, I don&apos;t really spend a lot
of time in those areas where native languages would have made a larger mark, so this
could be observer&apos;s contextual bias at work here.) That said, more native-based languages
are emerging, and certainly Apple&apos;s interest and support in LLVM (which, contrary
to it&apos;s name, is not really a &quot;virtual machine&quot;, per se) can be seen as such, but
not enough to make me feel comfortable saying I got this one right. 4-8.
&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;b&gt;THEN:&lt;/b&gt;
              &lt;i&gt;Hardware is the new platform.&lt;/i&gt;
            &lt;/p&gt;
            &lt;p&gt;
              &lt;b&gt;NOW:&lt;/b&gt; Surface was a bust. Chromebooks hardly registered on anybody&apos;s radar.
Dell threw out an arguable Surface-killer tablet, but for most consumer-minded folks
it never even crossed their minds, it seems. Hardware may be the new platform, and
certainly we&apos;re seeing a lot of non-x86-based machines continuing their race into
consumers&apos; hands, but most consumers don&apos;t think twice about the hardware as much
as they do the visible projection of that hardware choice, in the operating system.
(Think about it this way: when you go buy a device, do you care about the CPU, or
the OS--iOS, Android, Windows8--running it?) 4-9.
&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;b&gt;THEN:&lt;/b&gt;
              &lt;i&gt;APIs for lots of things are going to come out.&lt;/i&gt;
            &lt;/p&gt;
            &lt;p&gt;
              &lt;b&gt;NOW:&lt;/b&gt; Oh, my, yes. More on this later, but for now... 5-9.
&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
Well, with a final tally of 5 &quot;rights&quot; to 9 &quot;wrongs&quot;, clearly my 2013 record was about
as win-filled as the Baltimore Ravens&apos; 2013 record. *sigh* Oh, well, can&apos;t win &apos;em
all every year, right? 
&lt;h3&gt;2014 Predictions
&lt;/h3&gt;&lt;p&gt;
Now, though, let&apos;s do the fun part: What does Ted think 2014 has in store for us geeky
types? 
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;iOS, Android and Windows8 start to move into your car.&lt;/b&gt; Audi has already announced
this. Ford announced this last year with their SDK release. Frankly, with all the
emphasis on &quot;wearable tech&quot; and &quot;alternative tech&quot;, this seems a natural progression,
considering how much time Americans, at least, spend time in their car. What, exactly,
people will want software developers to do with this capability remains entirely unclear
to me (and, it seems, to everybody else, given the lack of apps for the Ford SDK so
far), but auto manufacturers will put it into their 2015 models just because their
competitors are starting to, and the auto industry is one place were you cannot be
seen as not keeping up with the neighbors.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Wearable tech hypes up (with little to no actual adoption or innovation).&lt;/b&gt; The
Samsung Smart Watch is out, one of nearly a dozen models introduced in 2013. Then
there was Google Glass. And given that the tech industry is a frequent &quot;hype it before
we even barely know it&apos;s going to work&quot; kind of place, this one seems like another
fast breakway layup kind of claim. Note that I fully expect that what we see offered
will, in time, be as hip and as cool as the original Newton, meaning that these first
iterations will be stumblin&apos;, fumblin&apos;, bumblin&apos; attempts to try and see what anybody
can do with these things to make them even remotely useful, and that unless you like
living on the very edge of techno-geekery, there&apos;ll be absolutely zero reason for
anyone to get one for at least calendar year 2014.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Apple&apos;s gadgets will be more of the same.&lt;/b&gt; Same one as last year: iPhone, iPad,
iPod, MacBook, they&apos;re all going to be incremental refinements on what we see already.
There will be no AppleTV, there will be no iWatch, there will be no radical new laptop-ish
thing. Apple is clearly the market leader, and they are clearly in the grips of the
Innovator&apos;s Dilemma, and they have no clear challenger (yet) that threatens to dethrone
them, leaving them with no reason to shake up the status quo.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Android market consolidates further around Samsung and Motorola.&lt;/b&gt; The Android
consumer market has slowly been collapsing around those two manufacturers, and I don&apos;t
see any reason for that trend to change. Yes, other carriers will continue to offer
Android on their devices, and yes, other device manufacturers will continue to put
Android on their devices, and yes, Android will continue to appear on things other
than tablets and phones, but as far as the consumer electronics world goes, the Android
market will be classified as Samsung, Motorola, and everybody else.&lt;/li&gt;&lt;li&gt;&lt;b&gt;We&apos;ll see one iOS release, two minor Android releases, and maybe two Windows8 minor
releases.&lt;/b&gt; The players are basically set, the game plans are already in play, and
nobody appears to have any kind of major game-changing feature set in the wings. 2014
will be a year of minor releases, tweaks to the existing systems and UIs, minor software
improvements, and so on. I can&apos;t see the mobile market getting any kind of major shock
or surprise this year.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Windows 8/8.1/9/whatever gains a little respect, but not market share gains.&lt;/b&gt; Windows8
as a tablet OS has been quietly gathering some converts, particularly among those
who didn&apos;t find themselves on the WindowsStore-only SurfaceRTs, and as such, I think
the &quot;Windows line&quot; will begin to gather more &quot;critics&apos; choice&quot; kinds of respect, but
that&apos;s not going to translate into much in the way of consumer sales. Unfortunately
for the Microsoftians, Windows as of yet doesn&apos;t demonstrate any kind of compelling
reason to choose it over the other two market leaders (iOS and Android), and until
that happens, Windows8, as a device OS, remains a distant third and always will.&lt;/li&gt;&lt;li&gt;&lt;b&gt;UI/UX emphasis is going to start moving to &quot;alternate&quot; input streams.&lt;/b&gt; Microsoft&apos;s
Kinect has demonstrated that gesture is a viable input technology. Google Glass demonstrated
that eyeballs can drive a UI. Voice commands are making their way into console gaming/media
devices (XBox, etc). This year, enterprise and business developers, looking for ways
to make a splash and justify greater research budgets, are going to start experimenting
with how those &quot;alternative&quot; kinds of input can be utilized in non-gaming scenarios.
Particularly when combined with the rise of automobiles offering programmable SDKs/platforms
(see above), this represents a huge, rich area for exploration.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Java-the-language starts to see a resurgence of &quot;mojo&quot;.&lt;/b&gt; Java8 will ship this
year--not even God Himself could stop that at this point. And once it does, Java-the-language
will see a revitalization as developers who&apos;ve been flirting with Groovy, Scala, Clojure,
and other lambda-supporting languages but can&apos;t use them on the job start to bring
those ideas into Java APIs. Google&apos;s already been doing this with Guava, but now many
of those ideas--already percolating in some libraries--will explode into common usage.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Meanwhile, this will be a quiet year for C#.&lt;/b&gt; The big news coming out of Microsoft,
&quot;Roslyn&quot;, the &quot;compiler-as-a-service&quot; rewrite of the C# and Visual Basic compilers,
won&apos;t be of much use to most developers on a practical level, and as a result, this
will likely be a pretty quiet year for C# and VB.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Functional languages will remain &quot;hipster&quot; tools that most people can&apos;t use.&lt;/b&gt; Haskell
remains far out of reach for most developers, and that&apos;s the most approachable of
the various functional languages discussed. (Don&apos;t even get me started on Julia, Pure,
Clean, or any of the others.) As much as I wish to the contrary, this is also likely
to remain true for several of the &quot;hybrid&quot; languages, like Scala, F#, and Clojure,
though I do think they will see some modest growth as some of the upper-echelon development
community begins to grok them. Those who understand them will continue to do some
amazing things with them, but this is not the year I would suggest starting a business
with anything &quot;functional&quot; as part of its business model, because not only will it
be difficult to find developers who can use those tools, but trying to sell developer-facing
things with those tools at the core will find a pretty dry and dusty market.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Dynamic languages will see continued growth and success.&lt;/b&gt; Ruby doesn&apos;t look
to be slowing down, Node/JavaScript only looks to get more hyped, and Objective-C
remains the dominant language for doing iOS development, which itself doesn&apos;t look
to be slowing down. More importantly, I think we&apos;re going to start to see a rise in
hybrid &quot;static/dynamic&quot; languages, wherein developers can choose (based on the way
they write their code) compiler enforcement as they wish. Between the introduction
of &quot;invokedynamic&quot; in Java7 (and its deeper use in Java8), and &quot;dynamic&quot; in C# getting
some serious exercise in the Oak framework, I&apos;m becoming more and more convinced that
having a language that supports both static and dynamic typing capabilities represents
the best compromise between those two poles of software development languages. That
said, neither Java nor C# &quot;gets it all the way right&quot; on this topic, and I suspect
that somewhere out there, there&apos;s a language hacker who&apos;s got a few ideas that he
or she will trot out and make us all go &quot;Doh!&quot;&lt;/li&gt;&lt;li&gt;&lt;b&gt;HTML 5 &quot;fragmentation&quot; will start to echo in the industry.&lt;/b&gt; Unfortunately, HTML
5 is not the same thing to all browsers, and those who are looking to HTML 5 as a
way to save them from platform differences are going to start to feel some pain. That,
in turn, is going to lead to some backlash as they are forced to deal with something
they thought they were going to be saved from.&lt;/li&gt;&lt;li&gt;&lt;b&gt;&quot;Mobile browsers&quot; become just &quot;browsers&quot;.&lt;/b&gt; With the explosive growth of devices
(tablets and phones) and the explosive growth of the capabilities of those devices
(processor(s), memory, and so on), the need for a &quot;crippled&quot; or &quot;low-end-optimized&quot;
browser has effectively gone the way of the Dodo bird. As a result...&lt;/li&gt;&lt;li&gt;&lt;b&gt;&quot;Mobile web&quot; starts a slow, steady slide into irrelevancy.&lt;/b&gt; ... sites optimized
for &quot;mobile&quot; browsing experiences--which represents a non-trivial development effort
in most cases--will start to drop away, mostly due to neglect. Instead...&lt;/li&gt;&lt;li&gt;&lt;b&gt;&quot;Responsive web&quot; becomes the new black.&lt;/b&gt; ... we&apos;ll see web sites using CSS frameworks
(among other tools) to build user interfaces that adjust themselves to the physical
viewsizes and input capabilities of the target browser. Bootstrap is an obvious frontrunner
here for building said kinds of user interfaces, but don&apos;t be surprised if a number
of other CSS and JavaScript frameworks to achieve the same ends start to spring up.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Microsoft fails to name a Ballmer successor.&lt;/b&gt; Yeah, this one&apos;s a stretch. It&apos;s
absolutely inconceivable that they wouldn&apos;t. And yet, in all honesty, I can&apos;t see
the Microsoft board finding somebody that meets Bill&apos;s approval from outside of the
company, and I can&apos;t imagine anyone inside of the company who isn&apos;t somehow &quot;tainted&quot;
by the various internecine wars that have been fought since Bill&apos;s departure. It is,
quite frankly, a mess, and I don&apos;t know that it&apos;ll be cleaned up before this time
next year. It would be a horrible result were that to be the case, by the way, but...
*shrug* I dunno. Pretty clearly, whomever it is, is going to have a monumental task
in front of them.&lt;/li&gt;&lt;li&gt;&lt;b&gt;&quot;Programmable Web&quot; becomes an even bigger thing, leading companies to develop APIs
that make no sense to anybody.&lt;/b&gt; Right now, as we spin up 2014, it&apos;s become the
fashionable thing to build your website not as an HTML-based presentation layer website,
but as a series of APIs. For some companies, that makes sense; for others, though,
that is going to be a seductive Siren song that leads them to a huge development effort
for little payoff. Note, I think almost all companies have interesting data and/or
resources that can be exposed as APIs that would lead to some powerful mashups--I&apos;m
not arguing otherwise. But what I think we&apos;re about to stumble into is the cargo-culting
blind obedience to the letter of the idea that so many companies undertake when a
new concept hits the industry hard, as &quot;Web APIs&quot; are doing now.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Five new single-page JavaScript MVC application frameworks will ship and gather
interest.&lt;/b&gt; For those of you who know me from the Java world, remember the 2000s
and the huge glut of open-source Web frameworks that led us all into analysis paralysis
for a half-decade or more? I see absolutely no reason why the exact same thing isn&apos;t
already under way in the JavaScript Web framework world, with the added delicious
twist that in the JavaScript world, we can do it on BOTH the client AND the server.
Let the forking begin.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Apple&apos;s MacPro machine inspires dozens of knock-off clones.&lt;/b&gt; When the MacBook
came out, silver-metal cases with chiclet keyboards suddenly appeared all over the
PC clone market. When the MacBook Air came out, suddenly thin was in. What on Earth
makes us think that the trashcan-sized MacPro desktop/server isn&apos;t gong to have exactly
the same effect?&lt;/li&gt;&lt;li&gt;&lt;b&gt;Desktop machine sales creep slightly higher.&lt;/b&gt; Work this through with me before
you shoot it down out of hand: Tablet sales are continuing to skyrocket, and nothing
seems to change that. But people still need to produce stuff (reports, articles, etc),
and that really requires a keyboard. But if tablets are easier to consume data on
the road, you&apos;re more likely to carry your tablet instead of your laptop (and most
people--myself wildly excluded--don&apos;t like carrying more than one or at most two devices
with them). Assuming that your mobile workload is light enough that you can &quot;get by&quot;
using your tablet, and you don&apos;t want to carry a laptop *and* a tablet, you&apos;re more
likely to leave your laptop at home or at work. Once your laptop is a glorified workstation,
why pay that added premium for a laptop at all? In other words, I think people are
going to start doing this particular math, and while tablets will continue to eat
away at the &quot;I need a mobile computing solution&quot; sales, desktops are going to start
to eat away at the &quot;I need a computing solution for my desk&quot; sales. Don&apos;t believe
me? Look around the office at all the workstations powered by laptops already, and
then start looking at whether those laptops are actually being used as laptops, and
whether that mobility need could, in fact, be replaced by a far lighter tablet. It&apos;s
a stretch, and it may not hit in 2014, but I really think that the world is going
to slowly stratify into an 80/20 split of tablets and desktops.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Dozens of new &quot;cloud&quot; platforms will be introduced, and most of them will remain
entirely irrelevant behind the &quot;Big Three&quot;.&lt;/b&gt; Lots of the big players are going
to start tossing out their version of a cloud platform if they haven&apos;t already (HP,
Oracle, IBM, I&apos;m looking at you), and smaller players are going to start offering
&quot;cloud&quot; platforms of their own (a la Rackspace), but fundamentally, the cloud will
remain a &quot;Big Three&quot; place: Amazon&apos;s AWS, Microsoft&apos;s Azure, and Google&apos;s Cloud Platform.&lt;/li&gt;&lt;li&gt;&lt;b&gt;We will never see any kind of official announcement, much less actual working prototypes,
around Amazon&apos;s &quot;Drone Delivery&quot; program ever again.&lt;/b&gt; Sure, Jeff made a splash
when he announced it. Sure, it resonates with the geek crowd. Sure, it seems like
a spiffy idea on paper. Do you have any idea of how much infrastructure and overhead
(and potential for failure that has nothing to do with geeks deploying &quot;anti-drone
defenses&quot;) would be involved? No way. What&apos;s more, Amazon is not really in the shipping
business (as the all-but-failed Amazon &quot;deliver groceries to your front door&quot; program
highlights), but in the &quot;We&apos;ll sell it to you and ship it through somebody else&quot; business.
It&apos;s a cool idea, but it&apos;ll never, ever, EVER, see the light of day.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;As always, thanks for reading, and keep this channel open--I&apos;ve got some news percolating&lt;br /&gt;
about my next new adventure that I&apos;m planning to &amp;quot;splash&amp;quot; in mid-January. It won&apos;t&lt;br /&gt;
be too surprising, but it&apos;s exciting (at least to me), and hopefully represents an&lt;br /&gt;
adventure that I can still be... uh... adventuring... for years to come.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>On (Free) Speaking</title>
      <link>http://blogs.newardassociates.com/blog/2013/on-free-speaking.html</link>
      <pubDate>Thu, 12 Dec 2013 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2013/on-free-speaking.html</guid>
      	<description>
	&lt;p&gt;Remember when I posted about speaking for free at conferences? And everybody got so upset? Because, you know... community!&lt;/p&gt;
&lt;p&gt;Somebody tell me how &lt;a href=&quot;http://imgur.com/r/MusicNews/sOsHnbf&quot;&gt;this&lt;/a&gt; is any different.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;When a conference chooses not to offer its speakers even a modest stipend beyond expenses (and let&apos;s not even begin to discuss the conferences who don&apos;t bother covering expenses), they are essentially asking the speaker to do all that work for free. Just like asking a musician to use his music for free. And some musicians will do it for &amp;quot;the exposure&amp;quot;, because they want the gig credit to list on their website more than they want the money. But at some point, the band needs to be paid, or else they break up and great music goes unplayed.&lt;/p&gt;
&lt;p&gt;Just sayin&apos;.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Speakers, stipends, and expenses</title>
      <link>http://blogs.newardassociates.com/blog/2013/on-speakers-expenses-and-stipends.html</link>
      <pubDate>Mon, 26 Aug 2013 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2013/on-speakers-expenses-and-stipends.html</guid>
      	<description>
	&lt;p&gt;In the past, I&apos;ve been asked about &lt;a href=&quot;http://channel9.msdn.com/Shows/HanselminutesOn9/Hanselminutes-on-9-The-Death-of-the-Professional-Conference-Speaker&quot;&gt;my thoughts on conferences and the potential &amp;quot;death&amp;quot; of conferences&lt;/a&gt;, and the question came up again more recently in a social setting. It&apos;s been a while since I commented on it, and if anything, my thoughts have only gotten sharper and clearer.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h3&gt;On speaking professionally&lt;/h3&gt;
&lt;p&gt;When you go to the dentist&apos;s office, who do you want holding the drill--the &amp;quot;enthused, excited amateur&amp;quot;, or the &amp;quot;practiced professional&amp;quot;?&lt;/p&gt;
&lt;p&gt;The use of the term &amp;quot;professional&amp;quot; here, by the way, is not in its technical use of the term, meaning &amp;quot;one who gets paid to perform a particular task&amp;quot;, but more in a follow-on to that, meaning, &amp;quot;one who takes their commitment very seriously, and holds themselves to the same morals and ethics as one who would be acting in a professional capacity, particularly with an eye towards actually being paid to perform said task at some point&amp;quot;. There is an implicit separation between someone who plays football because they love it, for example, going out on Sunday afternoons and body-slamming other like-minded individuals just because of the adrenaline rush and the male bonding, and those who go out on Sunday afternoons and command a rather decently-sized salary ($300k at a minimum, I think?) to do so. Being a professional means that not only is there a paycheck associated with the activity, but a number of responsibilities--this means not engaging in stupid activity that prevents you from being able to perform your paid activity. In the aforementioned professional athlete&apos;s case, this means not going out and doing backflips on a dance floor (&lt;em&gt;ahem&lt;/em&gt;, Gronkowski) or playing some other sport at a dangerous level of activity. (In the professional speaker&apos;s case, it means arranging travel plans to arrive at the conference at least a day before your session--never the day of--and so on.)&lt;/p&gt;
&lt;p&gt;For a lot of people, speaking at an event is an opportunity for them to share their passion and excitement about a given topic--and I never want to take that opportunity away from them. By all means, go out and speak--and maybe in so doing, you will find that you enjoy it, and will be willing to put the kind of time and energy required into doing it well.&lt;/p&gt;
&lt;p&gt;Because, really, at the end of the day, the speakers you see in the industry that are very, very good at what they do, they weren&apos;t just &amp;quot;born&amp;quot; that way. They got that way the same way professional athletes got that way, by doing a lot of preparation and work behind the scenes. They got that way because they got a lot of &amp;quot;first team reps&amp;quot;, speaking at a variety of events. And they continue to get better because they continue to speak, which means continuously putting effort and energy into new talks, into revising old talks, and so on.&lt;/p&gt;
&lt;p&gt;But all of that time can&apos;t be for free, or else people won&apos;t do it.&lt;/p&gt;
&lt;p&gt;Go back to the amateur athlete scenario: the more time said athlete has to work at a different job to pay the bills, the less time they have to prep and master their athletic skills. This is no different for speakers--if someone is already spending 8 hours a day working, and another 6 to 8 hours a day sleeping, then that&apos;s 8 to 10 hours in the day for everything else, including time spent with the family, eating, personal hygiene, and so on, including whatever relaxation time they can carve out. (And yes, we all need some degree of relaxation time.) When, exactly, is this individual, excited, passionate, enthused (or not), supposed to get those &amp;quot;first team reps&amp;quot; in? By sacrificing something else: time with the family, sleep, a hobby, whatever.&lt;/p&gt;
&lt;p&gt;Don&apos;t you think that they deserve some kind of compensation for that time?&lt;/p&gt;
&lt;p&gt;I know, I know, the usual response is, &amp;quot;But they&apos;re giving back to the community!&amp;quot; Yes, I know, you never really figured anything out on your own, you just ran off to StackOverflow or Google and found all the code you needed in order to learn the new technology--it was never any more effort on your own part than that. You OWE the community this engagement. And, by the way, you should also owe them all the code you ever write, for the same reason, because it&apos;s not like your employer ever gave you anything for that code, and it&apos;s not like you did all that research and study for the code you work on for them.&lt;/p&gt;
&lt;p&gt;See, the tangled threads of &amp;quot;why&amp;quot; we do something are often way too hard to unravel. So let&apos;s instead focus on the &amp;quot;what&amp;quot; you did. You submitted an abstract, you created an outline, you concocted some slides, you built some demos, you practiced your talk, you delivered it to the audience, and you submitted yourself to &amp;quot;life&apos;s slings and arrows&amp;quot; in the form of evaluations. And for all that, the conference organizers owe you nothing? In fact, you&apos;re required to pay for the privilege of doing all that?&lt;/p&gt;
&lt;h3&gt;On &amp;quot;professional&amp;quot; conferences&lt;/h3&gt;
&lt;p&gt;One dangerous trend I see in conferences, and it&apos;s not the same one I saw in 2009, is that the main focus of a conference is shifting; no longer is it a gathering of like-minded professionals who want to improve their technical skills by learning from others. Instead, it&apos;s turning into a gathering of people who want to party, play board games, gorge themselves on bacon, drink themselves to a stupor, play in a waterpark or go catch a Vegas show with naked women in it. Somehow, &amp;quot;professional developer conference&amp;quot; has taken on all the overtones of a Bacchanalian orgy, all in the name of &amp;quot;community&amp;quot;.&lt;/p&gt;
&lt;p&gt;Don&apos;t get me wrong--I think it can be useful to blow off some steam during a show, particularly because for most people, absorbing all this new information is mentally exhausting, and you need time to process it, both socially (in the form of hallway conversations) and physically (meaning, go give your body something to do while your mind is churning away). But when the focus of the conference shifts from &amp;quot;speakers&amp;quot; to &amp;quot;bacon bar&amp;quot;, that&apos;s a dangerous, dangerous sign.&lt;/p&gt;
&lt;p&gt;And you know what the first sign is that the conference doesn&apos;t think it&apos;s principal offering is the technical content? When they won&apos;t even cover the speakers&apos; costs to be at that event.&lt;/p&gt;
&lt;p&gt;Seriously, think about it for a moment: if the principal focus of this event is the exchange of intellectual and industrial information, through the medium of a lecture given by an individual, then where should your money go? The bacon bar? Or towards making sure that you have the best damn lecturers your budget can afford?&lt;/p&gt;
&lt;p&gt;When a conference doesn&apos;t offer to pick up airfare and hotel, then in my mind that conference is automatically telling the world, &amp;quot;We&apos;re willing to bring in the best speakers that are willing to do this all for free!&amp;quot; And how many of you would be willing to eat at a restaurant that said, &amp;quot;We&apos;re willing to bring in the best chefs that are willing to cook for free!&amp;quot;? Or go to a hospital that brings in &amp;quot;the best doctors that are willing to operate for free!&amp;quot;?&lt;/p&gt;
&lt;p&gt;And how many of you are willing to part of your own money to go to it?&lt;/p&gt;
&lt;p&gt;For community events like CodeCamps, it&apos;s an understood proposition that this is more about the networking and community-building than it is about the quality of the information you&apos;re going to get, and frankly, given that the CodeCamp is a free event, there&apos;s also an implicit &amp;quot;everybody here is a volunteer&amp;quot; that goes with it that explains--and, to my mind, encourages--people who&apos;ve never spoken before to get up and speak.&lt;/p&gt;
&lt;p&gt;But when you&apos;re a CodeMash, a devLink, or some of these other shows that are charging you, the attendee, a non-trivial amount of money to attend, and they&apos;re not covering speakers&apos; expenses at a minimum, then they&apos;re telling you that your money is going towards bacon bars and waterparks, not the quality of the information you&apos;re receiving.&lt;/p&gt;
&lt;p&gt;Yes, there are some great speakers who will continue to do those events, and Gods&apos; honest truth, if I had somebody to cover my mortgage and/or paid me to be there, I&apos;d love to do that, too. But many of those people who are paid by a company to be speaking at events are called &amp;quot;evangelists&amp;quot; and &amp;quot;salespeople&amp;quot;, and developers have already voted with their feet often enough to make it easy to say that we don&apos;t want a conference filled with &amp;quot;evangelists&amp;quot; and &amp;quot;salespeople&amp;quot;. You want an unbiased technical view of something? You want people to talk about a technology that don&apos;t have an implicit desire to sell it to you, so that they can tell you both what it&apos;s good for and where it sucks? Then you want speakers who aren&apos;t being paid by a company to be there; instead, you want speakers who can give you the &amp;quot;harsh truth&amp;quot; about a technology without fear of reprisal from their management. (And yes, there are a lot of evangelists who are very straight-shooting speakers, and I love &apos;em, every one. But there&apos;s a lot more of them out there who aren&apos;t.)&lt;/p&gt;
&lt;p&gt;In many cases, for the conference to deliver both the bacon bar and the speakers&apos; T&amp;amp;E, it would require your attendance fee to go up some. By rough back-of-the-napkin calculations, probably about $50 for each of you, depending on the venue, the length of the conference, the number of speakers (and the number of talks they each do), and the total number of attendees. Is it worth it?&lt;/p&gt;
&lt;p&gt;When you go to the dentist&apos;s office, do you want the &amp;quot;excited, enthused amateur&amp;quot;, or the &amp;quot;practiced professional&amp;quot;?&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>On &apos;Exclusive Content&apos;</title>
      <link>http://blogs.newardassociates.com/blog/2013/on-exclusive-content.html</link>
      <pubDate>Mon, 19 Aug 2013 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2013/on-exclusive-content.html</guid>
      	<description>
	&lt;p&gt;Although it seems to have dipped somewhat in recent years, periodically I get requests from conferences or webinars or other presentation-oriented organizations/events that demand that the material I present be &amp;quot;exclusive&amp;quot;, usually meaning that I&apos;ve never delivered said content at any other organized event (conference or what-have-you). And, almost without exception, I refuse to speak at those events, or else refuse to abide by the &amp;quot;exclusive&amp;quot; tag (and let them decide whether they still want me to speak for them).&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;People (by which I mean &amp;quot;organizers&amp;quot;--most speakers seem to get it intuitively if they&apos;ve spoken at more than five or so conferences in their life) have expressed some surprise and shock at my attitude. So, I decided to answer some of the more frequently-asked questions that I get in response to this, partly so that I don&apos;t have to keep repeating myself (yeah, right, as if said organizers are going to read my blog) and partly because putting something into a blog is a curious form of sanity-check, in that if I&apos;m way off, commenters will let me know posthaste.&lt;/p&gt;
&lt;p&gt;Thus...:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;Nobody will come to our conference/listen to our webinar if the content is the same as elsewhere.&amp;quot;&lt;/strong&gt; This is, by far, the first and most-used reaction I get, and let me be honest: if people came to your conference or fired up your webinar solely because of the information contained, they would never come to your conference or listen to your webinar. The Internet is huge. Mind-staggeringly huge. Anything you could possibly ever want about any topic you could ever possibly imagine, it&apos;s captured it somewhere. (There&apos;s a corollary to that, too; I call it &amp;quot;Whittington&apos;s Law&amp;quot;, which states, &amp;quot;Anything you can possibly imagine, the Internet not only has it, but a porn site version of it, as well&amp;quot;.) You will never have exclusive content, because unless I invented the damn thing, and I&apos;ve never shown it to anybody or ever used it before, somebody will likely have used it, written a blog post or a video tutorial or what-have-you, and posted it to the Internet. Therefore, by definition, it can&apos;t be exclusive.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;But even on top of that first point, no presentation given by the same guy using the same slides is ever exactly the same. Anybody who&apos;s ever seen me give a talk twice knows that a lot of how I give my presentations is extremely ad-hoc; I like to write code on the fly, incorporate audience feedback and participation, and sometimes I even get caught up in a tangent that we explore along the way. None of my presentations are ever scripted, such that if you filmed two of them and played them side-by-side, you&apos;ll see marked and stark differences between them. And frankly, if you&apos;re a conference organizer, you should be quite happy about this, because one of the first rules of presenting is to &amp;quot;Know thy audience&amp;quot;, but if you can&apos;t know your audience ahead of time, what course is left to you but to poll the audience when you first get started, and adjust your presentation based on that?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;Sure, the experience won&apos;t be as great as if they were in the room at the time, but if they can get the content elsewhere, why should they come to our conference?&amp;quot;&lt;/strong&gt; Well.... Honestly, that question really needs to be rephrased: &amp;quot;Given all the vast amounts of information out there on the Internet, why should someone come to your conference, period?&amp;quot; If you and your fellow organizers can&apos;t answer that question, then my content isn&apos;t going to help you in the slightest. TechEd and other big conferences that stream all of their content to the Web seem to be coming to the realization that there is something about the in-person experience that still creates value for attendees, so maybe you should be thinking about that, instead. Yes, you will likely lose a few ticket sales from people watching the content online, but if those numbers are staggeringly large, it means that your conference offered nothing but content in the first place, and you were going to see those numbers drop off significantly anyway once the majority of your audience figured out that the content is available elsewhere. And for free, no less.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;But why is this so important to you?&amp;quot;&lt;/strong&gt; Because, my friends, everything gets better with practice, and that includes presentations. When I taught for &lt;a href=&quot;http://www.develop.com&quot;&gt;DevelopMentor&lt;/a&gt; lo those many years ago, one of the fundamental rules was that &amp;quot;You don&apos;t really know a deck until you&apos;ve delivered it five times&amp;quot;. (I call it &amp;quot;Sumida&apos;s Law&amp;quot;, after the guy who trained me there.) What&apos;s more, the more often you&apos;ve presented on a subject, the more easily you see the &amp;quot;right&amp;quot; order to the topics, and better ways of explaining and analogizing those topics occur to you over time. (&amp;quot;Halloway&apos;s Corollary to Sumida&apos;s Law&amp;quot;: &amp;quot;Once you&apos;ve delivered a deck five times, you immediately want to rewrite it all&amp;quot;.) To be quite honest with you all, the first time I give a talk is much like the beta release of any software product: it takes user interaction and feedback before you start to see the non-obvious bugs.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I still respect the conference or webinar host that insists on exclusive content, and I wish you well finding your next speaker, but it won&apos;t be me. Or anyone I mentor or shepherd.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Programming Interviews</title>
      <link>http://blogs.newardassociates.com/blog/2013/programming-interviews.html</link>
      <pubDate>Mon, 19 Aug 2013 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2013/programming-interviews.html</guid>
      	<description>
	&lt;p&gt;Apparently I have become something of a resource on programming interviews: I&apos;ve had three people tell me they read the last two blog posts, one because his company is hiring and he wants his people to be doing interviews right, and two more expressing shock that I still get interviewed--which I don&apos;t really think is all that fair, more on that in a moment--and relief that it&apos;s not just them getting grilled on areas that they don&apos;t believe to be relevant to the job--and more on that in a moment, too.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;A couple of things have emerged in the last few weeks since the saga described earlier, so I thought I&apos;d wrap the thing up with a final post. Besides, I like things that come in threes.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;First, go see &lt;a href=&quot;http://channel9.msdn.com/Events/ALM-Summit/ALM-Summit-3/Technical-Interviewing-You-re-Doing-it-Wrong&quot;&gt;this video&lt;/a&gt;.&lt;/b&gt; Jonathan pinged me about it shortly after the second blog post came out, and damn if he and Mitch don&apos;t nail a bunch of things directly on the head. Specifically, I want to call out two lists they put into their slides (which I can&apos;t find online, or I&apos;d include a link, sorry).&lt;/p&gt;
&lt;p&gt;One, what are the things you&apos;re trying to answer in an interview? They call it out as three questions an interviewer or interview team is seeking to answer:
&lt;ol&gt;
&lt;li&gt;Can they do the job?&lt;/li&gt;
&lt;li&gt;Will they be motivated?&lt;/li&gt;
&lt;li&gt;Would they get along with the team?&lt;/li&gt;
&lt;/ol&gt;
Personally, #2 to me is a red herring--frankly, I expect that if you, the candidate, take a job with my company, then either you have determined that you will be motivated to work here, or else you can force yourself to be. I don&apos;t really expect you to be the company cheerleader (unless, of course, I&apos;m hiring you for that role), but I do expect professionalism: that you will be at work when you are scheduled or expected to be, that you will do quality work while you are there, and that you will look to make the best decisions possible given the information you have at the time. Motivation is not something I should be interviewing for; it&apos;s something you should be bringing.&lt;/p&gt;
&lt;p&gt;But the other two? Spot-on.&lt;/p&gt;
&lt;p&gt;And this brings me to my interim point: &lt;b&gt;I&apos;m not opposed to a programming test.&lt;/b&gt; I think I gave the impression to a number of readers that I think that I&apos;m too good or too famous or whatever to be tested on my skills; that&apos;s the furthest thing from the truth. I think you most certainly should be verifying that I have the technical chops to do the job you want me to do; what I do want to suggest, however, is that for a number of candidates (myself included), there are ways to determine my technical chops without forcing me to stand at a whiteboard and code with a pen. For some candidates, you can examine their GitHub profile and see how many repos they have that&apos;re public (and have a look through some of the code they wrote). In fact, what I think would be a &lt;i&gt;great&lt;/i&gt; interview question would be to look at a repo they haven&apos;t touched in a year, find some element of the code inside there, and ask them to explain what they were thinking when they wrote it. If it&apos;s well-documented, or if it&apos;s simple code, they&apos;ll be able to do that fairly quickly (once they context-swap to the codebase--got to give them time to remember, after all). If it&apos;s a complex or tricky bit, and they can&apos;t explain it...&lt;/p&gt;
&lt;p&gt;... well, you just learned something about the code they write, now didn&apos;t you?&lt;/p&gt;
&lt;p&gt;In my case, I have no public GitHub profile to choose from, but I&apos;m an edge case, in that you can also watch my videos, and/or read my books and articles. Granted, there&apos;s a chance that I have amazing editors who save me from incredible stupidity and make me look good... but what are the chances that somebody is doing that for over a decade, across several technology platforms, and all without any credit? Probably pretty close to nil, IMHO. I&apos;m not unique in this case--there&apos;s others whose work more or less speaks for itself, and I think you&apos;re disrespecting the candidate if you don&apos;t do your homework on the interview first.&lt;/p&gt;
&lt;p&gt;Which, by the way, brings up another point: As an interviewer, you have a responsibility to do your homework on the candidate before they walk in the door, particularly if you&apos;re expecting them to have done their homework on your firm. Don&apos;t waste my time (and yours, particularly since yours is probably a LOT more expensive than mine, considering that a lot of companies are doing &quot;interview loops&quot; these days with a team of people, and all of their time adds up). If you&apos;re not going to take my candidacy seriously, why should I take your job or job offer or interview seriously?&lt;/p&gt;
&lt;p&gt;The second list Jon and Mitch call out is their &quot;interviewing antipatterns&quot; list:
&lt;ul&gt;
&lt;li&gt;The Riddler&lt;/li&gt;
&lt;li&gt;The Disorienter&lt;/li&gt;
&lt;li&gt;The Stone Tablet&lt;/li&gt;
&lt;li&gt;The Knuth Fanatic&lt;/li&gt;
&lt;li&gt;The Cram Session&lt;/li&gt;
&lt;li&gt;Groundhog Day&lt;/li&gt;
&lt;li&gt;The Gladiator&lt;/li&gt;
&lt;li&gt;Hear No Evil&lt;/li&gt;
&lt;/ul&gt;
I want you to watch the video, so I&apos;m not going to summarize each here; go watch it. If you&apos;re in a position of doing hiring, ask yourself how many of those you yourself are perpetrating.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Second, go read &lt;a href=&quot;http://firstround.com/article/The-anatomy-of-the-perfect-technical-interview-from-a-former-Amazon-VP&quot;&gt;this article&lt;/a&gt;.&lt;/b&gt; I don&apos;t like that he has &quot;Dig into algorithms, data structures, code organization, simplicity&quot; as one of his takeaways, because I think most interviewers are going to see &quot;algorithms&quot; and &quot;data structures&quot; and stop there, but the rest seems pretty spot-on.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Third, ask yourself the critical question: What, exactly, are we doing wrong?&lt;/b&gt; You think you&apos;re an agile organization? Then ask yourself how much feedback you get on your interviewing process, and how you would know if you screwed it up. Yes, you will know if hire a bad candidate, but how will you know if you&apos;re letting good candidates go? Maybe you&apos;re the hot company that everybody wants to work at, and you can afford to throw some wheat out with the chaff a few times, but you&apos;re not going to be in that position for long if you do, and more importantly, you&apos;re not going to be in that position for long, period. If you don&apos;t start trying to improve your hiring process now, by the time you need to, it&apos;ll be too late.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Fourth, practice!&lt;/b&gt; When unit-testing came out, many programmers said, &quot;I don&apos;t need to test my code, my code is great!&quot;, and then everybody had a good laugh at their expense. Yet I see a lot of companies say essentially the same thing about their hiring and interview practices. How do you test an interview process? Easy--interview yourselves. Work with known-good conditions (people you know, people who work with you already, and so on), and run them through the process, but with the critical stipulation that &lt;i&gt;you must treat them exactly as you would a candidate&lt;/i&gt;. If you look at your tech lead and say, &quot;Yeah, this is where I&apos;d ask you a technical question, but I already know...&quot;, then unless you&apos;re prepared to do that for your candidates, you&apos;re cheating yourself on the feedback. It&apos;s exactly like saying, &quot;Yeah, this is where I&apos;d write a test checking to see how we handle a null in that second parameter, but I already know...&quot;. If you&apos;re not prepared to do the latter, don&apos;t do the former. (And if you are prepared to do the latter, then I probably don&apos;t want to work with you anyway.)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Fifth, remember: Interviewing is not easy!&lt;/b&gt; It&apos;s not easy on the candidates, and it shouldn&apos;t be on you. It would be great if you could just test somebody on one dimension of themselves and call it good, but as much as people want to pretend that a programmer is just a code-spewing cog in a machine, they&apos;re not. If you want well-rounded candidates, then you must interview all aspects of that well-roundedness to determine if they are or not.&lt;/p&gt;
&lt;p&gt;Whatever you interview for, that&apos;s what you will get.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>More on the Programming Tests saga</title>
      <link>http://blogs.newardassociates.com/blog/2013/more-on-the-programming-tests-saga.html</link>
      <pubDate>Thu, 25 Jul 2013 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2013/more-on-the-programming-tests-saga.html</guid>
      	<description>
	&lt;p&gt;A couple of people had asked how the story with the company that triggered the &quot;I Hate Programming Tests&quot; post ended, so I figured I&apos;d follow up with the rest of that story, and some thoughts.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;After handing in the disjoint-set solution I&apos;d come up with, the VP pondered things for a bit, then decided to bring me in for an in-person interview loop with a half-dozen of the others that work there. I said I&apos;d be happy to, and came in, did a brief meet-and-greet with the group of folks I&apos;d be interviewing with (plus, I think, a few others), and then we got to the first interview mono-a-mono, and after a brief &quot;Are you familiar with MVC?&quot;, we get into...&lt;/p&gt;
&lt;p&gt;... another algorithm challenge. A walk-up-to-the-whiteboard-and-code-this challenge.&lt;/p&gt;
&lt;p&gt;OK, whatever. I already said I&apos;m not great with algorithmic challenges like this, but maybe this guy didn&apos;t get the memo or he&apos;s just trying to see how I reason things through. So, sure, let&apos;s attack this, even though I haven&apos;t done this kind of problem in like twenty years. (One of the challenges was &quot;How do you sort a file of integer numbers when you can&apos;t store the entire collection of numbers in memory?&quot;, which wasn&apos;t an unfair challenge, just not something that I generally have to mess with. Honestly, in the working world, I&apos;ll start by going through the file number by number--or do chunks of the file in parallel using actors, if the file is large enough--and shove them into a database that&apos;s indexed on that number. But, of course, as with all of these kinds of challenges, the interviewer continues to throw constraints at the problem until we either get to the solution he wants or Ted runs out of imagination; in this case, I think it was the latter.) End result: not a positive win.&lt;/p&gt;
&lt;p&gt;Next interviewer walks in, he wasn&apos;t there for the meet-and-greet, which means he has even less context about me than the guy before me, and he immediately asks... another algorithmic challenge. &quot;If you have a tree of nodes, and you want to get a list of the nodes in rank order&quot; (meaning, a breadth-first search, where each node now gets a &quot;sibling&quot; pointer pointing to the sibling on its right in the tree, or null if it&apos;s the rightmost node at that depth level) &quot;how would you do it?&quot; Again, a fail, and now I&apos;m getting annoyed. I admitted, from the outset, that this is not the kind of stuff I&apos;m good at. We&apos;ve already made that point. I accept the &quot;F&quot; on that part of my report card. What&apos;s even more annoying, the interviewer keeps sighing and drumming his fingers in an obvious state of &quot;Why is this bozo wasting my time like this, I could be doing something vastly more important&quot; and so on, which, gotta say, was kind of distracting. End result: total fail.&lt;/p&gt;
&lt;p&gt;By this point, I&apos;m really annoyed. The VP comes to meet me, asks how it&apos;s going, and I tell him, flatly, &quot;Sucks.&quot; He nods, says, yeah, we&apos;re going to kill the interview loop early, but I want to talk to you over lunch (with another employee along for company) and then have you meet with one more person before we end the exercise.&lt;/p&gt;
&lt;p&gt;Lunch goes quite well, actually, and the last interview of the day is with their Product Manager, who then presents me with a challenge: &quot;Suppose I want to build an online system for ordering pizzas. Customers can order pizzas, in other words. Build for me either the UI or the data model for this system.&quot; OK, this is different. I choose the data model, and build a ridiculously simple one-to-many relationship of customers to orders, and a similar one-to-many for orders to pizzas. She then proceeds to complicate the model step by step, sometimes in response to my questions, sometimes out of the blue, until we have a fairly complex roughly-sketched data model on the whiteboard. Result: win.&lt;/p&gt;
&lt;p&gt;The VP at this point is on the horns of a dilemma: two of the engineers in the interview loop are convinced I&apos;m an idiot. They&apos;re clearly voting no on this. But he&apos;s read my articles, he&apos;s seen some of my presentations, he knows I&apos;m not the idiot the others assume me to be, and he&apos;s now trying to figure out what his next steps are. He takes a week to think about it, then emails me yesterday to say that it&apos;s not going to work.&lt;/p&gt;
&lt;p&gt;Here&apos;s my thoughts, and folks, if you interview people or are part of an interview process, I&apos;m trying to generalize this beyond this one experience to take it into a larger context:
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Know what you want to prove with your interview.&lt;/b&gt; I get the feeling that this interview loop was essentially a repeat of every interview loop they&apos;ve ever done before, with no consideration to the candidate himself. An interview is a chance for the company to get to know the candidate better, in order to make a well-informed decision. In this particular case, trying to suss out my skills around algorithms was a wasted effort--I&apos;d already conceded that point. Therefore, find new questions! Find new areas in which to challenge the candidate to see what their skills are. (If you can&apos;t think of something else to ask, then you&apos;re not really thinking about the interview all that hard, and you&apos;re just going through the motions.)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Look for the proof you seek in other areas.&lt;/b&gt; With the growth of things like Github and open source projects in general, it&apos;s becoming easier and easier to prove to yourself as a company that a candidate does or does not have the coding skills you&apos;re looking for. Did this guy submit some pull requests to a project? Did this guy post some blogs about interesting technical tidbits? (Or, Lord help us, write articles for major publications?) Did this guy author an open-source project, or work on a project that other people know about? Look at it this way: If Anders Heljsberg, Bjarne Stroustrup or James Gosling walk through the door, are you going to put them through the same interview questions you put the random recruiter-found candidate goes through? Or are you willing to consider their established body of work and call it covered? As an interviewer, it behooves you to look for that established body of work, so that you can spend the interview loop looking at other things.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Be clear in what you want.&lt;/b&gt; One of the things the VP said to me was that he was looking for somebody who had a similar skillset to what he had; that is, had a architectural view of things and an interest in managing the people involved. By then submitting my candidacy to a series of tests that didn&apos;t really test for those things, he essentially torpedoed whatever chances it might have had.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Be willing to assert your authority.&lt;/b&gt; If you&apos;re the VP of the company, and the people who work for you disagree with your decisions, sometimes the Right Thing To Do is to simply overrule them. Yes, I know, it&apos;s not all politically correct to do that, and if you do it too often you&apos;ll ruin whatever sense of empowerment that you want your employees to have within the company, but there are times when you just need to assert that authority and say, &quot;You know what? I appreciate y&apos;all&apos;s input, but this is one of those cases where I think I have a different enough perspective that I am going to just overrule and do it anyway.&quot; Sometimes you&apos;ll be right, yay, and sometimes you&apos;ll be wrong, boo, but there is a reason you&apos;re the VP or the Director or the Team Lead, and not the others. Leadership means making hard decisions sometimes.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Be willing to change up the process.&lt;/b&gt; So your candidate comes in, and they&apos;re a junior programmer who&apos;s just graduated college, with zero experience. Do you then start asking them questions about their experience? That would be a waste of their time and yours. So you&apos;ll have to come up with new questions and a new approach. Not all interviews have to be carbon copies of each other, because certainly your candidates aren&apos;t carbon copies of each other. (At least, you&apos;d better hope not, or else you&apos;re going to end up with a pretty single-dimensional staff.) If they&apos;ve proven their strength in some category, or admitted a lack in another, then drop your standard set of questions, and go to something different. There is no honor in asking the exact same questions of every candidate.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Be willing to hire somebody that offers complementary skills.&lt;/b&gt; If your company already has a couple of engineers who know algorithms really well, then hire somebody for a different skillset. Likewise, if your company already has a couple of people who are really good with customers, you don&apos;t need another one. Look for people that have skills that fall outside the realm of what you currently have, and trust that when that individual is presented with a problem that attacks their weakness, they&apos;ll turn to somebody else in the firm to help them with it. When presented with an algorithmic challenge, you&apos;re damn well sure that I&apos;m going to turn to somebody next to me and say, &quot;Hey, dude? Help me walk through this for a bit, would you?&quot; And, in turn, if that engineer has to give a presentation to a customer, and they turn to me and say, &quot;Hey, dude? Help me work on this presentation, would you?&quot;, I&apos;m absolutely ready to chip in. That&apos;s how teams are built. That&apos;s why we have teams in the first place.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the end, this is probably the best of all possible scenarios, not working for them, particularly since I have some other things brewing that will likely consume all of my attention in the coming months, but there&apos;s that part of me that hates the fact that I failed at this. That same part of me is now going back through a few of the &amp;quot;interview challenges&amp;quot; books that I picked up, ironically, for my eldest son when he goes out and does his programming interviews, just to work through a few of the problems because I HATE feeling inadequate to a challenge.&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;And that, in turn, raises my next challenge: I want to create a website, just a static thing, that has a series of questions that, I think, are far better coding challenges than the ones I was given. I don&apos;t know when or if I&apos;m going to get to this, but I gotta believe that any of the problems out of the book &quot;Programming Challenges&quot; (by Skiena and Revilla, Springer-Verlag, 2003) or the website from which those challenges were drawn, would be a much better test of the candidate&apos;s ability, particularly if you look at the ancillary parts of the challenge: do they write tests, how do they write their tests, do they pair well with somebody, and so on. THOSE are the things you really care about, not how well they remember their college lessons, which are easily accessible over Google or StackOverflow.&lt;/p&gt;
&lt;p&gt;Bottom line: Your time is precious, people. Interview well, or just don&apos;t bother.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Programming Tests</title>
      <link>http://blogs.newardassociates.com/blog/2013/programming-tests.html</link>
      <pubDate>Tue, 9 Jul 2013 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2013/programming-tests.html</guid>
      	<description>
	&lt;p&gt;It&apos;s official: I hate them.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Don&apos;t get me wrong, I understand their use and the reasons why potential employers give them out. There&apos;s enough programmers in the world who aren&apos;t really skilled enough for the job (whatever that job may be) that it becomes necessary to offer some kind of litmus test that a potential job-seeker must pass. I get that.&lt;/p&gt;
&lt;p&gt;And it&apos;s not like all the programming tests in the world are created equal: some are pretty useful ways to demonstrate basic programming facilities, a la the FizzBuzz problem. Or some of the projects I&apos;ve seen done, a la the &amp;quot;Robot on Mars&amp;quot; problem that ThoughtWorks handed out to candidates (a robot lands on Mars, which happens to be a cartesian grid; assuming that we hand the robot these instructions, such as LFFFRFFFRRFFF, where &amp;quot;L&amp;quot; is a &amp;quot;turn 90 degrees left&amp;quot;, &amp;quot;R&amp;quot; is a &amp;quot;turn 90 degrees right&amp;quot;, and &amp;quot;F&amp;quot; is &amp;quot;go forward one space, please write control code for the robot such that it ends up at the appropriate-and-correct destination, and include unit tests), are good indicators of how a candidate could/would handle a small project entirely on his/her own.&lt;/p&gt;
&lt;p&gt;But the ones where the challenge is to implement some algorithmic doodad or other? &lt;em&gt;shudder&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;For example, one I just took recently asks candidates to calculate the &amp;quot;disjoint sets&amp;quot; of a collection of sets; in other words, given sets of { 1, 2, 3 }, { 1, 2, 4 } and { 1, 2, 5 }, the result should be sets of {1,2},{3},{4}, and {5}. Do this and calculate the big-O notation for your solution in terms of time and of space/memory.&lt;/p&gt;
&lt;p&gt;I hate to say this, but in twenty years of programming, I&apos;ve never had to do this. Granted, I see the usefulness of it, and granted, it&apos;s something that, given large enough sets and large enough numbers of sets, will make a significant difference that it bears examination, but honestly, in times past when I&apos;ve been confronted with this problem, I&apos;m usually the first to ask somebody next to me how best to think about this, and start sounding out some ideas with them before writing any bit of code. Unit tests to test input and its expected responses are next. Then I start looking for the easy cases to verify before I start attacking the algorithm in its entirety, usually with liberal help from Google and StackOverflow.&lt;/p&gt;
&lt;p&gt;But in a programming test, you&apos;re doing this alone (which already takes away a significant part of my approach, because being an &amp;quot;external processor&amp;quot;, I think by talking out loud), and if it&apos;s timed (such as this one was), you&apos;re tempted to take a shortcut and forgo some of the setup (which I did) in order to maximize the time spent hacking, and when you end up down a wrong path (such as I did), you have nothing to fall back on.&lt;/p&gt;
&lt;p&gt;Granted, I screwed up, in that I should&apos;ve stuck to my process and simply said, &amp;quot;Here&apos;s how far I got in the hour&amp;quot;. But when you&apos;ve been writing code for twenty years, across three major platforms, for dozens of Fortune 500 companies and architected platforms that others will use to build software and services for thousands of users and customers, you feel like you should be able to hack something like this out fairly quickly.&lt;/p&gt;
&lt;p&gt;And when you can&apos;t, you feel like a failure.&lt;/p&gt;
&lt;p&gt;I hate programming tests.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; By the way, as always, I would love some suggestions on how to accomplish the disjoint-set problem. I kept thinking I was close, but was missing one key element. I particularly would LOVE a nudge in doing it in a object-functional language, like F# or Scala (I&apos;ve only attempted it in C# so far). Just a nudge, though--I want to work through it myself, so I learn.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Postscript&lt;/strong&gt; An analogy hit me shortly after posting this: it&apos;s almost as if, in order to test a master carpenter&apos;s skill at carpentry, you ask him to build a hammer. After all, if he&apos;s all that good, he should be able to do something as simple as affix a metal head to a wooden shaft and have the result be a superior device to anything he could buy off the shelf, right?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Further update:&lt;/strong&gt; After writing this, I took a break, had some dinner, played a game of Magic: The Gathering with my wife and kids (I won, but I can&apos;t be certain they didn&apos;t let me win, since they knew I was grumpy about not getting this test done in time), and then came back to it. I built up a series of little steps, backed by unit tests to make sure I was stepping through my attempts at reasoning out the algorithm correctly, backed up once or twice with a new approach, and finally solved it in about three hours, emailing it to the company at 6am (0600 for those of you reading this across the Atlantic or from a keyboard marked &amp;quot;Property of US Armed Forces&amp;quot;), just for grins. I wasn&apos;t expecting to get a response, since I was grossly beyond the time allotted, but apparently it was good enough to merit a follow-up interview, so yay for me. :-) Upshot is, though, I have an implementation that works, though now I find myself wondering if there&apos;s a way to do it in a functional/no-side-effect/persistent-data-structure kind of way....&lt;/p&gt;
&lt;p&gt;I still hate them, though, at least the algorithm-based ones, and in a fleeting moment of transparent honesty, I will admit it&apos;s probably because I&apos;m not very good at them, but if you repeat that to anyone I&apos;ll deny it as outrageous slander and demand satisfaction, Nerf guns at ten paces.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>More on Types</title>
      <link>http://blogs.newardassociates.com/blog/2013/more-on-types.html</link>
      <pubDate>Wed, 1 May 2013 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2013/more-on-types.html</guid>
      	<description>
	&lt;p&gt;With my most recent blog post, some of you were a little less than impressed with the idea of using types.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;One reader, in particular, suggested that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Your encapsulating type aliases don&apos;t... encapsulate :|&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Actually, it kinda does. But not in the way you described.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;using X = qualified.type;&lt;/code&gt; merely introduces an alias, and will consequently (a) not prevent assignment of a FirstName to a LastName (b) not even be detectible as such from CLI metadata (i.e. using reflection).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is true—-the &lt;code&gt;using&lt;/code&gt; statement only introduces an alias, in much the same way that C++’s “typedef” does. It’s not perfect, by any real means. Which is why the much &lt;em&gt;better&lt;/em&gt; approach would be to introduce an actual type for Name, rather than just an alias--the alias is just a starting point.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Also, the alias is lexically scoped, and doesn&apos;t actually &lt;em&gt;declare a public name&lt;/em&gt; (so, it would need to be redeclared in all &apos;client&apos; compilation units. (This won&apos;t be done, of course, because the clients would have no clue about this and happily be passing &lt;code&gt;System.String&lt;/code&gt; as ever). The same goes for C++ typedefs, or, indeed C++11 template aliases (&lt;code&gt;using FirstName = std::string;&lt;/code&gt; and &lt;code&gt;using LastName = std::string;&lt;/code&gt;). You&apos;d be better off using &lt;code&gt;BOOST_STRONG_TYPEDEF&lt;/code&gt; (or a roll-your-own version of this thing that is basically a CRTP pattern with some inherited constructors. When your compiler has the latter feature, you could probably do without an evil MACRO).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;All of which is also true. Frankly, the “using” statement is a temporary stopgap, simply a placeholder designed to say, “In time, this will be replaced with a full-fledged type.”&lt;/p&gt;
&lt;p&gt;And even more to the point, he fails to point out that my “Age” class from my example doesn’t really encapsulate the fact that Age is, fundamentally, an “int” under the covers—-because Age possesses type conversion operators to convert it into an int on demand (hence the “implicit” in that operator declaration), it’s pretty easy to get it back to straight “int”-land. Were I not so concerned with brevity, I’d have created a type that allowed for addition on it, though frankly I probably would forbid subtraction, and most certainly multiplication and division. (What does multiplying an Age mean, really?)&lt;/p&gt;
&lt;p&gt;See, in truth, I cheated, because I know that the first reaction most O-O developers will have is, “Are you crazy? That’s tons more work—-just use the int!” Which, is fair, wrong, and an old argument-—the C guys said the same thing about these “object” things, and how much work it was compared to just declaring a data structure and writing a few procedures to manipulate them. Creating a full-fledged type for each domain—-or each fraction of a domain—-seems... heavy.&lt;/p&gt;
&lt;p&gt;Truthfully, this is &lt;strong&gt;much&lt;/strong&gt; easier to do in F#. And in Scala. And in a number of different languages. Unfortunately, in C#, Java, and even C++ (and frankly, I don’t think the use of an “evil MACRO” is unwarranted, if it doesn’t promote bad things). The fact that “doing it right” in those languages means “doing a ton of work to get it right” is exactly why nobody does it—and suffers the commensurate loss of encapsulation and integrity in their domain model.&lt;/p&gt;
&lt;p&gt;Another poster pointed out that there is a &lt;em&gt;much&lt;/em&gt; better series on this at &lt;a href=&quot;http://www.fsharpforfunandprofit.com&quot;&gt;&lt;a href=&quot;http://www.fsharpforfunandprofit.com&quot;&gt;http://www.fsharpforfunandprofit.com&lt;/a&gt;&lt;/a&gt;. In particular, check out the series on &lt;a href=&quot;http://fsharpforfunandprofit.com/series/designing-with-types.html&quot;&gt;&amp;quot;Designing with Types&amp;quot;&lt;/a&gt;—-it expresses everything I wanted to say, albeit in F# (where I was trying, somewhat unsuccessfully, to example-code it in C#). By the way, I suspect that almost every linguistic feature he uses would translate pretty easily/smoothly over to Scala (or possibly Clojure) as well.&lt;/p&gt;
&lt;p&gt;Another poster pointed out that doing this type-driven design (TDD, anyone?) would create some serious havoc with your persistence. Cry me a river, and then go use a persistence model that fits an object-oriented and type-oriented paradigm. Like, I dunno, an &lt;a href=&quot;http://www.db4o.com&quot;&gt;object database&lt;/a&gt;. Particularly considering that you shouldn’t want to expose your database schema to anyone outside the project anyway, if you’re concerned about code being tightly coupled. (As in, any other code outside this project—like a reporting engine or an ETL process—that accesses your database directly now is tied to that schema, and is therefore a tight-coupling restriction on evolving your schema.)&lt;/p&gt;
&lt;p&gt;Achieving good encapsulation isn’t a matter of trying to hide the methods being used—it’s (partly) a matter of allowing the type system to carry a significant percentage of the cognitive load, so that you don’t have to. Which, when you think on it, is kinda what objects and strongly-typed type systems are supposed to do, isn’t it?&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>On Types</title>
      <link>http://blogs.newardassociates.com/blog/2013/on-types.html</link>
      <pubDate>Fri, 26 Apr 2013 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2013/on-types.html</guid>
      	<description>
	&lt;p&gt;Recently, having been teaching C# for a bit at Bellevue College, I’ve been thinking more and more about the way in which we approach building object-oriented programs, and particularly the debates around types and type systems. I think, not surprisingly, that the way in which the vast majority of the O-O developers in the world approach types and when/how they use them is flat wrong—both in terms of the times when they create classes when they shouldn’t (or shouldn’t have to, anyway, though obviously this is partly a measure of their language), and the times when they should create classes and don’t.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;The latter point is the one I feel like exploring here; the former one is certainly interesting on its own, but I’ll save that for a later date. For now, I want to think about (and write about) how we often don’t create types in an O-O program, and should, because doing so can often create clearer, more expressive programs.&lt;/p&gt;  &lt;h3&gt;A Person&lt;/h3&gt;  &lt;p&gt;Common object-oriented parlance suggests that when we have a taxonomical entity that we want to represent in code (i.e., a concept of some form), we use a class to do so; for example, if we want to model a &quot;person&quot; in the world by capturing some of their critical attributes, we do so using a class (in this case, C#):
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;class Person
{
	public string FirstName { get; set; }
	public string LastName { get; set; }
	public int Age { get; set; }
	public bool Gender { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Granted, this is a pretty simplified case; O-O enthusiasts will find lots of things wrong with this code, most of which have to do with dealing with the complexities that can arise.&lt;/p&gt;
&lt;p&gt;From here, there’s a lot of ways in which this conversation can get a lot more complicated—how, where and when should inheritance factor into the discussion, for example, and how exactly do we represent the relationship between parents and children (after all, some children will be adopted, some will be natural birth, some will be disowned) and the relationship between various members who wish to engage in some form of marital status (putting aside the political hot-button of same-sex marriage, we find that some states respect &amp;quot;civil unions&amp;quot; even where no formal ceremony has taken place, many cultures still recognize polygamy—one man, many wives—as Utah did up until the mid-1800s, and a growing movement around polyamory—one or more men, one or more women—looks like it may be the next political hot-button around marriage) definitely depends on the business issues in question...&lt;/p&gt;
&lt;p&gt;... but that’s the whole point of encapsulation, right? That if the business needs change, we can adapt as necessary to the changed requirements without having to go back and rewrite everything.&lt;/p&gt;
&lt;h4&gt;Genders&lt;/h4&gt;
&lt;p&gt;Consider, for example, the rather horrible decision to represent &amp;quot;gender&amp;quot; as a boolean: while, yes, at birth, there are essentially two genders at the biological level, there are some interesting birth defects/disorders/conditions in which a person’s gender is, for lack of a better term, screwed up—men born with female plumbing and vice versa. The system might need to track that. Or, there are those who consider themselves to have been born into the wrong gender, and choose to live a lifestyle that is markedly different from what societal norms suggest (the transgender crowd). Or, in some cases, the gender may not have even been determined yet: fetuses don’t develop gender until about halfway through the pregnancy.&lt;/p&gt;
&lt;p&gt;Which suggests, offhand, that the use of a boolean here is clearly a Bad Idea. But what suggests as its replacement? Certainly we could maintain an internal state string or something similar, using the get/set properties to verify that the strings being set are correct and valid, but the .NET type system has a better answer: Given that there is a finite number of choices to gender—whether that’s two or four or a dozen—it seems that an enumeration is a good replacement:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;enum Gender
{ Male, Female, Indeterminate, Transgender }

class Person
{
	public string FirstName { get; set; }
	public string LastName { get; set; }
	public int Age { get; set; }
	public Gender Gender { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Don’t let the fact that the property and the type have the same name be too confusing—-not only does it compile cleanly, but it actually provides some clear description of what’s being stored. (Although, I’ll admit, it’s confusing the first time you look at it.) More importantly, there’s no additional code that needs to be written to enforce only the four acceptable values—or, extend it as necessary when that becomes necessary.&lt;/p&gt;
&lt;h4&gt;Ages&lt;/h4&gt;
&lt;p&gt;Similarly, the age of a person is not an integer value—people cannot be negative age, nor do they usually age beyond a hundred or so. Again, we could put code around the get/set blocks of the Age property to ensure the proper values, but it would again be easier to let the type system do all the work:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;struct Age
{
	int data;
	public Age(int d) { Validate(d); data = d;
}

public static void Validate(int d)
{ 
	if (d &amp;lt; 0) throw new ArgumentException(&amp;quot;Age cannot be negative&amp;quot;);
	if (d &amp;gt; 120) throw new ArgumentException(&amp;quot;Age cannot be over 120&amp;quot;);
}

// explicit int to Age conversion operator
public static implicit operator Age(int a) { return new Age(a); }

// explicit Age to int conversion operator 
public static implicit operator int(Age a){ return a.data; }

class Person
{
	public string FirstName { get; set; }
	public string LastName { get; set; }
	public Age Age { get; set; }
	public Gender Gender { get; set; }
}

Notice that we’re still having to write the same code, but now the code is embodied in a type, which is itself intrinsically reusable—we can reuse the Age type in other classes, which is more than we can say if that code lives in the Person.Age property getter/setter. Again, too, now the Person class really has nothing to do in terms of ensuring that age is maintained properly (and by that, I mean greater than zero and less than 120). (The &amp;quot;implicit&amp;quot; in the conversion operators means that the code doesn’t need to explicitly cast the int to an Age or vice versa.)

Technically, what I’ve done with Age is create a restriction around the integer (System.Int32 in .NET terms) type; were this XSD Schema types, I could do a derivation-by-restriction to restrict an xsd:int to the values I care about (0 – 120, inclusive). Unfortunately, no O-O language I know of permits derivation-by-restriction, so it requires work to create a type that &amp;quot;wraps&amp;quot; another, in this case, an Int32.

#### Names
Names are another point of problem, in that there’s all kinds of crazy cases that (as much as we’d like to pretend otherwise) turn out to be far more common than we’d like—not only do most people have middle names, but sometimes women will take their husband’s last name and hyphenate it with their own, making it sort of a middle name but not really, or sometimes people will give their children to multiple middle names, Japanese names put family names first, sometimes people choose to take a single name, and so on. This is again a case where we can either choose to bake that logic into property getters/setters, or bake it into a single type (a &amp;quot;Name&amp;quot; type) that has the necessary code and properties to provide all the functionality that a person’s name represents.

So, without getting into the actual implementation, then, if we want to represent names in the system, then we should have a full-fledged &amp;quot;Name&amp;quot; class that captures the various permutations that arise:

```csharp
class Name
{
	public Title Honorific { get { ... } }
	public string Individual { get { ... } }
	public string Nickname { get { ... } }
	public string Family { get { ... } }
	public string Full { get { ... } }
	public static Name Parse(string incoming) { ... }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See, ultimately, everything will have to boil back to the core primitives within the language, but we need to build stronger primitives for the system—Name, Title, Age, and don’t even get me started on relationships.&lt;/p&gt;
&lt;h4&gt;Relationships&lt;/h4&gt;
&lt;p&gt;Parent-child relationships are also a case where things are vastly more complicated than just the one-to-many or one-to-one (or two-to-one) that direct object references encourage; in the case of families, given how complex the modern American family can get (and frankly, it’s not any easier if we go back and look at medieval families, either—go have a look at any royal European genealogical line and think about how you’d model that, particularly Henry VIII), it becomes pretty quickly apparent that modeling the relationships themselves often presents itself as the only reasonable solution.&lt;/p&gt;
&lt;p&gt;I won’t even begin to get into that example, by the way, simply because this blog post is too long as it is. I might try it for a later blog post to explore the idea further, but I think the point is made at this point.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;The object-oriented paradigm often finds itself wading in tens of thousands of types, so it seems counterintuitive to suggest that we need more of them to make programs more clear. I agree, many O-O programs are too type-heavy, but part of the problem there is that we’re spending too much time creating classes that we shouldn’t need to create (DTOs and the like) and not enough time thinking about the actual entities in the system.&lt;/p&gt;
&lt;p&gt;I’ll be the first to admit, too, that not all systems will need to treat names the way that I’ve done—sometimes an age is just an integer, and we’re OK with that. Truthfully, though, it seems more often than not that we’re later adding the necessary code to ensure that ages can never be negative, have to fall within a certain range, and so on.&lt;/p&gt;
&lt;p&gt;As a suggestion, then, I throw out this idea: &lt;strong&gt;&lt;em&gt;Ensure that all of your domain classes never expose primitive types to the user of the system.&lt;/em&gt;&lt;/strong&gt; In other words, &lt;code&gt;Person&lt;/code&gt; never exposes an &lt;code&gt;int&lt;/code&gt; for the idea of age, only an &lt;code&gt;Age&lt;/code&gt; type. C# makes this easy via &lt;code&gt;using&lt;/code&gt; declarations, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;using FirstName = System.String;
using LastName = System.String;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which can then, if you’re thorough and disciplined about using the FirstName and LastName types instead of &lt;code&gt;string&lt;/code&gt;, evolve into fully-formed types later in their own right if they need to. C++ provides &lt;code&gt;typedef&lt;/code&gt; for this purpose—unfortunately, Java lacks any such facility, making this a much harder prospect. (This is something I’d stick at the top of my TODO list were I nominated to take Brian Goetz’s place at the head of Java9 development.)&lt;/p&gt;
&lt;p&gt;In essence, encapsulate the primitive types away so that when they don’t need to be primitives, or when they need to be more complex than just simple holders of data, they don’t have to be, and clients will never know the difference. That, folks, is what encapsulation is trying to be about.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Say that part about HTML standards, again?</title>
      <link>http://blogs.newardassociates.com/blog/2013/say-that-part-about-html-standards-again.html</link>
      <pubDate>Sat, 13 Apr 2013 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2013/say-that-part-about-html-standards-again.html</guid>
      	<description>
	&lt;p&gt;In incarnations past, I have had debates, public and otherwise, with friends and colleagues who have asserted that HTML5 (by which we really mean HTML5/JavaScript/CSS3) will essentially become the platform of choice for all applications going forward—that essentially, &lt;em&gt;this&lt;/em&gt; time, standards will win out, and companies that try to subvert the open nature of the web by creating their own implementations with their own extensions and proprietary features that aren’t part of the standards, lose.
&lt;!--more--&gt;
&lt;p&gt;Then, I read the Wired news post about &lt;a href=&quot;http://www.wired.com/wiredenterprise/2013/04/blink/&quot; target=&quot;_blank&quot;&gt;Google’s departure from WebKit&lt;/a&gt;, and I’m a little surprised that the Internet (and by “the Internet”, I mean “the very people who get up in arms about standards and subverting them and blah blah blah”) hasn’t taken more issues with some of the things cited therein:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Google’s decision is in tune with its overall efforts to improve the infrastructure of the internet. When it comes to browser software and other web technologies that directly effect the how quickly and effectively your machine grabs and displays webpages, the company likes to use open source technologies. That way, it can feed their adoption outside the company — and ultimately improve the delivery of its many online services (including all important advertisements). But if it believes the rest of the web is moving too slowly, it has no problem starting up its own project.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Just to be clear, Google is happy to use open-source technologies, so it can feed adoption of those technologies, but if it’s something that Google thinks is being adopted too slowly—like, say, Google’s extensions to the various standards that aren’t being picked up by its competitors—then Google feels the need to kick off its own thing. Interesting.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;… [T]he trouble with WebKit is that is used different “multi-process architecture” than its Chrome browser, which basically means it didn’t handle concurrent tasks in the same way. When Chrome was first released in 2008 WebKit didn’t have a multi-process architecture, so Google had to build its own. WebKit2, released in 2010, adds multi-process features, but is quite different from what Google had already built. Apple and Google don’t see eye to eye on the project, and it became too difficult and too time-consuming for the company juggle the two architectures. “Supporting multiple architectures over the years has led to increasing complexity for both [projects],” the post says. “This has slowed down the collective pace of innovation.”&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So… Google tried to use some open-source software, but discovered that the project didn’t work the way they built the rest of their application to work. (I’m certain that’s the first time that has happened, ever.) When the custodians of the project did add the feature Google wanted, the feature was implemented in a manner that still wasn’t in lockstep with the way Google wanted things to work in their application. This meant that “innovation” is “slowed down”.&lt;/p&gt;
&lt;p&gt;(As an aside, I find it fascinating that whenever a company adopts open-source, it’s to “foster interoperability and open standards”, but when they abandon open-source, it’s to “foster innovation and faster evolution”. And I’m sure it’s entirely accidental that most of the time, adopting “open standards” is usually when the company is way behind on the technology curve for a given thing, and adopting “faster innovation” is usually when that same company thinks they’ve caught up the distance or surged ahead of their competitors in that space.)&lt;/p&gt;
&lt;p&gt;Of course, a new implementation has its risks of bugs and incompatibilities, but Google has a plan for that:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;“Throughout this transition, we’ll collaborate closely with other browser vendors to move the web forward and preserve the compatibility that made it a successful ecosystem,” the announcement reads.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Ah, there. See? By collaborating closely with their competitors, they will preserve compatibility. Because when Microsoft did that, everybody was totally OK with that…. uh, and… yeah… it worked pretty well, too, and….&lt;/p&gt;
&lt;p&gt;Look, it seems pretty reasonable to assume that even if the tags and the DOM and the APIs are all 100% unchanged from Chrome v.Past to v.Next, there’s still going to be places where they optimize differently than WebKit does, which means now that developers will need to learn (and implement) optimizations in their Web-based applications differently. And frankly, the assumption that Chrome’s Blink and WebKit will somehow be bug-for-bug compatible/identical with each other is a pretty steep bar to accept blindly, considering the history.&lt;/p&gt;
&lt;p&gt;Once again, we see the cycle coming around: in the beginning, when a technology is fleshing out, companies yearn for standards in order to create adoption. After a certain tipping point of adoption, however, the major players start to seek ways to avoid becoming a commodity, and start introducing “extensions” and “innovations” that for some odd reason their competitors in the standards meetings don’t seem all that inclined to adopt. That’s when they start forking and shying away from staying true to the standard, and eventually, the standard becomes either a least-common-denominator… or a joke.&lt;/p&gt;
&lt;p&gt;Anybody want to bet on which outcome emerges for HTML5?&lt;/p&gt;
&lt;p&gt;(Before you reach for the “Comment” link to flame me all to Hell, yes, even an HTML 5 standard that is 80% consistent across all the browsers is still pretty damn useful—just as a SQL standard that is 80% consistent across all the databases is useful. But this is a far cry from the utopia of interconnectedness and interoperability that was promised to us by the HTMLophiles, and it simply demonstrates that the Circle of TechnoLife continues, unabated, as it has ever since PC manufacturers—and the rest of us watching them--discovered what happens to them when they become a commodity.)&lt;/p&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Programming Language &apos;laws&apos;</title>
      <link>http://blogs.newardassociates.com/blog/2013/programming-language-laws.html</link>
      <pubDate>Tue, 19 Mar 2013 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2013/programming-language-laws.html</guid>
      	<description>
	&lt;p&gt;As is pretty typical for that site, Lambda the Ultimate has &lt;a href=&quot;http://lambda-the-ultimate.org/node/4698&quot;&gt;a great discussion&lt;/a&gt; on some insights that the creators of Mozart and Oz have come to, regarding the design of programming languages; I repeat the post here for convenience:&lt;/p&gt;
&lt;!--more--&gt;
&lt;blockquote&gt;
Now that we are close to releasing Mozart 2 (a complete redesign of the Mozart system), I have been thinking about how best to summarize the lessons we learned about programming paradigms in CTM. Here are five &quot;laws&quot; that summarize these lessons:
&lt;ol&gt;
&lt;li&gt;A well-designed program uses the right concepts, and the paradigm follows from the concepts that are used. [Paradigms are epiphenomena]&lt;/li&gt;
&lt;li&gt;A paradigm with more concepts than another is not better or worse, just different. [Paradigm paradox]&lt;/li&gt;
&lt;li&gt;Each problem has a best paradigm in which to program it; a paradigm with less concepts makes the program more complicated and a paradigm with more concepts makes reasoning more complicated. [Best paradigm principle]&lt;/li&gt;
&lt;li&gt;If a program is complicated for reasons unrelated to the problem being solved, then a new concept should be added to the paradigm. [Creative extension principle]&lt;/li&gt;
&lt;li&gt;A program&apos;s interface should depend only on its externally visible functionality, not on the paradigm used to implement it. [Model independence principle]&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here a &amp;quot;paradigm&amp;quot; is defined as a formal system that defines how computations are done and that leads to a set of techniques for programming and reasoning about programs. Some commonly used paradigms are called functional programming, object-oriented programming, and logic programming. The term &amp;quot;best paradigm&amp;quot; can have different meanings depending on the ultimate goal of the programming project; it usually refers to a paradigm that maximizes some combination of good properties such as clarity, provability, maintainability, efficiency, and extensibility. I am curious to see what the LtU community thinks of these laws and their formulation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This just so neatly calls out to me, based on my own very brief and very informal investigation into multi-paradigm programming (based on James Coplien&apos;s work from C++ from a decade-plus ago). I think they really have something interesting here.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>&quot;We Accept Pull Requests&quot;</title>
      <link>http://blogs.newardassociates.com/blog/2013/we-accept-pull-requests.html</link>
      <pubDate>Tue, 26 Feb 2013 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2013/we-accept-pull-requests.html</guid>
      	<description>
	&lt;p&gt;There are times when the industry in which I find myself does things that I just don&apos;t understand.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Consider, for a moment, &lt;a href=&quot;http://jeffhandley.com/archive/2013/02/25/The-We-accept-pull-requests-Addiction.aspx&quot;&gt;this blog&lt;/a&gt; by Jeff Handley, in which he essentially says that the phrase &amp;quot;We accept pull requests&amp;quot; is &amp;quot;cringe-inducing&amp;quot;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Why do the words “we accept pull requests” have such a stigma?  Why were they cringe-inducing when I spoke them?  Because too many OSS projects use these words as an easy way to shut people up.  We (the collective of OSS project owners) can too easily jump to this phrase when we don’t want to do something ourselves.  If we don’t see the value in a feature, but the requester persists, we can simply utter, “We accept pull requests,” and drop it until the end of days or when a pull request is submitted, whichever comes first.  The phrase now basically means, “Buzz off!”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;OK, I admit that I&apos;m somewhat removed from the OSS community--I don&apos;t have any particular dogs in that race, as the old saying goes--and the idea that &amp;quot;We accept pull requests&amp;quot; is a &amp;quot;Buzz off!&amp;quot; phrase is news to me. But I understand what Jeff is saying: a phrase has taken on a meaning of its own, and as is often the case, it&apos;s a meaning that&apos;s contrary to its stated one:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;At Microsoft, having open source projects that actually accept pull requests is a fairly new concept.  I work on NuGet, which is an Outercurve project that accepts contributions from Microsoft and many others.  I was the dev lead for Razor and Web Pages at the time it went open source through Microsoft Open Tech.  I collaborate with teams that work on EntityFramework, SignalR, MVC, and several other open source projects.  I spend virtually all my time thinking about projects that are open source.  Just a few years ago, this was unimaginable at Microsoft.  Sometimes I feel like it still hasn’t sunk in how awesome it is that we have gotten to where we are, and I think I’ve been trigger happy and I’ve said “We accept pull requests” too often  I typically use the phrase in jest, but I admit that I have said it when I was really thinking “Buzz off!”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Honestly, I&apos;ve heard the same kind of thing from the mouths of Microsoft developers during Software Development Reviews (SDRs), in the form of the phrase &amp;quot;Thank you for your feedback&amp;quot;--it&apos;s usually at the end of a fervent discussion when one of the reviewers is commenting on a feature being done (or not being done) and the team is in some kind of disagreement about the feature&apos;s relative importance or the implementation used. It&apos;s usually uttered in a manner that gives the crowd a very clear intent: &amp;quot;You can stop talking now, because I&apos;ve stopped listening.&amp;quot;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The weekend after the MVP summit, I was still regretting having said what I said.  I wished all week I could take the words back.  And then I saw someone else fall victim.  On a highly controversial NuGet issue, the infamous Phil Haack used a similar phrase as part of a response stating that the core team probably wouldn’t be taking action on the proposed changes, but that there was nothing stopping those affected from issuing a pull request.  With my mistake still fresh in my mind, I read Phil’s words just as I’m sure everyone in the room at the MVP summit heard my own.  It sounded flippant and it had the opposite effect from what Phil intended or what I would want people thinking of the NuGet core team.  From there, the thread started turning nasty.  We were stuck arguing opinions and we were no longer discussing the actual issue and how it could be solved.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As Jeff goes on to mention, I got involved in that Twitter conversation, along with a number of others, and as he says, the conversation moved on to JabbR, but without me--I bailed on it for a couple of reasons. Phil proposed a resolution to the problem, though, that seemed to satisfy at least a few folks:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;With that many mentions on the tweets, we ran out of characters and eventually moved into JabbR.  By the end of the conversation, we all agreed that the words “we accept pull requests” should never be used again.  Phil proposed a great phrase to use instead: “Want to take a crack at it? We’ll help.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But frankly, I don&apos;t care for this phraseology. Yes, I understand the intent--the owners of open-source projects shouldn&apos;t brush off people&apos;s suggestions about things to do with the project in the future and shouldn&apos;t reach for a handy phrase that will essentially serve the purpose of saying &amp;quot;Buzz off&amp;quot;. And keeping an open ear to your community is a good thing, yes.&lt;/p&gt;
&lt;p&gt;What I don&apos;t like about the new phrase is twofold. First, if people use the phrase casually enough, eventually it too will be overused and interpreted to mean &amp;quot;Buzz off!&amp;quot;, just as &amp;quot;Thank you for your feedback&amp;quot; became. But secondly, where in the world did it somehow become a law that open source projects MUST implement every feature that their users suggest? This is part of the strange economics of open source--in a commercial product, if the developers stray too far away from what customers need or want, declining sales will serve as a corrective force to bring them back around (or, if they don&apos;t, bankruptcy of either the product or the company will eventually follow). But in an open-source project, there&apos;s no real visible marker to serve as that accountability and feedback--and so the project owners, those who want to try and stay in tune with their users anyway, feel a deeper responsibility to respond to user requests. And on its own, that&apos;s a good thing.&lt;/p&gt;
&lt;p&gt;The part that bothers me, though, is that this new phraseology essentially implies that any open-source project has a responsibility to implement the features that its users ask for, and frankly, that&apos;s not sustainable. Open-source projects are, for the most part, maintained by volunteers, but even those that are backed by commercial firms (like Microsoft or GitHub) have finite resources--they simply cannot commit resources, even just &amp;quot;help&amp;quot;, to every feature request that any user makes of them. This is why the &amp;quot;We accept pull requests&amp;quot; was always, to my mind, an acceptable response: loosely translated, to me at least, it meant, &amp;quot;Look, that&apos;s an interesting idea, but it either isn&apos;t on our immediate roadmap, or it takes the project in a different direction than we&apos;d intended, or we&apos;re not even entirely sure that it&apos;s feasible or doable or easily managed or what-have-you. Why don&apos;t you take a stab at implementing it in your own fork of the code, and if you can get it to some point of implementation that you can show us, send us a copy of the code in the form of a pull request so we can take a look and see if it fits with how we see the project going.&amp;quot; This is not an unreasonable response: if you care passionately about this feature, either because you think it should be there or because your company needs that feature to get its work done, then you have the time, energy and motivation to at least take a first pass at it and prove the concept (or, sometimes, prove to yourself that it&apos;s not such an easy request as you thought). Cultivating a sense of entitlement in your users is not a good practice--it&apos;s a step towards a completely unsustainable model that could, if not curbed, eventually lead to the death of the project as the maintainers essentially give up when faced with feature request after feature request.&lt;/p&gt;
&lt;p&gt;I applaud the efforts on the part of project maintainers, particularly those at large commercial corporations involved in open source, to avoid &amp;quot;Buzz off&amp;quot; phrases. But it&apos;s not OK for project maintainers to feel like they are under a responsibility to implement any particular feature or idea suggested by a user. Some ideas are going to be good ones, some are going to be just &amp;quot;off the radar&amp;quot; of the project&apos;s core committers, and some are going to be just plain bad. You think your idea is one of those? Take a stab at it. Write the code. And if you&apos;ve got it to a point where it seems to be working, then submit a pull request.&lt;/p&gt;
&lt;p&gt;But please, let&apos;s not blow this out of proportion. Users need to cut the people who give them software for free some slack.&lt;/p&gt;
&lt;p&gt;(&lt;strong&gt;EDIT:&lt;/strong&gt; I accidentally referred to Jeff as &amp;quot;Anthony&amp;quot; in one place and &amp;quot;Andrew&amp;quot; in another. Not really sure how or why, but... Edited.)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>More on &apos;Craftsmanship&apos;</title>
      <link>http://blogs.newardassociates.com/blog/2013/more-on-craftsmanship.html</link>
      <pubDate>Fri, 25 Jan 2013 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2013/more-on-craftsmanship.html</guid>
      	<description>
	&lt;p&gt;&lt;strong&gt;tl;df&lt;/strong&gt;: To all those who dissented, you&apos;re right, but you&apos;re wrong. Craftsmanship is a noble meme, when it&apos;s something that somebody holds as a personal goal, but it&apos;s often coming across as a way to beat up and denigrate on others who don&apos;t choose to invest significant time and energy into programming. The Zen Masters didn&apos;t walk around the countryside, proclaiming &amp;quot;I am a Zen Master!&amp;quot;&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Wow. Apparently I touched a nerve.&lt;/p&gt;
&lt;p&gt;It&apos;s been 48 hours since I posted &lt;a href=&quot;http://blogs.tedneward.com/2013/01/24/On+The+Dark+Side+Of+Craftsmanship.aspx&quot;&gt;On the Dark Side of &apos;Craftsmanship&apos;&lt;/a&gt;, and it&apos;s gotten a ton of interest, as well as a few syndicated re-posts (DZone and a few others). Comments to the blog included a response from Dave Thomas, other blog posts have been brought to my attention, and Twitter was on FIRE with people pinging me with their thoughts, which turn out to be across the spectrum, approving and dissenting. Not at all what I really expected to happen, to be honest--I kinda thought it would get lost in the noise of others commenting around the whole thing.&lt;/p&gt;
&lt;p&gt;But for whatever reason, it&apos;s gotten a lot of attention, so I feel a certain responsibility to respond and explain to some of the dissenters who&apos;ve responded. Not to defend, per se, but to at least demonstrate some recognition and attempt to clarify my position where I think it&apos;s gotten mis-heard. (To those who approved of the message, thank you for your support, and I&apos;m happy to have vocalized something you felt unable, unwilling, unheard, or too busy to vocalize yourself. I hope my explanations here continue to represent your opinions, but if not, please feel free to let me know.)&lt;/p&gt;
&lt;p&gt;A lot of the opinions centered around a few core ideas, it seems, so let me try and respond to those first.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;You&apos;re confusing &quot;craftsmanship&quot; with a few people behaving badly.&lt;/b&gt; That may well be, but those who behaved badly included at least one who holds himself up as a leader of the craftsman movement and has held his actions up as indications of how &quot;craftsmen&quot; should behave. When you do this, you invite this kind of criticism and association. So if the movement is being given a black eye because of the actions of a single individual, well, now you know how a bunch of moderate Republicans feel about Paul Ryan.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Corey is a nice guy, he apologized, don&apos;t crucify him.&lt;/b&gt; Of course he is. Corey is a nice guy--and, speaking well to his character, he apologized almost immediately when it all broke. I learned a long time ago that &quot;true sorry&quot; means you (a) apologize for your actions, (b) seek to remedy the damage your actions have caused (&quot;make it right&quot;, in other words), and (c) avoid making the same mistake in the future. From a distance, it seems like he feels contrition, and has publicly apologized for his actions. I would hope he&apos;s reached out to Heather directly to try and make things right with her, but that&apos;s between the two of them. Whether he avoids this kind of activity in the future remains to be seen. I think he will, but that&apos;s because I think he&apos;s learned a harsh lesson about being in the spotlight--it tends to be a harsh place to be. The rest of this really isn&apos;t about Corey and Heather anymore, so as far as I&apos;m concerned, that thread complete.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;You misunderstand the nature of &quot;craftsmanship&quot;.&lt;/b&gt; Actually, no, I don&apos;t. At its heart, the original intent of &quot;craftsmanship&quot; was a constant striving to be better about what you do, and taking pride in the things that you do. It&apos;s related to the Japanese code of the samurai (kaizen) that says, in essence, that we are constantly striving to get better. The samurai sought to become better swordsmen, constantly challenging each other to prove the mettle against one another, improving their skills and, conditioning, but also their honor, by how they treated each other, their lord, their servants, and those they sought to protect. Kanban is a wonderful code, and one I have tried to live my entire life, even before I&apos;d discovered it. Please don&apos;t assume that I misunderstand the teachings of your movement just because I don&apos;t go to the meetings.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Why you pick on &quot;craftsmanship&quot;, anyway? If I want to take pride in what I do, what difference does it make?&lt;/b&gt; This is me paraphrasing on much of the dissent, and my response boils down to two basic thoughts:
&lt;ol&gt;
&lt;li&gt;If you think your movement is &quot;just about yourself&quot;, why invent a label to differentiate yourself from the rest?&lt;/li&gt;
&lt;li&gt;If you invent a label, it becomes almost automatic to draw a line between &quot;us&quot; and &quot;them&quot;, and that in of itself almost automatically leads to &quot;us vs them&quot; behavior and mentality.&lt;/li&gt;
&lt;/ol&gt;
Look, I view this whole thing as kind of like religion: whatever you want to do behind closed doors, that&apos;s your business. But when you start waving it in other peoples&apos; faces, then I have a problem with it. You want to spend time on the weekends improving your skills, go for it. You want to spend time at night learning a bunch of programming languages so you can improve your code and your ability to design systems, go for it. You want to study psychology and philosophy so you can understand other people better when it comes time to interact with them, go for it. And hey, you want to put some code up somewhere so people can point to it and help you get it better, go for it. But when you start waving all that time and dedication in my face, you&apos;re either doing it because you want recognition, or you want to suggest that I&apos;m somehow not as good as you. Live the virtuous life, don&apos;t brag about it.&lt;/p&gt;
&lt;p&gt;There were some specific blogs and comments that I think deserve discusson, too:&lt;/p&gt;
&lt;p&gt;Dave Thomas was kind enough to comment on my blog:
&lt;blockquote&gt;
I remember the farmer comment :)  I think I said 30%, but I stand by what I said. And it isn&apos;t really an elitist stance. Instead, I feel that programming is hard work. At the end of a day of coding, I&apos;m tired. And so I believe that if you are asking someone to do programming, then it is in both your and their interest that they are doing something they enjoy. Because if they don&apos;t enjoy it, then they are truly just a laborer, working hard at something that has no meaning to them. And as you spend 8 hours a day, 5 days a week doing it, that seems like an awful waste of an intelligent person&apos;s life.
&lt;/blockquote&gt;
Sure, programming is hard. So is house painting. They&apos;re different kinds of exhaustion, but it&apos;s exhaustion all the same. But, frankly, if somebody has chosen to take up a job that they do just because it&apos;s a job, that&apos;s their choice, and not ours to criticize, in my opinion. (And I remember it as 50%, because I very clearly remember saying the &quot;way to insult half the room&quot; crack after it, but maybe I misheard you. I do know others also heard it at 50%, because an attendee or two came up to talk about it after the panel. At least, that&apos;s how I remember it at the time. But the number itself is kinda meaningless, now that I think about it.)
&lt;blockquote&gt;
The farming quote was a deliberate attempt at being shocking to make a point. But I still think it is valid. I&apos;d guess that 30% of the developers I meet are not happy in their work. And I think those folks would be happier and more fulfilled doing something else that gave them more satisfaction.
&lt;/blockquote&gt;
Again, you and I are both in agreement, that people should be doing what they love, but that&apos;s a personal judgment that each person is permitted to make for themselves. There are aspects of our lives that we don&apos;t love, but we do because they make other people happy (Juliet and Charlotte driving the boys around to their various activities comes to mind, for example), and it is not our position to judge how others choose for themselves, IMHO.
&lt;blockquote&gt;
No one should have to be a laborer.
&lt;/blockquote&gt;
And here, you and I will disagree quite fundamentally: as I believe it was Martin Luther King, Jr, who said, &quot;If you are going to be a janitor, be the best janitor you know how to be.&quot; It seems by that statement that you are saying that people who labor with their bodies rather than your minds (and trust me, you may not be a laborer anymore, big publishing magnate that you are, but I know I sure still am) are somehow less well-off than those who have other people working for them. Some people don&apos;t want the responsibility of being the boss, or the owner. See the story of the mexican fisherman at the end of this blog.&lt;/p&gt;
&lt;p&gt;Nate commented:
&lt;blockquote&gt;
You have a logical fallacy by lumping together the people that derided Heather&apos;s code and people that are involved in software craftmanship. It&apos;s actually a huge leap of logic to make that connection, and it really retracts from the article.
&lt;/blockquote&gt;
As I point out later, the people who derided Heather&apos;s code were some of the same folks who hold up software craftsmanship. That wasn&apos;t me making that up.
&lt;/p&gt;
&lt;p&gt;
&lt;blockquote&gt;
Now you realise that you are planting your flag firmly in the &apos;craftmanship&apos; camp while propelling your position upwards by drawing a line in the sand to define another group of people as &apos;labourers&apos;. Or in other words attempt to elevate yourself by patronising others with the position you think you are paying them a compliment.
&lt;p&gt;Maybe you do not realise this?&lt;/p&gt;
&lt;/blockquote&gt;
No, I realize it, and it&apos;s a fair critique, which is why I don&apos;t label myself as a &quot;craftsman&quot;. I have more to say on this below.
&lt;blockquote&gt;
However, have you considered that the craft is not how awesome and perfect you and your code are, but what is applicable for the task at hand. I think most people who you would put into either camp share the same mix of attributes whether good or bad. The important thing is if the solution created does what it is designed to do, is delivered on time for when it is needed and if the environment that the solution has been created for warrants it, that the code is easily understandable by yourself and others (that matter) so it can be developed further over time and maintained. 
&lt;/blockquote&gt;
And the very people who call themselves &quot;craftsmen&quot; criticized a piece of code that, as near as I can tell, met all of those criteria. Hence my reaction that started this whole thing.
&lt;blockquote&gt;
I don&apos;t wish to judge you, and maybe you are a great, smart guy who does good in the world, but like you I have not researched anything about you, I have simply read your assessment above and come to a conclusion, that&apos;s being human I guess.
&lt;/blockquote&gt;
Oh, people judge each other all the time, and it&apos;s high time we stopped beating them up for it. It&apos;s human to judge. And while it would be politically correct to say, &quot;You shouldn&apos;t judge me before you know me&quot;, fact is, of course you&apos;re going to do exactly that, because you don&apos;t have time to get to know me. And the fact that you don&apos;t know me except but through the blog is totally acceptable--you shouldn&apos;t have to research me in order to have an opinion. So we&apos;re all square on that point. (As to whether I&apos;m a great smart guy who does good in the world, well, that&apos;s for others to judge in my opinion, not mine.)
&lt;blockquote&gt;
The above just sounds like more of the same &apos;elitism&apos; that has been ripe in this world from playground to the workplace since the beginning.
&lt;/blockquote&gt;
It does, doesn&apos;t it? And hopefully I clarify the position more clearly later.
&lt;/p&gt;
&lt;p&gt;In &lt;a href=&quot;http://rtigger.com/blog/2013/01/25/its-okay-to-love-your-job/&quot;&gt;It&apos;s OK to love your job&lt;/a&gt;, Chad McCallum says that
&lt;blockquote&gt;
The basic premise (or at least the one the author start out with) is that because there’s a self-declared group of “software craftspeople”, there is going to be an egotistical divide between those who “get it” and those who don’t.
&lt;/blockquote&gt;
Like it or not, Chad, that egotistical divide is there. You can &quot;call bullshit&quot; all day long, but look at the reactions that have popped up over this--people feel that divide, and frankly, it&apos;s one that&apos;s been there for a long, long time. This isn&apos;t just me making this up.&lt;/p&gt;
&lt;p&gt;Chad also says,
&lt;blockquote&gt;
&lt;p&gt;It’s true the feedback that Heather got was unnecessarily negative. And that it came from people who are probably considered “software craftspeople”. That said, correlation doesn’t equal causation. I’m guessing the negative feedback was more because those original offenders had a bad day and needed to vent. And maybe the comments after that one just jumped on the bandwagon because someone with lots of followers and/or respect said it.&lt;/p&gt;
&lt;p&gt;These are both things that can and have happened to anyone, regardless of the industry they work in. It’s extremely unfair to associate “someone who’s passionate about software development” to “person who’s waiting to jump on you for your mistakes”.&lt;/p&gt;
&lt;/blockquote&gt;
Unfortunately, Chad, the excuse that &quot;others do it, too&quot; is not an acceptable excuse. If everybody jumped off a cliff, would you do it, too? I understand the rationale--it&apos;s extremely hard being the one to go against the herd (I&apos;ve got the psychological studies I can cite at you that prove it), but that doesn&apos;t make it OK or excuse it. Saying &quot;it happens in other industries&quot; is just an extension of that. In other industries, women are still explicitly discriminated against--does that make it OK for us to do that, too?&lt;/p&gt;
&lt;p&gt;Chad closes his blog with &quot;Stop calling us egotistical jerks just because we love what we do.&quot; To which I respond, &quot;I am happy to do so, as soon as those &apos;craftsmen&apos; who are acting like one, stop acting like one.&quot; If you&apos;re not acting like one, then there should be no argument here. If you&apos;re trying to tell me that your label is somehow immune to criticism, then I think we just have to agree to disagree.&lt;/p&gt;
&lt;p&gt;Paul Pagel (on a site devoted to software craftsmanship, no less) responded as well with his &lt;a href=&quot;http://blog.8thlight.com/paul-pagel/2013/01/24/humble-pursuit-of-mastery.html&quot;&gt;Humble Pursuit of Mastery&lt;/a&gt;. He opens with:
&lt;blockquote&gt;
I have been reading on blogs and tweets the sentiment that &quot;software craftsmanship is elitism&quot;. This perception is formed around comments of code, process, or techniques. I understand a craftsman&apos;s earned sense of pride in their work can sometimes be inappropriately communicated.
&lt;/blockquote&gt;
I don&apos;t think I commented on code, process or technique, so I can&apos;t be sure if this is directly refuting what I&apos;m saying, but I note that Paul has already touched on the meme he wants to communicate in his last phrase: the craftsman&apos;s &quot;earned sense of pride&quot;. I have no problem with the work being something that you take pride in; I note, however, that &quot;pride goeth before a fall&quot;, and note that, again, Ozymandias was justifiably proud of his accomplishments, too.&lt;/p&gt;
&lt;p&gt;Paul then goes through a summation of his career, making sure to smallcaps certain terms with which I have no argument: &quot;sacrifice&quot;, &quot;listen&quot;, &quot;practicing&quot;, &quot;critique&quot; and &quot;teaching&quot;. And, in all honesty, these are things that I embrace, as well. But I start getting a little dubious about the sanctity of your terminology, Paul, when it&apos;s being used pretty blatantly as an advertising slogan and theme all over the site--if you want the term to remain a Zen-like pursuit, then you need to keep the commercialism out of it, in my opinion, or you invite the kind of criticism that&apos;s coming here (explicit or implicit).&lt;/p&gt;
&lt;p&gt;Paul&apos;s conclusion wraps up with:
&lt;blockquote&gt;
Do sacrificing, listening, practice, critiquing, and teaching sound like elitist qualities to you? Software craftsmanship starts out as a humble endeavor moving towards mastery. I won&apos;t let 140 or 1000 characters redefine the hours and years spent working hard to become a craftsman. It gave me humility and the confidence to be a professional software developer. Sometimes I let confidence get the better of me, but I know when that happens I am not honoring the spirit of craftsmanship which I was trained.
&lt;/blockquote&gt;
Humility enough to trademark your phrase &quot;Software is our craft&quot;? Humility enough to call yourself a &quot;driving force&quot; behind software craftsmanship? Don&apos;t get me wrong, Paul, there is a certain amount of commercialism that any consultant must adopt in order to survive--but either please don&apos;t mix your life-guiding principles with your commercialism, or else don&apos;t be surprised when others take aim at your &quot;humility&quot; when you do. It&apos;s the same when ministers stand in a multi-million dollar building on a Sunday morning and talk about the parable of the widow giving away her last two coppers--that smacks of hypocrisy.&lt;/p&gt;
&lt;p&gt;Finally, Matt van Horn wrote in &lt;a href=&quot;http://www.mattvanhorn.com/2013/01/24/craftsmanship-a-rebuttal/&quot;&gt;Crafsmanship, a rebuttal&lt;/a&gt; that:
&lt;blockquote&gt;
there is an allusion to software craftsmen as being an exclusive group who agre on the “right” tools and techniques. This could not be further from the truth. Anyone who is serious about their craft knows that for every job there are some tools that are better and some that are worse.
&lt;/blockquote&gt; 
... but then he goes right into making that exact mistake:
&lt;blockquote&gt;
Now, I may not have a good definition of elegant code, but I definitely know it when I see it – regardless of who wrote it. If you can’t see that &lt;br/&gt;
&lt;pre&gt;
(1..10).each{|i| puts i}
&lt;/pre&gt;
&lt;br/&gt;
is more elegant than
&lt;br/&gt;
&lt;pre&gt;
x = 0
while true do
  x = x + 1
  if x &gt; 10
    break
  end
  puts x
end
&lt;/pre&gt;
then you must near the beginning of your journey towards mastery. Practicing your craft develops your ability to recognize these differences, just as a skilled tailor can more easily spot the difference between a bespoke suit and something from Men’s Wearhouse.
&lt;/blockquote&gt;
Matt, you kind of make my point for me. What makes it elegant? You take it as self-evident. I don&apos;t. As a matter of fact, I&apos;ve been asking this question for some years now, &quot;What makes code &apos;elegant&apos;, as opposed to &apos;ugly&apos;? Ironically, Elliott Rusty Harold just blogged about how this style of coding is dangerous in Java, and got crucified for it, but he has the point that functional style (your first example) doesn&apos;t JIT as well as the more imperative style right now on the JVM (or on the CLR, from what I can tell). Are you assuming that this will be running on a native Ruby implementation, on JRuby, IronRuby, ...? You have judged the code in the second example based on an intrinsic value system that you may have never questioned. To judge, you have to be able to explain your judgments in terms of the value system. And the fact that you judge without any context, kind of speaks directly to the point I was trying to make: &quot;craftsmen&quot;, it seems, have this tendency to judge in absence of context, because they are clearly &quot;further down their journey towards mastery&quot;, to use your own metaphor.&lt;/p&gt;
&lt;p&gt;Or, to put it much more succinctly, &quot;Beauty is in the eye of the beholder&quot;.&lt;/p&gt;
&lt;p&gt;Matt then tells me I missed the point of the samurai and tea master story:
&lt;blockquote&gt;
inally, he closes with a famous zen story, but he entirely misses the point of it. The story concerns a tea master, and a samurai, who get into a duel. The tea master prevails by bringing the same concentration to the duel that he brings to his tea ceremony. The point that Ted seems to miss here is that the tea master is a craftsman of the highest order. A master of cha-do (the way of tea) is able to transform the simple act of making and pouring a cup of tea into something transcendant by bringing to this simple act a clear mind, a good attitude, and years of patient, humble practice. Arguably he prevails because he has perfected his craft to a higher degree than the samurai has perfected his own. That is why he has earned the right to wear the garb of a samurai, and why he is able to face down his opponent.
&lt;/blockquote&gt;
Which, again, I find funny, because most Zen masters will tell you that the story--any Zen story, in fact--has no &quot;definitive&quot; meaning, but has meaning based on how you interpret it. (There are a few Zen parables that reinforce this point, but it gets a little meta to justify my understanding of a Zen story by quoting another Zen story.) How Matt chooses to interpret that parable is, of course, up to him. I choose to interpret the story thusly: the insulted samurai felt that his &quot;earned sense of pride&quot; at his sword mastery was insulted by the tea master--clearly no swordsman, as it says in the story--wore robes of a rank and honor that he had not earned. And clearly, the tea master was no swordsman. But what the tea master learned from his peer was not how to use his concentration and discipline to improve his own swordsmanship, but how to demonstrate that he had, in fact, earned a note of mastery through an entirely different discipline than the insulted samurai&apos;s. The tea master still has no mastery of the sword, but in his own domain, he is an expert. This was all the insulted samurai needed to see, that the badge of honor had been earned, and not just imposed by a capricious (and disrespectful) lord. Put a paintbrush and canvas into the hands of a house painter, and you get pretty much a mess--but put a spray painter in the hands of Leonardo, and you still get a mess. In fact, to really do the parable justice, we should see how much &quot;craft&quot; Matt can bring when asked to paint a house, because that&apos;s about how much relevance swordsmanship and house painting have in relationship to one another. (All analogies fail eventually, by the way, and we&apos;re probably reaching the boundaries of this one.)&lt;/p&gt;
&lt;p&gt;Billy Hollis is a master with VB, far more than I ever will be; I know C++ far better than he ever will. I respect his abilities, and he, mine. There is no argument here. But more importantly, there are friends I&apos;ve worked with in the past who are masters with neither VB nor C++, nor any other programming language, but chose instead to sink their time and energy into skiing, pottery, or being a fan of a television show. They chose to put their energies--energies the &quot;craftsmen&quot; seem to say should be put towards their programming--towards things that bring them joy, which happen to not be programming.&lt;/p&gt;
&lt;p&gt;Which brings me to another refrain that came up over and over again: &lt;b&gt;You criticize the craftsman, but then you draw a distinction between &quot;craftsman&quot; and &quot;laborer&quot;. You&apos;re confusing (or confused).&lt;/b&gt; First of all, I think it important to disambiguate along two axes: those who are choosing to invest their time into learning to write better software, and those who are choosing to look at writing code as &quot;just&quot; a job as one axis, and along a second axis, the degree to which they have mastered programming. By your own definitions, &quot;craftsmen&quot;, can one be early in your mastery of programming and still be a &quot;craftsman&quot;? Can one be a master bowler who&apos;s just picked up programming and be considered a &quot;craftsman&quot;? Is the nature of &quot;craftsmanship&quot; a measure of your skill, or is it your dedication to programming, or is it your dedication to something in your life, period? (Remember, the tea master parable says that a master C++ developer will see the master bowler and respect his mastery of bowling, even though he can&apos;t code worth a crap. Would you call him a &quot;craftsman&quot;?)&lt;p&gt;
&lt;p&gt;Frankly, I will say, for the record, that I think there are people programming who don&apos;t want to put a ton of time and energy into learning how to be better programmers. (I suspect that most of them won&apos;t ever read this blog, either.) They see the job as &quot;just a job&quot;, and are willing to be taught how to do things, but aren&apos;t willing to go off and learn how to do them on their own. They want to do the best job they can, because they, like any human being, want to bring value to the world, but don&apos;t have that passion for programming. They want to come in at 9, do their job, and go home at 5. These are those whom I call &quot;laborers&quot;. They are the &quot;fisherman&quot; in &lt;a href=&quot;http://www.lifeprinciples.net/SuccessatLife.html&quot;&gt;the following story&lt;/a&gt;:
&lt;blockquote&gt;
&lt;p&gt;The businessman was at the pier of a small coastal Mexican village when a small boat with just one fisherman docked. Inside the small boat were several large yellowfin tuna. The businessman complimented the Mexican on the quality of his fish and asked how long it took to catch them. The Mexican replied only a little while.&lt;/p&gt;
&lt;p&gt;The businessman then asked why he didn&apos;t stay out longer and catch more fish? The Mexican said he had enough to support his family&apos;s immediate needs. The businessman then asked, but what do you do with the rest of your time? The Mexican fisherman said, &quot;I sleep late, fish a little, play with my children, take a siesta with my wife, Maria, stroll into the village each evening where I sip wine and play guitar with my amigos; I have a full and busy life, señor.&quot;&lt;/p&gt;
&lt;p&gt;The businessman scoffed, &quot;I am a Harvard MBA and I could help you. You should spend more time fishing and with the proceeds buy a bigger boat. With the proceeds from the bigger boat you could buy several boats; eventually you would have a fleet of fishing boats. Instead of selling your catch to a middleman, you would sell directly to the processor and eventually open your own cannery. You would control the product, processing and distribution. You would need to leave this small coastal fishing village and move to Mexico City, then LA and eventually New York City where you would run your expanding enterprise.&quot;&lt;/p&gt;
&lt;p&gt;The Mexican fisherman asked, &quot;But señor, how long will this all take?&quot; To which the businessman replied, &quot;15-20 years.&quot; &quot;But what then, señor?&quot; The businessman laughed and said, &quot;That&apos;s the best part! When the time is right you would announce an IPO and sell your company stock to the public and become very rich. You would make millions.&quot; &quot;Millions, señor? Then what?&quot; The businessman said, &quot;Then you would retire. Move to a small coastal fishing village where you would sleep late, fish a little, play with your kids, take a siesta with your wife, stroll to the village in the evenings where you could sip wine and play your guitar with your amigos.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/p&gt;
&lt;p&gt;What makes all of this (this particular subject, craftsmanship) particularly hard for me is that I &lt;i&gt;like&lt;/i&gt; the message that craftsmanship brings, in terms of how you conduct yourself. I &lt;i&gt;love&lt;/i&gt; the book &lt;a href=&quot;http://www.amazon.com/Apprenticeship-Patterns-Guidance-Aspiring-Craftsman/dp/0596518382&quot;&gt;Apprenticeship Patterns&lt;/a&gt;, for example, and think that anyone, novice or master, should read this book. I have taken on speaking apprentices in the past, and will continue to do so well into the future. The message that underlies the meme of craftsmanship--the constant striving to improve--is a good one, and I don&apos;t want to throw the baby out with the bathwater. If you have adopted &quot;craftsmanship&quot; as a core value of yours, then please, by all means, continue to practice it! Myself, I choose to do so, as well. I have mentored programmers, I have taken speaking apprentices, and I strive to learn more about my craft by branching my studies out well beyond software--I am reading books on management, psychology, building architecture, and business, because I think there is more to software than just the choice of programming language or style.&lt;/p&gt;
&lt;p&gt;But be aware that if you start telling people how you&apos;re living your life, there is an implicit criticism or expectation that they should be doing that, as well. And when you start criticizing other peoples&apos; code as being &quot;unelegant&quot; or &quot;unbeautiful&quot; or &quot;unclean&quot;, you&apos;d better be able to explain your value system and why you judged it as so. Humility is a hard, hard path to tread, and one that I have only recently started to see the outlines of; I am guilty of just about every sin imaginable when it comes to this subject. I have created &quot;elegant&quot; systems that failed their original intent. I have criticized &quot;ugly&quot; code that, in fact, served the purpose well. I have bragged of my own accomplishments to those who accomplished a lot more than I did, or ever will. And I consider it amazing to me that my friends who&apos;ve been with me since long before I started to eat my justly-deserved humble pie are still with me. (And that those friends are some amazing people in their own right.; if a man is judged by the company he keeps, then by looking around at my friends, I am judged to be a king.) I will continue to strive to be better than I am now, though, even within this discussion right now: those of you who took criticism with my post, you have good points, all of you, and I certainly don&apos;t want to stop you from continuing on your journeys of self-discovery, either.&lt;/p&gt;
&lt;p&gt;And if we ever cross paths in person, I will buy you a beer so that we can sit down, and we can continue this discussion in person.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>On the Dark Side of &apos;Craftsmanship&apos;</title>
      <link>http://blogs.newardassociates.com/blog/2013/on-the-dark-side-of-craftsmanship.html</link>
      <pubDate>Wed, 23 Jan 2013 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2013/on-the-dark-side-of-craftsmanship.html</guid>
      	<description>
	&lt;p&gt;I don&apos;t know Heather Arthur from Eve. Never met her, never read an article by her, seen a video she&apos;s in or shot, or seen her code. Matter of fact, I don&apos;t even know that she is a &amp;quot;she&amp;quot;--I&apos;m just guessing from the name. But I&apos;m coming out, right now, to say that the way she&apos;s being treated is absolutely beyond the pale, and she deserves better.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Apparently she got &lt;a href=&quot;http://harthur.wordpress.com/2013/01/24/771/&quot;&gt;quite an ugly reaction&lt;/a&gt; from a few folks when she open-sourced some code:&lt;/p&gt;
&lt;blockquote&gt;
So I went to see what people were saying about this project. I searched Twitter and several tweets came up. One of them, I guess the original one, was basically like “hey, this is cool”, but then the rest went like this:
&lt;br /&gt;
&quot;I cannot even make this stuff up.&quot; --@steveklabnik
&lt;br /&gt;
&quot;Ever wanted to make sed or grep worse?&quot; --@zeeg
&lt;br /&gt;
&quot;@steveklabnik or just point to the actual code file. eyes bleeding!&quot; --@coreyhaines
&lt;br /&gt;
At this point, all I know is that by creating this project I’ve done something very wrong. It seemed liked I’d done something fundamentally wrong, so stupid that it flabbergasts someone. So wrong that it doesn’t even need to be explained.  And my code is so bad it makes people’s eyes bleed. So of course I start sobbing.
&lt;/blockquote&gt;
&lt;p&gt;Now, to be fair, &lt;a href=&quot;http://programmingtour.blogspot.com/2013/01/im-sorry.html&quot;&gt;Corey later apologized&lt;/a&gt;. But I&apos;m still going to criticize the response. Not because Heather&apos;s a &amp;quot;she&amp;quot; and we should be more supportive of women in IT. Not because somebody took something they found interesting and put it up on github for anyone to take a look at and use if they found it useful. Not even because it&apos;s good code when they said it was bad code or vice versa. (To be honest, I haven&apos;t even looked at the code--that&apos;s how immaterial it is to my point.)&lt;/p&gt;
&lt;p&gt;I&apos;m criticizing because this is what &amp;quot;software craftsmanship&amp;quot; gets us: an imposed segregation of those who &amp;quot;get it&amp;quot; from those who &amp;quot;don&apos;t&amp;quot; based on somebody&apos;s arbitrary criteria of what we should or shouldn&apos;t be doing. And if somebody doesn&apos;t use the &amp;quot;right&amp;quot; tools or code it in the &amp;quot;right&amp;quot; way, then bam! You clearly aren&apos;t a &amp;quot;craftsman&amp;quot; (or &amp;quot;craftswoman&amp;quot;?) and you clearly don&apos;t care about your craft and you clearly aren&apos;t worth the time or energy necessary to support and nourish and grow and....&lt;/p&gt;
&lt;p&gt;Frankly, I&apos;ve not been a fan of this movement since its inception. Dave Thomas (Ruby Dave) was on a software panel with me at a No Fluff Just Stuff show about five years ago when we got on to this subject, and Dave said, point blank, &amp;quot;About half of the programmers in the world should just go take up farming.&amp;quot; He paused, and in the moment that followed, I said, &amp;quot;Wow, Dave, way to insult half the room.&amp;quot; He immediately pointed out that the people in the room were part of the first half, since they were at a conference, but it just sort of underscored to me how high-handed and high-minded that kind of talk and position can be.&lt;/p&gt;
&lt;p&gt;Not all of us writing code have to be artists. Frankly, in the world of painting, there are those who will spend hours and days and months, tiny brushes in hand, jars of pigment just one lumens different from one another, laboring over the finest details, creating just one piece... and then there are those who paint houses with paint-sprayers, out of cans of mass-produced &amp;quot;Cream Beige&amp;quot; found at your local Lowes. And you know what? &lt;i&gt;We need both of them.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;I will now coin a term that I consider to be the opposite of &amp;quot;software craftsman&amp;quot;: the &amp;quot;software laborer&amp;quot;. In my younger days, believing myself to be one of those &amp;quot;craftsmen&amp;quot;, a developer who knew C++ in and out, who understood memory management and pointers, who could create elegant and useful solutions in templates and classes and inheritance, I turned up my nose at those &amp;quot;laborers&amp;quot; who cranked out one crappy app after another in (what else?) Visual Basic. My app was tight, lean, and well-tuned; their apps were sloppy, bloated, and ugly. My app was a paragon of reused code; their apps were cut-and-paste cobbled-together duct-tape wonders. My app was a shining beacon on a hill for all the world to admire; their apps were mindless drones, slogging through the mud.... Yeah, OK, so you get the idea.&lt;/p&gt;
&lt;p&gt;But the funny thing was, those &amp;quot;laborers&amp;quot; were going home at 5 every day. Me, I was staying sometimes until 9pm, wallowing in the wonderment of my code. And, I have to wonder, how much of that was actually not the wonderment of my code, but the wonderment of &amp;quot;me&amp;quot; over the wonderment of &amp;quot;code&amp;quot;.&lt;/p&gt;
&lt;p&gt;Speaking of, by the way, there appear to be the makings of another such false segregation, in the areas of &amp;quot;functional programming&amp;quot;. In defense of Elliott Rusty Harold&apos;s blog the other day (which I criticized, and still stand behind, for the reasons I cited there), there are a lot of programmers that are falling into the trap of thinking that &amp;quot;all the cool kids are using functional programming, so if I want to be a cool kid, I have to use functional programming too, even though I&apos;m not sure what I&apos;m doing....&amp;quot;. Not all the cool kids are using FP. Some aren&apos;t even using OOP. Some are just happily humming along using good ol&apos; fashioned C. And producing some really quality stuff doing so.&lt;/p&gt;
&lt;p&gt;See, I have to wonder just how much of the software &amp;quot;craftsmanship&amp;quot; being touted isn&apos;t really a narcissistic &amp;quot;Look at me, world! Look at how much better I am because I care about what I do! Look upon my works, ye mighty, and despair!&amp;quot; kind of mentality. Too much of software &amp;quot;craftsmanship&amp;quot; seems to be about the &amp;quot;me&amp;quot; part of &amp;quot;my code&amp;quot;. And when I think about why that is, I come to an interesting assertion: That if we take the name away from the code, and just look at the code, we can&apos;t really tell what&apos;s &amp;quot;elegant&amp;quot; code, what&apos;s &amp;quot;hack&amp;quot; code, and what was &amp;quot;elegant hack because there were all these other surrounding constraints outside the code&amp;quot;. Without the context, we can&apos;t tell.&lt;/p&gt;
&lt;p&gt;A few years after my high point as a C++ &amp;quot;craftsman&amp;quot;, I was asked to do a short, one-week programming gig/assignment, and the more I looked at it, the more it screamed &amp;quot;VB&amp;quot; at me. And I discovered that what would&apos;ve taken me probably a month to do in C++ was easily accomplished in a few days in VB. I remember looking at the code, and feeling this sickening, sinking sense of despair at how stupid I must&apos;ve looked, crowing. VB isn&apos;t a bad language--and neither is C++. Or Java. Or C#. Or Groovy, or Scala, or Python, or, heck, just about any language you choose to name. (Except Perl. I refuse to cave on that point. Mostly for comedic effect.)&lt;/p&gt;
&lt;p&gt;But more importantly, somebody who comes in at 9, does what they&apos;re told, leaves at 5, and &lt;em&gt;never gives a rat&apos;s ass about programming except for what they need to know to get their job done&lt;/em&gt;, I have respect for them. Yes, some people will want to hold themselves up as &amp;quot;painters&amp;quot;, and others will just show up at your house at 8 in the morning with drop cloths. Both have their place in the world. Neither should be denigrated for their choices about how they live their lives or manage their careers. (Yes, there&apos;s a question of professional ethics--I want the house painters to make sure they do a good job, too, but quality can come just as easily from the nozzle of a spray painter as it does from the tip of a paintbrush.)&lt;/p&gt;
&lt;p&gt;I end this with one of my favorite parables from Japanese lore:&lt;/p&gt;
&lt;blockquote&gt;
Several centuries ago, a tea master worked in the service of Lord Yamanouchi. No-one else performed the way of the tea to such perfection. The timing and the grace of his every move, from the unfurling of mat, to the setting out of the cups, and the sifting of the green leaves, was beauty itself. His master was so pleased with his servant, that he bestowed upon him the rank and robes of a Samurai warrior.
&lt;p&gt;When Lord Yamanouchi travelled, he always took his tea master with him, so that others could appreciate the perfection of his art. On one occasion, he went on business to the great city of Edo, which we now know as Tokyo.&lt;/p&gt;
&lt;p&gt;When evening fell, the tea master and his friends set out to explore the pleasure district, known as the floating world. As they turned the corner of a wooden pavement, they found themselves face to face with two Samurai warriors.&lt;/p&gt;
&lt;p&gt;The tea master bowed, and politely step into the gutter to let the fearsome ones pass. But although one warrior went by, the other remained rooted to the spot. He stroked a long black whisker that decorated his face, gnarled by the sun, and scarred by the sword. His eyes pierced through the tea maker’s heart like an arrow.&lt;/p&gt;
&lt;p&gt;He did not quite know what to make of the fellow who dressed like a fellow Samurai, yet who would willingly step aside into a gutter. What kind of warrior was this? He looked him up and down. Where were broad shoulders and the thick neck of a man of force and muscle? Instinct told him that this was no soldier. He was an impostor who by ignorance or impudence had donned the uniform of a Samurai. He snarled: “Tell me, oh strange one, where are you from and what is your rank?”&lt;/p&gt;
&lt;p&gt;The tea master bowed once more. “It is my honour to serve Lord Yamanouchi and I am his master of the way of the tea.”&lt;/p&gt;
&lt;p&gt;“A tea-sprout who dares to wear the robes of Samurai?” exclaimed the rough warrior.&lt;/p&gt;
&lt;p&gt;The tea master’s lip trembled. He pressed his hands together and said: “My lord has honoured me with the rank of a Samurai and he requires me to wear these robes. “&lt;/p&gt;
&lt;p&gt;The warrior stamped the ground like a raging a bull and exclaimed: “He who wears the robes of a Samurai must fight like a Samurai. I challenge you to a duel. If you die with dignity, you will bring honour to your ancestors. And if you die like a dog, at least you will be no longer insult the rank of the Samurai!”&lt;/p&gt;
&lt;p&gt;By now, the hairs on the tea master’s neck were standing on end like the feet of a helpless centipede that has been turned upside down. He imagined he could feel that edge of the Samurai blade against his skin. He thought that his last second on earth had come.&lt;/p&gt;
&lt;p&gt;But the corner of the street was no place for a duel with honour. Death is a serious matter, and everything has to be arranged just so. The Samurai’s friend spoke to the tea master’s friends, and gave them the time and the place for the mortal contest.&lt;/p&gt;
&lt;p&gt;When the fierce warriors had departed, the tea master’s friends fanned his face and treated his faint nerves with smelling salts. They steadied him as they took him into a nearby place of rest and refreshment. There they assured him that there was no need to fear for his life. Each one of them would give freely of money from his own purse, and they would collect a handsome enough sum to buy the warrior off and make him forget his desire to fight a duel. And if by chance the warrior was not satisfied with the bribe, then surely Lord Yamanouchi would give generously to save his much prized master of the way of the tea.&lt;/p&gt;
&lt;p&gt;But these generous words brought no cheer to the tea master. He thought of his family, and his ancestors, and of Lord Yamanouchi himself, and he knew that he must not bring them any reason to be ashamed of him.&lt;/p&gt;
&lt;p&gt;“No,” he said with a firmness that surprised his friends. “I have one day and one night to learn how to die with honour, and I will do so.”&lt;/p&gt;
&lt;p&gt;And so speaking, he got up and returned alone to the court of Lord Yamanouchi. There he found his equal in rank, the master of fencing, he was skilled as no other in the art of fighting with a sword.&lt;/p&gt;
&lt;p&gt;“Master,” he said, when he had explained his tale, “Teach me to die like a Samurai.”&lt;/p&gt;
&lt;p&gt;But the master of fencing was a wise man, and he had a great respect for the master of the Tea ceremony. And so he said: “I will teach you all you require, but first, I ask that you perform the way of the Tea for me one last time.”&lt;/p&gt;
&lt;p&gt;The tea master could not refuse this request. As he performed the ceremony, all trace of fear seemed to leave his face. He was serenely concentrated on the simple but beautiful cups and pots, and the delicate aroma of the leaves. There was no room in his mind for anxiety. His thoughts were focused on the ritual.&lt;/p&gt;
&lt;p&gt;When the ceremony was complete, the fencing master slapped his thigh and exclaimed with pleasure : “There you have it. No need to learn anything of the way of death. Your state of mind when you perform the tea ceremony is all that is required. When you see your challenger tomorrow, imagine that you are about to serve tea for him. Salute him courteously, express regret that you could not meet him sooner, take off your coat and fold it as you did just now. Wrap your head in a silken scarf and and do it with the same serenity as you dress for the tea ritual. Draw your sword, and hold it high above your head. Then close your eyes and ready yourself for combat. “&lt;/p&gt;
&lt;p&gt;And that is exactly what the tea master did when, the following morning, at the crack of dawn he met his opponent. The Samurai warrior had been expecting a quivering wreck and he was amazed by the tea master’s presence of mind as he prepared himself for combat. The Samurai’s eyes were opened and he saw a different man altogether. He thought he must have fallen victim to some kind of trick or deception ,and now it was he who feared for his life. The warrior bowed, asked to be excused for his rude behaviour, and left the place of combat with as much speed and dignity as he could muster.&lt;/p&gt;
&lt;/blockquote&gt;
(excerpted from &lt;a href=&quot;http://storynory.com/2011/03/27/the-samurai-and-the-tea-master/&quot;&gt;http://storynory.com/2011/03/27/the-samurai-and-the-tea-master/&lt;/a&gt;)
&lt;p&gt;My name is Ted Neward. And I bow with respect to the &amp;quot;software laborers&amp;quot; of the world, who churn out quality code without concern for &amp;quot;craftsmanship&amp;quot;, because their lives are more than just their code.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>On Functional Programming in Java</title>
      <link>http://blogs.newardassociates.com/blog/2013/on-functional-programming-in-java.html</link>
      <pubDate>Mon, 21 Jan 2013 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2013/on-functional-programming-in-java.html</guid>
      	<description>
	&lt;p&gt;Elliott Rusty Harold is &lt;a href=&quot;http://cafe.elharo.com/programming/java-programming/why-functional-programming-in-java-is-dangerous/&quot;&gt;blogging that functional programming in Java is dangerous&lt;/a&gt;. He&apos;s wrong, and he&apos;s way late to the party on this one--it&apos;s coming to Java whether he likes it or not.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Go read his post first, while I try to sum up the reasons he cites for saying it&apos;s dangerous:
&lt;ol&gt;
&lt;li&gt;Java is not a lazy-evaluated language. Programmers in Java will screw up and create heap and stack errors as a result.&lt;/li&gt;
&lt;li&gt;See? Here&apos;s a naive implementation of Clojure code taken directly over to Java and look how it blows up.&lt;/li&gt;
&lt;li&gt;Programmers can do bad things with this idea, so therefore we should avoid it.&lt;/li&gt;
&lt;li&gt;Oh, and by the way, it&apos;s &quot;dangerously inefficient&quot; in Java/JVM, even though I offer no perf benchmarks or comparisons to back this statement, and I&apos;m somehow ignoring that Clojure and Scala run on the JVM as well, apparently without problem.&lt;/li&gt;
&lt;/ol&gt;
That kind of about sums it up, I think.&lt;/p&gt;
&lt;p&gt;Look, as Elliott points out, Java is not Haskell. Neither is it Lisp. It&apos;s its own language, rooted in imperative and object-oriented history, but no less able to incorporate functional features into its development than Lisp could incorporate object-oriented features. However, if you do stupid things, like trying to re-create an infinite (implicitly lazily-evaluated) list in Clojure by creating an actualized list that stretches to infinity... you&apos;re going to blow the JVM up. Duh. Not even the supercomputer on the USS Enterprise five hundred years from now will be able to construct that list.&lt;/p&gt;
&lt;p&gt;Porting code from one language to another is not a trivial exercise. If you attempt to port line-for-line and expression-for-expression, you can expect that your ported code will not be idiomatically correct. (I know this already, having &lt;a href=&quot;http://blogs.tedneward.com/2012/12/21/Envoy+In+Scala+JavaScript+And+More.aspx&quot;&gt;done the exercise myself&lt;/a&gt;.) The root of the problem in his ported code is twofold. One, he (rather foolishly and in elegant strawman fashion) badly simulates what an infinite list would look like in Java--a commenter does the better job by showing how an Iterator can be made to perform the same thing that Haskell actually does under the hood by producing the next value on demand, rather than trying to create a list of Integers stretching to infinity. For someone who professes to have some Haskell experience and love, it surprises me that Elliott makes this kind of mistake, which leads me to conclude that he&apos;s trying to create the strawman. Two, he assumes that anyone who programs in Java functionally will have to create all of their functional tools by hand, and frankly, using Guava or FJ here would make this code sample a LOT easier to swallow. The fact that he ignores both of these in his stawman again sort of reinforces the idea that he&apos;s deliberately crippling his strawman to make his point.&lt;/p&gt;
&lt;p&gt;His underlying point, though, seems to be simple: &quot;I work with bad programmers, who don&apos;t seem to understand how to write code functionally in Java without screwing it up.&quot; Dude. Sucks to be you. &quot;Bad programmers will move heaven and earth to do the wrong thing.&quot; --Glenn Vanderburg.&lt;/p&gt;
&lt;p&gt;What really sucks for him is that these features are coming in Java 8, including lambda expressions and library support including a Stream interface that will allow for exactly this kind of code to be written without pain. Those programmers Elliott is working with are going to be even more on fire to use their functional approaches (and all the associated goodness of doing so, including composability and what-not) in their Java code. What might make Elliott more happy is that at least they won&apos;t have written it; it&apos;ll all be written by guys much smarter than any of them.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Book Review: Metaprogramming in .NET</title>
      <link>http://blogs.newardassociates.com/blog/2013/book-review-metaprogramming-in-net.html</link>
      <pubDate>Sat, 5 Jan 2013 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2013/book-review-metaprogramming-in-net.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;&lt;a href=&quot;http://www.amazon.com/Metaprogramming-NET-Kevin-Hazzard/dp/1617290262/ref=sr_1_1&quot;&gt;Metaprogramming in .NET&lt;/a&gt;&lt;/em&gt; (Kevin Hazzard, Jason Bock; Manning)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; This is a great book (not perfect), but not an easy read for everyone, not because the writing is bad, but because the subject is a whole new level of abstraction above what most developers deal with.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Full disclosure: Manning Publications is a publisher I&apos;ve published with before, and Kevin and Jason are both friends of mine in the .NET community. I write a column for MSDN Magazine, and metaprogramming was one of the topics in one of the series I&apos;ve written (&amp;quot;Metaparadigmatic Programming&amp;quot;) for the column, so this subject is not unfamiliar to me.&lt;/p&gt;
&lt;p&gt;Kevin and Jason have done a great job covering a pretty diverse subject, in my opinion. Because metaprogramming is &amp;quot;programming about programming&amp;quot;, it&apos;s sometimes a hard concept for people who&apos;ve never really investigated it to wrap their heads around, but Kevin and Jason do a great job opening with some concepts first, then exploring .NET Reflection, which is most developers&apos; first introduction to metaprogramming. If you can understand how Reflection is programming against code and code metadata, then you&apos;re in a good place to start exploring metaprogramming in further depth.&lt;/p&gt;
&lt;p&gt;And explore it they do. From code generation with T4, CodeDOM and Reflection.Emit to code-level Expressions to low-level IL munging, they take you through a lot of the metaprogramming tools. They&apos;ve also tried to include some practical places where these techniques are useful, though I do wish the examples had been a bit &amp;quot;larger&amp;quot;, meaning they were integrated into the larger picture of a &amp;quot;real-world&amp;quot; system, but that&apos;s hard to do sometimes, and most readers sufficiently senior enough to read this book should be able to see how to apply them to their own problems. I also wish they&apos;d approached generics a bit more thoroughly, since that&apos;s another metaprogrammatic technique that often doesn&apos;t get much love from developers (most of whom seem to view generics as a necessary evil, not a huge opportunity for design power), but maybe that would&apos;ve been too much head-exploding for one book. Writing a LINQ provider would&apos;ve been a good enhancement to the book, but again, that may have been a little too much for one book. I also wish they had put an IL overview into its own chapter, since it comes up in several chapters at once and would&apos;ve been good as a reference, but there&apos;s books out there on IL, which hasn&apos;t changed much since .NET 2.0 days, so readers finding IL challenging should pick up one of those if they&apos;re finding their heads spinning a little on the IL syntax.&lt;/p&gt;
&lt;p&gt;Having taken you through those techniques, though, they then take a different tack and take you through scripting languages and the Microsoft Dynamic Language Runtime (DLR), as well as into a few &amp;quot;alternative&amp;quot; languages for the CLR, which is an entirely different way of approaching metaprogrammatic techniques. Nemerle, for example, is a language that supports macros defined within the language, a technique that generally is limited to Lisps. (I admit it, Nemerle is one of my favorite CLR languages, and should be something every .NET developer plays with for at least a weekend.) They also include the first published coverage that I&apos;m aware of on Roslyn, the Compiler-as-a-Service project under way at Microsoft, so readers intrigued by how they might use the compiler as part of their development efforts in v.Next of Visual Studio should definitely have a look.&lt;/p&gt;
&lt;p&gt;Overall, the writing style is crisp, clean, not too academic but not too folksy, and entirely representative of two men I&apos;ve been privileged to meet, have interesting technical conversations with, and have over to my house for dinner. Both are extremely approachable, and their text reflects this. Every .NET developer that wants to claim &amp;quot;senior&amp;quot; or &amp;quot;guru&amp;quot; level status should read this book and experiment with one or more of these techniques; these are the things that the &amp;quot;cool kids&amp;quot; in the .NET world know how to do, and if you want to hang with the best, this is the book you&apos;ll read cover to cover.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;(This review was posted to Amazon at the above link on 5 Jan 2013, then copy-and-pasted here because I like posting reviews to my blog as well as to Amazon.)&lt;/i&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2013 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2013/2013-tech-predictions.html</link>
      <pubDate>Tue, 1 Jan 2013 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2013/2013-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;Here we go again: the annual review of last year&apos;s predictions, and a set of new ones for the new year.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Once again, it&apos;s time for my annual prognostication and &lt;a href=&quot;../2012/2012-tech-predictions.html&quot;&gt;review of last year&apos;s efforts&lt;/a&gt;. For those of you who&apos;ve been long-time readers, you know what this means, but for those two or three of you who haven&apos;t seen this before, let&apos;s set the rules: if I got a prediction right from last year, you take a drink, and if I didn&apos;t, you take a drink. (Best. Drinking game. EVAR!)&lt;/p&gt;
&lt;p&gt;Let&apos;s begin....&lt;/p&gt;
&lt;h3 id=&quot;recap-2012-predictions&quot;&gt;Recap: 2012 Predictions&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;THEN&lt;/strong&gt;: &lt;em&gt;Lisps will be the languages to watch.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;With Clojure leading the way, Lisps (that is, languages that are more or less loosely based on Common Lisp or one of its variants) are slowly clawing their way back into the limelight. Lisps are both functional languages as well as dynamic languages, which gives them a significant reason for interest. Clojure runs on top of the JVM, which makes it highly interoperable with other JVM languages/systems, and Clojure/CLR is the version of Clojure for the CLR platform, though there seems to be less interest in it in the .NET world (which is a mistake, if you ask me).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOW&lt;/strong&gt;: Clojure is definitely cementing itself as a &quot;critic&apos;s darling&quot; of a language among the digital cognoscenti, but I don&apos;t see its uptake increasing--or decreasing. It seems that, like so many critic&apos;s darlings, those who like it are using it, and those who aren&apos;t have either never heard of it (the far more likely scenario) or don&apos;t care for it. Datomic, a NoSQL written by the creator of Clojure (Rich Hickey), is interesting, but I&apos;ve not heard of many folks taking it up, either. And Clojure/CLR is all but dead, it seems. I score myself a &quot;0&quot; on this one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;THEN&lt;/strong&gt;: &lt;em&gt;Functional languages will....&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have no idea. As I said above, I&apos;m kind of stymied on the whole functional-language thing and their future. I keep thinking they will either &quot;take off&quot; or &quot;drop off&quot;, and they keep tacking to the middle, doing neither, just sort of hanging in there as a concept for programmers to take and run with. Mind you, I like functional languages, and I want to see them become mainstream, or at least more so, but I keep wondering if the mainstream programming public is ready to accept the ideas and concepts hiding therein. So this year, let&apos;s try something different: I predict that they will remain exactly where they are, neither &quot;done&quot; nor &quot;accepted&quot;, but continue next year to sort of hang out in the middle.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOW&lt;/strong&gt;: Functional concepts are slowly making their way into the mainstream of programming topics, but in some cases, programmers seem to be picking-and-choosing which of the functional concepts they believe in. I&apos;ve heard developers argue vehemently about &quot;lazy values&quot; but go &quot;meh&quot; about lack-of-side-effects, or vice versa. Moreover, it seems that developers are still taking an &quot;object-first, functional-when-I-need-it&quot; kind of approach, which seems a little object-heavy, if you ask me. So, since the concepts seem to be taking some sort of shallow root, I don&apos;t know that I get the point for this one, but at the same time, it&apos;s not like I was wildly off. So, let&apos;s say &quot;0&quot; again.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;THEN&lt;/strong&gt;: &lt;em&gt;F#&apos;s type providers will show up in C# v.Next.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This one is actually a &quot;gimme&quot;, if you look across the history of F# and C#: for almost every version of F# v.&quot;N&quot;, features from that version show up in C# v.&quot;N+1&quot;. More importantly, F# 3.0&apos;s type provider feature is an amazing idea, and one that I think will open up language research in some very interesting ways. (Not sure what F#&apos;s type providers are or what they&apos;ll do for you? Check out Don Syme&apos;s talk on it at BUILD last year.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOW&lt;/strong&gt;: C# v.Next hasn&apos;t been announced yet, so I can&apos;t say that this one has come true. We should start hearing some vague rumors out of Redmond soon, though, so maybe 2013 will be the year that C# gets type providers (or some scaled-back version thereof). Again, a &quot;0&quot;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;THEN&lt;/strong&gt;: &lt;em&gt;Windows8 will generate a lot of chatter.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As 2012 progresses, Microsoft will try to force a lot of buzz around it by keeping things under wraps until various points in the year that feel strategic (TechEd, BUILD, etc). In doing so, though, they will annoy a number of people by not talking about them more openly or transparently.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOW&lt;/strong&gt;: Oh, my, did they. Windows8 was announced with a bang, but Microsoft (and Sinofsky, who ran the OS division up until recently) decided that they could go it alone and leave critical partners (like Dropbox!) out of the loop entirely. As a result, the Windows8 Store didn&apos;t have a lot of apps in it that people (including myself) really expected would be there. And THEN, there was Surface... which took everybody by surprise, as near as I can tell. Totally under wraps. I&apos;m scoring myself &quot;+2&quot; for that one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;THEN&lt;/strong&gt;: &lt;em&gt;Windows8 (&quot;Metro&quot;)-style apps won&apos;t impress at first.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The more I think about it, the more I&apos;m becoming convinced that Metro-style apps on a desktop machine are going to collectively underwhelm. The UI simply isn&apos;t designed for keyboard-and-mouse kinds of interaction, and that&apos;s going to be the hardware setup that most people first experience Windows8 on--contrary to what (I think) Microsoft thinks, people do not just have tablets laying around waiting for Windows 8 to be installed on it, nor are they going to buy a Windows8 tablet just to try it out, at least not until it&apos;s gathered some mojo behind it. Microsoft is going to have to finesse the messaging here very, very finely, and that&apos;s not something they&apos;ve shown themselves to be particularly good at over the last half-decade.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOW&lt;/strong&gt;: I find myself somewhat at a loss how to score this one--on the one hand, the &quot;used-to-be-called-Metro&quot;-style applications aren&apos;t terrible, and I haven&apos;t really heard anyone complain about them tremendously, but at the same time, I haven&apos;t heard anyone really go wild and ga-ga over them, either. Part of that, I think, is because there just aren&apos;t a lot of apps out there for it yet, aside from a rather skimpy selection of games (compared to the iOS App Store and Android Play Store). Again, I think Microsoft really screwed themselves with this one--keeping it all under wraps helped them make a big &quot;Oh, WOW&quot; kind of event buzz within the conference hall when they announced Surface, for example, but that buzz sort of left the room (figuratively) when people started looking for their favorite apps so they could start using that device. (Which, by the way, isn&apos;t a bad piece of hardware, I&apos;m finding.) I&apos;ll give myself a &quot;+1&quot; for this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;THEN&lt;/strong&gt;: &lt;em&gt;Scala will get bigger, thanks to Heroku.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;With the adoption of Scala and Play for their Java apps, Heroku is going to make Scala look attractive as a development platform, and the adoption of Play by Typesafe (the same people who brought you Akka) means that these four--Heroku, Scala, Play and Akka--will combine into a very compelling and interesting platform. I&apos;m looking forward to seeing what comes of that.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOW&lt;/strong&gt;: We&apos;re going to get to cloud in a second, but on the whole, Heroku is now starting to make Scala/Play attractive, arguably as attractive as Ruby/Rails is. Play 2.0 unfortunately is not backwards-compatible with Play 1.x modules, which hurts it, but hopefully the Play community brings that back up to speed fairly quickly. &quot;+1&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;THEN&lt;/strong&gt;: &lt;em&gt;Cloud will continue to whip up a lot of air.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For all the hype and money spent on it, it doesn&apos;t really seem like cloud is gathering commensurate amounts of traction, across all the various cloud providers with the possible exception of Amazon&apos;s cloud system. But, as the different cloud platforms start to diversify their platform technology (Microsoft seems to be leading the way here, ironically, with the introduction of Java, Hadoop and some limited NoSQL bits into their Azure offerings), and as we start to get more experience with the pricing and costs of cloud, 2012 might be the year that we start to see mainstream cloud adoption, beyond &quot;just&quot; the usage patterns we&apos;ve seen so far (as a backing server for mobile apps and as an easy way to spin up startups).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOW&lt;/strong&gt;: It&apos;s been whipping up air, all right, but it&apos;s starting to look like tornadoes and hurricanes--the talk of 2012 seems to have been more around notable cloud outages instead of notable cloud successes, capped off by a nationwide Netflix outage on Christmas Eve that seemed to dominate my Facebook feed that night. Later analysis suggested that the outage was with Amazon&apos;s AWS cloud, on which Netflix resides, and boy, did that make a few heads spin. I suspect we haven&apos;t yet (as of this writing) seen the last of that discussion. Overall, it seems like lots of startups and other greenfield apps are being deployed to the cloud, but it seems like corporations are hesitating to pull the trigger on an &quot;all-in&quot; kind of cloud adoption, because of some of the fears surrounding cloud security and now (of all things) robustness. &quot;+1&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;THEN&lt;/strong&gt;: &lt;em&gt;Android tablets will start to gain momentum.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Amazon&apos;s Kindle Fire has hit the market strong, definitely better than any other Android-based tablet before it. The Nooq (the Kindle&apos;s principal competitor, at least in the e-reader world) is also an Android tablet, which means that right now, consumers can get into the Android tablet world for far, far less than what an iPad costs. Apple rumors suggest that they may have a 7&quot; form factor tablet that will price competitively (in the $200/$300 range), but that&apos;s just rumor right now, and Apple has never shown an interest in that form factor, which means the 7&quot; world will remain exclusively Android&apos;s (at least for now), and that&apos;s a nice form factor for a lot of things. This translates well into more sales of Android tablets in general, I think.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOW&lt;/strong&gt;: Google&apos;s Nexus 7 came to dominate the discussion of the 7&quot; tablet, until...&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;THEN&lt;/strong&gt;: &lt;em&gt;Apple will release an iPad 3, and it will be &quot;more of the same&quot;.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Trying to predict Apple is generally a lost cause, particularly when it comes to their vaunted iOS lines, but somewhere around the middle of the year would be ripe for a new iPad, at the very least. (With the iPhone 4S out a few months ago, it&apos;s hard to imagine they&apos;d cannibalize those sales by releasing a new iPhone, until the end of the year at the earliest.) Frankly, though, I don&apos;t expect the iPad 3 to be all that big of a boost, just a faster processor, more storage, and probably about the same size. Probably the only thing I&apos;d want added to the iPad would be a USB port, but that conflicts with the Apple desire to present the iPad as a &quot;device&quot;, rather than as a &quot;computer&quot;. (USB ports smack of &quot;computers&quot;, not self-contained &quot;devices&quot;.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOW&lt;/strong&gt;: ... the iPad Mini. Which, I&apos;d like to point out, is just an iPad in a 7&quot; form factor. (Actually, I think it&apos;s a little bit bigger than most 7&quot; tablets--it looks to be a smidge wider than the other 7&quot; tablets I have.) And the &quot;new iPad&quot; (not the iPad 3, which I call a massive FAIL on the part of Apple marketing) is exactly that: same iPad, just faster. And still no USB port on either the iPad or iPad Mini. So between this one and the previous one, I score myself at &quot;+3&quot; across both.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;THEN&lt;/strong&gt;: &lt;em&gt;Apple will get hauled in front of the US government for... something.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Apple&apos;s recent foray in the legal world, effectively informing Samsung that they can&apos;t make square phones and offering advice as to what will avoid future litigation, smacks of such hubris and arrogance, it makes Microsoft look like a Pollyanna Pushover by comparison. It is pretty much a given, it seems to me, that a confrontation in the legal halls is not far removed, either with the US or with the EU, over anti-cometitive behavior. (And if this kind of behavior continues, and there is no legal action, it&apos;ll be pretty apparent that Apple has a pretty good set of US Congressmen and Senators in their pocket, something they probably learned from watching Microsoft and IBM slug it out rather than just buy them off.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOW&lt;/strong&gt;: Congress has started to take a serious look at the patent system and how it&apos;s being used by patent trolls (of which, folks, I include Apple these days) to stifle innovation and create this Byzantine system of cross-patent licensing that only benefits the big players, which was exactly what the patent system was designed to avoid. (Patents were supposed to be a way to allow inventors, who are often independents, to avoid getting crushed by bigger, established, well-monetized firms.) Apple hasn&apos;t been put squarely in the crosshairs, but the Economist&apos;s article on Apple, Google, Microsoft and Amazon in the Dec 11th issue definitely points out that all four are squarely in the sights of governments on both sides of the Atlantic. Still, no points for me.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;THEN&lt;/strong&gt;: &lt;em&gt;IBM will be entirely irrelevant again.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Look, IBM&apos;s main contribution to the Java world is/was Eclipse, and to a much lesser degree, Harmony. With Eclipse more or less &quot;done&quot; (aside from all the work on plugins being done by third parties), and with IBM abandoning Harmony in favor of OpenJDK, IBM more or less removes themselves from the game, as far as developers are concerned. Which shouldn&apos;t really be surprising--they&apos;ve been more or less irrelevant pretty much ever since the mid-2000s or so.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOW&lt;/strong&gt;: IBM who? Wait, didn&apos;t they used to make a really kick-ass laptop, back when we liked using laptops? &quot;+1&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;THEN&lt;/strong&gt;: &lt;em&gt;Oracle will &quot;screw it up&quot; at least once.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Right now, the Java community is poised, like a starving vulture, waiting for Oracle to do something else that demonstrates and befits their Evil Emperor status. The community has already been quick (far too quick, if you ask me) to highlight Oracle&apos;s supposed missteps, such as the JVM-crashing bug (which has already been fixed in the _u1 release of Java7, which garnered no attention from the various Java news sites) and the debacle around Hudson/Jenkins/whatever-the-heck-we-need-to-call-it-this-week. I&apos;ll grant you, the Hudson/Jenkins debacle was deserving of ire, but Oracle is hardly the Evil Emperor the community makes them out to be--at least, so far. (I&apos;ll admit it, though, I&apos;m a touch biased, both because Brian Goetz is a friend of mine and because Oracle TechNet has asked me to write a column for them next year. Still, in the spirit of &quot;innocent until proven guilty&quot;....)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOW&lt;/strong&gt;: It is with great pleasure that I score myself a &quot;0&quot; here. Oracle&apos;s been pretty good about things, sticking with the OpenJDK approach to developing software and talking very openly about what they&apos;re trying to do with Java8. They&apos;re not entirely innocent, mind you--the fact that a Java install tries to monkey with my browser bar by installing some plugin or other and so on is not something I really appreciate--but they&apos;re not acting like Ming the Merciless, either. Matter of fact, they even seem to be going out of their way to be community-inclusive, in some circles. I give myself a &quot;-1&quot; here, and I&apos;m happy to claim it. Good job, guys.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;THEN&lt;/strong&gt;: &lt;em&gt;VMWare/SpringSource will start pushing their cloud solution in a major way.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Companies like Microsoft and Google are pushing cloud solutions because Software-as-a-Service is a reoccurring revenue model, generating revenue even in years when the product hasn&apos;t incremented. VMWare, being a product company, is in the same boat--the only time they make money is when they sell a new copy of their product, unless they can start pushing their virtualization story onto hardware on behalf of clients--a.k.a. &quot;the cloud&quot;. With SpringSource as the software stack, VMWare has a more-or-less complete cloud play, so it&apos;s surprising that they didn&apos;t push it harder in 2011; I suspect they&apos;ll start cramming it down everybody&apos;s throats in 2012. Expect to see Rod Johnson talking a lot about the cloud as a result.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOW&lt;/strong&gt;: Again, I give myself a &quot;-1&quot; here, and frankly, I&apos;m shocked to be doing it. I really thought this one was a no-brainer. CloudFoundry seemed like a pretty straightforward play, and VMWare already owned a significant share of the virtualization story, so.... And yet, I really haven&apos;t seen much by way of significant marketing, advertising, or developer outreach around their cloud story. It&apos;s much the same as what it was in 2011; it almost feels like the parent corporation (EMC) either doesn&apos;t &quot;get&quot; why they should push a cloud play, doesn&apos;t see it as worth the cost, or else doesn&apos;t care. Count me confused. &quot;0&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;THEN&lt;/strong&gt;: &lt;em&gt;JavaScript hype will continue to grow, and by years&apos; end will be at near-backlash levels.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;JavaScript (more properly known as ECMAScript, not that anyone seems to care but me) is gaining all kinds of steam as a mainstream development language (as opposed to just-a-browser language), particularly with the release of NodeJS. That hype will continue to escalate, and by the end of the year we may start to see a backlash against it. (Speaking personally, NodeJS is an interesting solution, but suggesting that it will replace your Tomcat or IIS server is a bit far-fetched; event-driven I/O is something both of those servers have been doing for years, and the rest of it is &quot;just&quot; a language discussion. We could pretty easily use JavaScript as the development language inside both servers, as Sun demonstrated years ago with their &quot;Phobos&quot; project--not that anybody really cared back then.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOW&lt;/strong&gt;: JavaScript frameworks are exploding everywhere like fireworks at a Disney theme park. Douglas Crockford is getting more invites to conference keynote opportunities than James Gosling ever did. You can get a job if you know how to spell &quot;NodeJS&quot;. And yet, I&apos;m starting to hear the same kinds of rumblings about &quot;how in the hell do we manage a 200K LOC codebase written in JavaScript&quot; that I heard people gripe about Ruby/Rails a few years ago. If the backlash hasn&apos;t started, then it&apos;s right on the cusp. &quot;+1&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;THEN&lt;/strong&gt;: &lt;em&gt;NoSQL buzz will continue to grow, and by years&apos; end will start to generate a backlash.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;More and more companies are jumping into NoSQL-based solutions, and this trend will continue to accelerate, until some extremely public failure will start to generate a backlash against it. (This seems to be a pattern that shows up with a lot of technologies, so it seems entirely realistic that it&apos;ll happen here, too.) Mind you, I don&apos;t mean to suggest that the backlash will be factual or correct--usually these sorts of things come from misuing the tool, not from any intrinsic failure in it--but it&apos;ll generate some bad press.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOW&lt;/strong&gt;: Recently, I heard that NBC was thinking about starting up a new comedy series called &quot;Everybody Hates Mongo&quot;, with Chris Rock narrating. And I think that&apos;s just the beginning--lots of companies, particularly startups, decided to run with a NoSQL solution before seriously contemplating how they were going to make up for the things that a NoSQL doesn&apos;t provide (like a schema, for a lot of these), and suddenly find themselves wishing they had spent a little more time thinking about that back in the early days. Again, if the backlash isn&apos;t already started, it&apos;s about to. &quot;+1&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;THEN&lt;/strong&gt;: &lt;em&gt;Ted will thoroughly rock the house during his CodeMash keynote.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Yeah, OK, that&apos;s more of a fervent wish than a prediction, but hey, keep a positive attitude and all that, right?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOW&lt;/strong&gt;: Welllll..... Looking back at it with almost a years&apos; worth of distance, I can freely admit I dropped a few too many &quot;F&quot;-bombs (a buddy of mine counted 18), but aside from a (very) vocal minority, my takeaway is that a lot of people enjoyed it. Still, I do wish I&apos;d throttled it back some--InfoQ recorded it, and the fact that it hasn&apos;t yet seen public posting on the website implies (to me) that they found it too much work to &quot;bleep&quot; out all the naughty words. Which I call &quot;my bad&quot; on, because I think they were really hoping to use that as part of their promotional activities (not that they needed it, selling out again in minutes). To all those who found it distasteful, I apologize, and to those who chafe at the fact that I&apos;m apologizing, I apologize. I take a &quot;-1&quot; here.&lt;/p&gt;
&lt;h3 id=&quot;predictions&quot;&gt;2013 Predictions:&lt;/h3&gt;
&lt;p&gt;Having thus scored myself at a &quot;9&quot; (out of 17) for last year, let&apos;s take a stab at a few for next year:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&quot;Big data&quot; and &quot;data analytics&quot; will dominate the enterprise landscape.&lt;/strong&gt; I&apos;m actually pretty late to the ballgame to talk about this one, in fact--it was starting its rapid climb up the hype wave already this year. And, part and parcel with going up this end of the hype wave this quickly, it also stands to reason that companies will start marketing the hell out of the term &quot;big data&quot; without being entirely too precise about what they mean when they say &quot;big data&quot;.... By the end of the year, people will start building services and/or products on top of Hadoop, which appears primed to be the &quot;Big Data&quot; platform of choice, thus far.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NoSQL buzz will start to diversify.&lt;/strong&gt; The various &quot;NoSQL&quot; vendors are going to start wanting to differentiate themselves from each other, and will start using &quot;NoSQL&quot; in their marketing and advertising talking points less and less. Some of this will be because Pandora&apos;s Box on data storage has already been opened--nobody&apos;s just assuming a relational database all the time, every time, anymore--but some of this will be because the different NoSQL vendors, who are at different stages in the adoption curve, will want to differentiate themselves from the vendors that are taking on the backlash. I predict Mongo, who seems to be leading the way of the NoSQL vendors, will be the sacrificial scapegoat for a lot of the NoSQL backlash that&apos;s coming down the pike.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Desktops increasingly become niche products.&lt;/strong&gt; Look, does anyone buy a desktop machine anymore? I have three sitting next to me in my office, and none of the three has been turned on in probably two years--I&apos;m exclusively laptop-bound these days. Between tablets as consumption devices (slowly obsoleting the laptop), and cloud offerings becoming more and more varied (slowly obsoleting the server), there&apos;s just no room for companies that sell desktops--or the various Mom-and-Pop shops that put them together for you. In fact, I&apos;m starting to wonder if all those parts I used to buy at Fry&apos;s Electronics and swap meets will start to disappear, too. Gamers keep desktops alive, and I don&apos;t know if there&apos;s enough money in that world to keep lots of those vendors alive. (I hope so, but I don&apos;t know for sure.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Home servers will start to grow in interest.&lt;/strong&gt; This may seem paradoxical to the previous point, but I think techno-geek leader-types are going to start looking into &quot;servers-in-a-box&quot; that they can set up at home and have all their devices sync to and store to. Sure, all the media will come through there, and the key here will be &quot;turnkey&quot;, since most folks are getting used to machines that &quot;just work&quot;. Lots of friends, for example, seem to be using Mac Minis for exactly this purpose, and there&apos;s a vendor here in Redmond that sells a &lt;a href=&quot;http://www.usmicro.com/hot-offers.php&quot;&gt;ridiculously-powered server in a box&lt;/a&gt; for a couple thousand. (This is on my birthday list, right after I get my maxed-out 13&quot; MacBook Air and iPad 3.) This is also going to be fueled by...&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Private cloud is going to start getting hot.&lt;/strong&gt; The great advantage of cloud is that you don&apos;t have to have an IT department; the great disadvantage of cloud is that when things go bad, you don&apos;t have an IT department. Too many well-publicized cloud failures are going to drive corporations to try and find a solution that is the best-of-both-worlds: the flexibility and resiliency of cloud provisioning, but staffed by IT resources they can whip and threaten and cajole when things fail. (And, by the way, I fully understand that most cloud providers have better uptimes than most private IT organizations--this is about perception and control and the feelings of powerlessness and helplessness when things go south, not reality.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Oracle will release Java8, and while several Java pundits will decry &quot;it&apos;s not the Java I love!&quot;, most will actually come to like it.&lt;/strong&gt; Let&apos;s be blunt, Java has long since moved past being the flower of fancy and a critic&apos;s darling, and it&apos;s moved squarely into the battleship-gray of slogging out code and getting line-of-business apps done. Java8 adopting function literals (aka &quot;closures&quot;) and retrofitting the Collection library to use them will be a subtle, but powerful, extension to the lifetime of the Java language, but it&apos;s never going to be sexy again. Fortunately, it doesn&apos;t need to be.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microsoft will start courting the .NET developers again.&lt;/strong&gt; Windows8 left a bad impression in the minds of many .NET developers, with the emphasis on HTML/JavaScript apps and C++ apps, leaving many .NET developers to wonder if they were somehow rendered obsolete by the new platform. Despite numerous attempts in numerous ways to tell them no, developers still seem to have that opinion--and Microsoft needs to go on the offensive to show them that .NET and Windows8 (and WinRT) do, in fact, go very well together. Microsoft can&apos;t afford for their loyal developer community to feel left out or abandoned. They know that, and they&apos;ll start working on it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Samsung will start pushing themselves further and further into the consumer market.&lt;/strong&gt; They already have started gathering more and more of a consumer name for themselves, they just need to solidify their tablet offerings and get closer in line with either Google (for Android tablets) or even Microsoft (for Windows8 tablets and/or Surface competitors) to compete with Apple. They may even start looking into writing their own tablet OS, which would be something of a mistake, but an understandable one.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple&apos;s next release cycle will, again, be &quot;more of the same&quot;.&lt;/strong&gt; iPhone 6, iPad 4, iPad Mini 2, MacBooks, MacBook Airs, none of them are going to get much in the way of innovation or new features. Apple is going to run squarely into the Innovator&apos;s Dilemma soon, and their products are going to be &quot;more of the same&quot; for a while. Incremental improvements along a couple of lines, perhaps, but nothing Earth-shattering. (Hey, Apple, how about opening up Siri to us to program against, for example, so we can hook into her command structure and hook our own apps up? I can do that with Android today, why not her?)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Visual Studio 2014 features will start being discussed at the end of the year.&lt;/strong&gt; If Microsoft is going to hit their every-two-year-cycle with Visual Studio, then they&apos;ll start talking/whispering/rumoring some of the v.Next features towards the middle to end of 2013. I fully expect C# 6 will get some form of type providers, Visual Basic will be a close carbon copy of C# again, and F# 4 will have something completely revolutionary that anyone who sees it will be like, &quot;Oh, cool! Now, when can I get that in C#?&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scala interest wanes.&lt;/strong&gt; As much as I don&apos;t want it to happen, I think interest in Scala is going to slow down, and possibly regress. This will be the year that Typesafe needs to make a major splash if they want to show the world that they&apos;re serious, and I don&apos;t know that the JVM world is really all that interested in seeing a new player. Instead, I think Scala will be seen as what &quot;the 1%&quot; of the Java community uses, and the rest will take some ideas from there and apply them (poorly, perhaps) to Java.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interest in native languages will rise.&lt;/strong&gt; Just for kicks, developers will start experimenting with some of the new compile-to-native-code languages (Go, Rust, Slate, Haskell, whatever) and start finding some of the joys (and heartaches) that come with running &quot;on the metal&quot;. More importantly, they&apos;ll start looking at ways to use these languages with platforms where running &quot;on the metal&quot; is more important, like mobile devices and tablets.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As always, folks, thanks for reading. See you next year.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;UPDATE:&lt;/b&gt; Two things happened this week (7 Jan 2013) that made me want to add to this list:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hardware is the new platform.&lt;/strong&gt; A buddy of mine (Scott Davis) pointed out on a mailing list we share that &quot;hardware is the new platform&quot;, and with Microsoft&apos;s Surface out now, there&apos;s three major players (Apple, Google, Microsoft) in this game. It&apos;s becoming apparent that more and more companies are starting to see opportunities in going the Apple route of owning not just the OS and the store, but the hardware underneath it. More and more companies are going to start playing this game, too, I think, and we&apos;re going to see Amazon take some shots here, and probably a few others. Of course, already announced is the Ubuntu Phone, and a new Android-like player, &lt;a href=&quot;http://www.tizen.org&quot;&gt;Tizen&lt;/a&gt;, but I&apos;m not thinking about new players--there&apos;s always new players--but about some of the big standouts. And look for companies like Dell and HP to start looking for ways to play in this game, too, either through partnerships or acquisitions. (Hello, Oracle, I&apos;m looking at you.... And Adobe, too.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;APIs for lots of things are going to come out.&lt;/strong&gt; Ford &lt;a href=&quot;http://techcrunch.com/2013/01/07/ford-launches-open-developer-program-to-let-mobile-apps-interface-with-its-cars/&quot;&gt;just&lt;/a&gt; did &lt;a href=&quot;http://developer.ford.com&quot;&gt;this&lt;/a&gt;. This is not going away--this is going to proliferate. And the startup community is going to lap it up like kittens attacking a bowl of cream. If you&apos;re looking for a play in the startup world, pursue this.&lt;/li&gt;
&lt;/ul&gt;

	</description>
    </item>
    <item>
      <title>Envoy (in Scala, JavaScript, and more)</title>
      <link>http://blogs.newardassociates.com/blog/2012/envoy-in-scala-javascript-and-more.html</link>
      <pubDate>Thu, 20 Dec 2012 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2012/envoy-in-scala-javascript-and-more.html</guid>
      	<description>
	&lt;p&gt;A little over a decade ago, Eugene Wallingford wrote a paper for the PloP &apos;99 conference, describing the &lt;a href=&quot;http://www.cs.uni.edu/~wallingf/patterns/envoy.pdf&quot;&gt;Envoy&lt;/a&gt; pattern language, &amp;quot;a pattern language for managing state in a functional program&amp;quot;. It&apos;s a good read, but the implementation language for the paper is Scheme--given that it&apos;s a Lisp dialect, often isn&apos;t particularly obvious or easy to understand at first, I thought it might be interesting (both for me and any readers that wanted to follow along) to translate the implementation examples into a variety of different languages. In this case, I thought it would be relatively easy to do it in &lt;a href=&quot;http://www.typesafe.com&quot;&gt;Scala&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/F_Sharp_(programming_language)&quot;&gt;F#&lt;/a&gt;, given their hybrid object-functional nature, but it&apos;s also an interesting exercise to demonstrate it in [Javascript](I&apos;ll use NodeJS v0.8.15, running on my Mac, and Rhino, with the JVM), &lt;a href=&quot;http://mth.github.com/yeti/&quot;&gt;Yeti&lt;/a&gt; (an ML dialect that runs on the JVM), &lt;a href=&quot;http://jaskell.codehaus.org&quot;&gt;Jaskell&lt;/a&gt; (a Haskell dialect that also runs on the JVM), and, hey, what the heck, let&apos;s do it in C# while we&apos;re at it, just so the .NET guys don&apos;t feel too badly outnumbered.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;(I&apos;m posting this now with the intent of filling in the Yeti, Jaskell, F# and C# implementations later.)&lt;/p&gt;
&lt;p&gt;Note that with lambdas coming in Java 8, it&apos;ll be possible to adapt this pattern language to work with Java, too--I&apos;ll leave that as exercise to do for myself (and update this blog entry) once I get a Java8 build on the machine on which I&apos;m writing this.&lt;/p&gt;
&lt;p&gt;One reason for doing this in Yeti and Jaskell is to demonstrate the original purpose of the Envoy pattern language--that we can achieve object-like semantics even in languages that don&apos;t directly support object semantics (like Scheme). But for the other languages, it&apos;s fair to ask why anyone would bother doing this in languages that do directly support objects (a la Scala, F#, etc), since it would seem a lot easier to just use the object features directly. And, truth be told, it&apos;s true--when looking to model objects in a language that has first-class support for objects, just use that support and those features, and call it a day. The point of this exercise is, for me, to exercise the functional features of those languages, and see exactly how functional languages can provide some of the same benefits that an O-O language enjoys, without having to use the O-O features directly. (There&apos;s been a lot of people writing functional-isms in O-O languages, yours truly included, so it seems a good exercise to flip that on its head.) This will also help me figure out where/when/how to use these features, when the need arises.&lt;/p&gt;
&lt;p&gt;If you&apos;ve not yet read the Envoy pattern language, take a moment and do that now; I don&apos;t want to annoy Mr. Wallingford in any way by repeating his prose here (not to mention that I&apos;m going to have enough to do as it is just translating the code into several different languages). But I will toss in a brief summary of each of the elements in the pattern language, just so we&apos;re all on the same page about what&apos;s happening in each of these code samples.&lt;/p&gt;
&lt;h2 id=&quot;implementation-notes&quot;&gt;Implementation notes&lt;/h2&gt;
These are a few notes for each of the implementation langauges.
&lt;h3 id=&quot;javascript&quot;&gt;JavaScript&lt;/h3&gt;
Because I want to be able to run the JavaScript code on either the Node platform directly or on the Rhino engine (via the Java JDK &quot;jrunscript&quot; command that installs on Java implementations starting with Java 6), and because those two environments provide different mechanisms for printing to the console (&quot;console.log&quot; in Node, and &quot;println&quot; in Rhino), I create a top-level function &quot;out&quot; that aliases to one or the other of those, depending on what&apos;s defined in the environment:
&lt;pre&gt;&lt;code&gt;var out = (function() {
  if (typeof(console) !== &amp;quot;undefined&amp;quot; &amp;amp;amp;&amp;amp;amp;
      typeof(console.log) !== &amp;quot;undefined&amp;quot;)
    return console.log
  else if (typeof(println) !== &amp;quot;undefined&amp;quot;)
    return println
  else
    throw new Error(&amp;quot;No idea what to use for output&amp;quot;)
})();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(This actually gives away one of the punchlines in the first element of the pattern language, Function as Object, below, because here we&apos;re pretty clearly using &amp;quot;out&amp;quot; as a function-as-object.)&lt;br /&gt;
I used Rhino that ships with Java6, and node v0.8.15 for these.&lt;/p&gt;
&lt;h3 id=&quot;scala&quot;&gt;Scala&lt;/h3&gt;
I used Scala v2.9.2 running on Java6 for this.
&lt;h3 id=&quot;yeti&quot;&gt;Yeti&lt;/h3&gt;
Yeti is an ML-based language that compiles to Java bytecode. Unlike Scala, it&apos;s a functional-only language (well, sort of), with Hindley-Milner type inference. As the &lt;a href=&quot;http://mth.github.com/yeti/&quot;&gt;Yeti&lt;/a&gt; home page describes, it supports polymorphic structure and variant types, property fields, lazy lists, pattern-matching on values, and a decent interop facility against Java code (meaning it can call Java classes, as well as compile to classes to be called from Java if desired.)
&lt;p&gt;Yeti was at v0.9.7 at the time I wrote this, and again, running on the Java6 VM.&lt;/p&gt;
&lt;h3 id=&quot;f&quot;&gt;F#&lt;/h3&gt;
I&apos;m using the Visual Studio 2012 release to write the F# bits, which corresponds to F# 3.0. As far as I can tell, there&apos;s nothing really all that &quot;3.0-specific&quot; that I&apos;m using, so it should work with F# 2.0, which shipped with Visual Studio 2010, and there&apos;s nothing Windows-specific here either, which means it should run fine on F# 3.0-on-Mono.
Note that, like what I&apos;m doing with the JavaScript version, I&apos;m binding each of the pattern elements into a function for execution, thus creating a scope block that is dissociated from the larger global scope:
&lt;pre&gt;&lt;code&gt;let example = fun () -&amp;gt;
    Console.WriteLine &amp;quot;Howdy world&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If (like I tried once) we were to use the more naive approach:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let example =
    Console.WriteLine &amp;quot;Howdy world&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... then each of the functions is executed and the results bound to the name described (&amp;quot;example&amp;quot;, in this case) at the time the compiler sees it; in other words, each is eagerly-evaluated, instead of waiting to be invoked in the main entry point of the program later. By binding an anonymous function literal, it essentially lazy-fies each of them, and won&apos;t execute them until they are deliberately invoked in Main, as in:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[&amp;lt;EntryPoint&amp;gt;]
let main argv = 
    example()
    // ... the others go here
    0 // return an integer exit code
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the platform (and prelude) details out of the way, let&apos;s begin.&lt;/p&gt;
&lt;h3 id=&quot;c&quot;&gt;C#&lt;/h3&gt;
Wow, the C# version is going to be ugly. Let me explain what I mean.
&lt;p&gt;Let&apos;s start with the syntax for an anonymous function literal (a lambda, in C# parlance):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;() =&amp;gt; { return 5; };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a function that takes no arguments and yields an int. (Actually, to be exact, this is a delegate, since the lambda wouldn&apos;t need an explicit return or the curly braces, since it&apos;s a single-expression block and the lambda assumes that the result of the single expression should be implicitly returned.)&lt;/p&gt;
&lt;p&gt;Ideally, we&apos;d be able to capture this in an implicitly-typed local variable, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var giveMeFive = () =&amp;gt; { return 5; };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But unfortunately, C# doesn&apos;t allow this, saying that it &amp;quot;Cannot assign lambda to implicitly-typed local variable&amp;quot;. (Doesn&apos;t get much more straightforward than that when it comes to an error message.) So, we have to explicitly-type the local variable, which is a Func&amp;lt;&amp;gt; of some type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int&amp;gt; giveMeFive = () =&amp;gt; { return 5; };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hold on to this thought, because things are going to get even uglier when we want to invoke an anonymous block like this later (when we get into the Closure parts of the pattern language).&lt;/p&gt;
&lt;h2 id=&quot;function-as-object&quot;&gt;Function as Object&lt;/h2&gt;
In pure functional languages, it&apos;s actually difficult to keep state and data tied together--in fact, part of the whole point of a functional language is to write functions that operate on data, ideally on lots of different kinds of data. &quot;Therefore, create a function that acts like an object. Such a function carries the data it needs along with the expression that operates on the data. More importantly, an object encapsulates its data, ensuring that only the allowed operations are applied to them.&quot; In other words, by writing a function and keeping the data buried inside of it, we achieve the same kind of encapsulation that object-orientation has traditionally reserved for itself as its principal advantage. This is done via a closure, which is the next element in the language.
&lt;h3 id=&quot;scheme&quot;&gt;Scheme:&lt;/h3&gt;
The original Scheme implementation looked like this:
&lt;pre&gt;&lt;code&gt;(define balance 0)
(define withdraw
  (lambda (balance amount)
    (if (&amp;lt;= amount balance)
      (- balance amount)
      (error &amp;quot;Insufficient funds&amp;quot; balance))
  ))
(define deposit
  (lambda (balance amount)
    (+ balance amount)
  ))
(define accrue-interest
  (lambda (balance interest-rate)
    (+ balance (* balance interest-rate))
  ))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There&apos;s a few things wrong with this approach, as Wallingford points out, but to be faithful, recreating this in our target languages is pretty straightforward: three functions, each of which operate on parameters passed in. &amp;quot;You could create new accounts simply by binding values to names. Operating on accounts involves passing the account to the appropriate procedure and binding the new value as appropriate.&amp;quot;&lt;/p&gt;
&lt;h3 id=&quot;javascript-1&quot;&gt;JavaScript:&lt;/h3&gt;
In JavaScript, we can bind function values to names just as we can in Scheme, so it&apos;s not actually all that different, once you get past the lack of parentheses and added curly braces. Thus, it looks like:
&lt;pre&gt;&lt;code&gt;(function() {
  out(&amp;quot;function-as-object =========&amp;quot;)
  
  var balance = 0
  var withdraw = function(amount) {
    if (amount &amp;lt;= balance)
      balance = balance - amount
    else
      throw new Error(&amp;quot;Insufficient funds&amp;quot;)
  }
  var deposit = function(amount) {
    balance += amount
  }
  var accrueInterest = function(interestRate) {
    balance += (balance * interestRate)
  }
})()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that I wrap all of it into its own function so as to give the whole thing some scope--makes it easier to define in a single .js file and execute.&lt;/p&gt;
&lt;h3 id=&quot;scala-1&quot;&gt;Scala:&lt;/h3&gt;
Similarly, Scala allows us to bind functions to names, too:
&lt;pre&gt;&lt;code&gt;def functionAsObject() = {
  def withdraw(balance : Int, amount : Int) = {
    if (amount &amp;lt;= balance) balance - amount else throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
  }
  def deposit(balance: Int, amount : Int) = {
    balance + amount
  }
  def accrueInterest(balance : Int, rate : Float) = {
    balance + (balance * rate)
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, all of it is wrapped into a function for easier (on me, while I was experimenting with all of this) scoping.&lt;/p&gt;
&lt;h3 id=&quot;f-1&quot;&gt;F#:&lt;/h3&gt;
F#, like most functional/object hybrid languages, also offers the ability to bind functions to values, so this is also pretty straightforward. I choose to just operate against the &quot;global&quot; balance value, rather than do the more functional &quot;pass the balance in&quot; that the previous two use:
&lt;pre&gt;&lt;code&gt;let functionAsObject = fun () -&amp;gt;
    let balance = ref 0
    let withdraw = 
        fun amt -&amp;gt;
            if amt &amp;lt;= !balance then
                balance := (!balance) - amt
                !balance
            else
                raise (Exception(&amp;quot;Insufficient funds&amp;quot;))
    let deposit = 
        fun amt -&amp;gt; 
            balance := (!balance) + amt
            !balance
    let accrueInterest = 
        fun (intRate : float) -&amp;gt; 
            balance := (!balance) + (int (float !balance * intRate))
            !balance
    
    Console.WriteLine &amp;quot;=========&amp;gt; Function as Object&amp;quot;
    printfn &amp;quot;%d&amp;quot; (deposit 200)
    printfn &amp;quot;%d&amp;quot; (withdraw 50)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;yeti-ml&quot;&gt;Yeti (ML):&lt;/h3&gt;
Although Yeti supports a slightly more succinct syntax for defining a function, I choose to use the syntax that more closely matches what we&apos;re doing in the other examples--bind a function literal (do ... done;) to a name (withdraw, deposit and accrueInterest). Again, since this is running on top of the JVM, we have full access to the underlying Java library, which means we can make use of RuntimeException again as a cheap way of signaling a bad withdrawal.
&lt;pre&gt;&lt;code&gt;withdraw = 
  do bal amt:
    if amt &amp;lt;= bal then
      bal - amt
    else
      throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
    fi
  done;

deposit =
  do bal amt: bal + amt done;
  
accrueInterest =
  do bal intRate:
    bal + (bal * intRate)
  done;

balance = 100;
println (withdraw balance 10)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;jaskell-haskell&quot;&gt;Jaskell (Haskell):&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;c-1&quot;&gt;C#:&lt;/h3&gt;
This is a little more verbose than some of the other versions we&apos;ve seen thus far, because C# lacks the type-inference that F# or Yeti or Scala has, yet requires explicit typing (in some places) because it is a statically-typed language. Again, because the language explicitly forbids the assignment of a lambda/delegate to an implicitly-typed local variable, the local names &quot;withdraw&quot;, &quot;deposit&quot;, and &quot;accrueInterest&quot; have to be explicitly typed.
&lt;pre&gt;&lt;code&gt;static void FunctionAsObject()
{
    var balance = 0;
    Func&amp;lt;int, int&amp;gt; withdraw = (amount) =&amp;gt;
    {
        if (amount &amp;lt;= balance)
        {
            balance = balance - amount;
            return balance;
        }
        else
            throw new Exception(&amp;quot;Insufficient funds&amp;quot;);
    };
    Func&amp;lt;int, int&amp;gt; deposit = (amount) =&amp;gt; 
    {
        balance += amount; return balance;
    };
    Func&amp;lt;float, int&amp;gt; accrueInterest = (intRate) =&amp;gt; 
    { 
        balance += (int)(intRate * balance); return balance; 
    };

    Console.WriteLine(&amp;quot;=============&amp;gt; FunctionAsObject&amp;quot;);
    Console.WriteLine(&amp;quot;{0}&amp;quot;, deposit(100));
    Console.WriteLine(&amp;quot;{0}&amp;quot;, withdraw(10));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that again, I choose to operate on the &amp;quot;global&amp;quot; variable &amp;quot;balance&amp;quot;, rather than pass it in. (It&apos;s fairly easy to imagine how it would look if &amp;quot;balance&amp;quot; were passed in.)&lt;/p&gt;
&lt;h2 id=&quot;closure&quot;&gt;Closure&lt;/h2&gt;
&quot;You are writing a function with a free variable. How do you bundle a function with a data value defined outside the procedure&apos;s body?&quot; If the data value is defined inside the procedure, remember, it gets reset to the same value each time, and obviously this isn&apos;t going to track state at all well. &quot;So you might try defining the balance outside the function.&quot; But that doesn&apos;t work, because now the value isn&apos;t encapsulated anymore. &quot;Therefore, create the function in an environment where its free variables are bound to local variables.&quot;
&lt;p&gt;This is something that O-O folks won&apos;t see right away, but it&apos;s a powerful mechanism for reuse. Traditional O-O says to tuck the encapsulated value (balance) away as a private field, but in environments like JavaScript, which lack any sort of formal access control, or in environments like the JVM or CLR, both of which offer a means by which to bypass access control directives (via the Reflection libraries in both), what&apos;s marked as &amp;quot;private&amp;quot; often isn&apos;t as private as we might want. By creating a local variable that&apos;s outside the scope of the returned function object but inside of the scope of the function returning the function (see where &amp;quot;balance&amp;quot; is declared in the JavaScript version, for example), the language or platform has to &amp;quot;close over&amp;quot; that variable (hence the name &amp;quot;closure&amp;quot;), thus making it accessible to the returned function for use, but effectively hidden away from any prying eyes that might want to screw with it outside of permitted access channels.&lt;/p&gt;
&lt;h3 id=&quot;scheme-1&quot;&gt;Scheme:&lt;/h3&gt;
The only key thing to note here is that &quot;withdraw&quot; references a lambda, a function literal in Scheme. We&apos;ll try to keep this flavor in the other language implementations, just to be faithful:
&lt;pre&gt;&lt;code&gt;(define withdraw
  (let ((balance 100)) ;; balance is defined here,
    (lambda (amount)
      (if (&amp;gt;= balance amount) ;; so this reference is bound
        (begin
          (set! balance (- balance amount))
          balance)
        (error &amp;quot;Insufficient funds&amp;quot; balance)))
    ))
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;javascript-2&quot;&gt;JavaScript:&lt;/h3&gt;
JavaScript is, surprisingly to some &quot;old-school&quot; JavaScript programmers, a full-fledged member of the family of languages that support closures, so all that&apos;s necessary here is to define a function that returns a function that &quot;closes over&quot; the local variable &quot;balance&quot;. But, in order to make sure that balance isn&apos;t reset to its original value of 100 each time we call the function, we have to actually invoke the outer function to return the inner function, which is then bound to the name &quot;withdraw&quot;; that way, the variable &quot;balance&quot; is initialized once, yet still referenced:
&lt;pre&gt;&lt;code&gt;(function() {
  out(&amp;quot;closure ====================&amp;quot;)

  var withdraw = function() {
    var balance = 100
    return function(amount) {
      if (balance &amp;gt;= amount) {
        balance -= amount
        return balance
      }
      else
        throw new Error(&amp;quot;Insufficient funds&amp;quot;)
    }
  }()
  out(&amp;quot;withdraw 20 &amp;quot; + withdraw(20))
  out(&amp;quot;withdraw 30 &amp;quot; + withdraw(30))
})()
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;scala-2&quot;&gt;Scala:&lt;/h3&gt;
We can do the same thing in Scala, and the syntax looks somewhat similar to the JavaScript version--create a function literal, invoke it, and bind the result to the name &quot;withdraw&quot;, where the return is another anonymous function literal:
&lt;pre&gt;&lt;code&gt;  def closure() = {
    val withdraw = (() =&amp;gt; {
      var balance = 100
      (amount: Int) =&amp;gt; {
        if (amount &amp;lt;= balance) {
          balance -= amount
          balance
        }
        else
          throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
      }
    })()
    println(withdraw(20))
    println(withdraw(20))
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;f-2&quot;&gt;F#:&lt;/h3&gt;
The F# version gets interesting because when we try to do the same thing that the JavaScript (or other languages) do--that is, &quot;close over&quot; a local variable defined in the outer scope--the compiler immediately rejects that, saying point-blank that the language does not support that, and to use &quot;reference variables&quot; (the `ref` keyword) instead:
&lt;pre&gt;&lt;code&gt;let closure = fun () -&amp;gt;
    let withdraw =
        let balance = ref 100
        fun amt -&amp;gt;
            if amt &amp;lt;= !balance then
                balance := (!balance) - amt
                !balance
            else
                raise (Exception(&amp;quot;Insufficient funds&amp;quot;))

    Console.WriteLine &amp;quot;=========&amp;gt; Closure&amp;quot;
    printfn &amp;quot;%d&amp;quot; (withdraw 20)
    printfn &amp;quot;%d&amp;quot; (withdraw 30)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What essentially we&apos;re doing, then, is capturing a pointer/reference to balance, and carrying that into the returned function literal, rather than letting the language capture that for us. The ref is dereferenced using the &amp;quot;!&amp;quot; operator, and assigned through using the &amp;quot;:=&amp;quot; operator, as can be seen above. Other than that, this is pretty much identical to the other languages&apos; versions.&lt;/p&gt;
&lt;p&gt;By the way, it should be noted that F#&apos;s &amp;quot;printfn&amp;quot; function is actually type-safe, so attempts to write &amp;quot;printfn &amp;quot;%d&amp;quot; x&amp;quot; where &amp;quot;x&amp;quot; is a non-integer value will yield a compile-time error. That&apos;s an incredibly spiffy feature, and I wish it were something we could apply to our own F# APIs, but from what I understand from Don Syme (the F# language creator), it&apos;s something that&apos;s baked into the compiler somehow. :-/&lt;/p&gt;
&lt;h3 id=&quot;yeti-ml-1&quot;&gt;Yeti (ML):&lt;/h3&gt;
Yeti works just as any of the others have, since we can define a function literal that returns a function literal, so just like the JavaScript and Scala versions, we can bind a variable (as opposed to a value, which is immutable) just outside the inner function literal, and Yeti will &quot;close over&quot; that variable and use it for modifiable state:
&lt;pre&gt;&lt;code&gt;withdraw = 
  (do:
    var balance = 100;
    do amt:
      if amt &amp;lt;= balance then
        balance := balance - amt;
        balance
      else
        throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
      fi
    done;
  done;) ();

println (withdraw 10);  // prints 90
println (withdraw 10);  // prints 80
println (withdraw 10);  // prints 70
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;jaskell-haskell-1&quot;&gt;Jaskell (Haskell):&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;c-2&quot;&gt;C#:&lt;/h3&gt;
Brace yourself--things are about to get really ugly here. The other versions suggest that we obtain encapsulation by capturing the &quot;balance&quot; value inside an outer function scope which is then referenced from an inner function scope, that inner function scope being the returned function literal. But... C# doesn&apos;t let us invoke function literals directly, except if they&apos;re cast to Func&lt;&gt; instances:
&lt;pre&gt;&lt;code&gt;static void Closure()
{
    Func&amp;lt;int, int&amp;gt; withdraw = ((Func&amp;lt;Func&amp;lt;int, int&amp;gt;)(() =&amp;gt; {
        var balance = 100;
        Func&amp;lt;int, int&amp;gt; result = delegate(int amount)
        {
            if (balance &amp;gt;= amount)
            {
                balance -= amount;
                return balance;
            }
            else
                throw new Exception(&amp;quot;Insufficient funds&amp;quot;);
        };
        return result;
    }))();
    Console.WriteLine(&amp;quot;=============&amp;gt; Closure&amp;quot;);
    Console.WriteLine(&amp;quot;{0}&amp;quot;, withdraw(20));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Did all that make sense? It might be clearer if I go back to the version I wrote that I had to use in order to figure all this out on my own:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;static void Closure()
{
    Func&amp;lt;Func&amp;lt;int, int&amp;gt; withdrawMaker = (delegate {
        var balance = 100;
        Func&amp;lt;int, int&amp;gt; result = delegate(int amount)
        {
            if (balance &amp;gt;= amount)
            {
                balance -= amount;
                return balance;
            }
            else
                throw new Exception(&amp;quot;Insufficient funds&amp;quot;);
        };
        return result;
    });
    Func&amp;lt;int, int&amp;gt; withdraw = withdrawMaker();

    Console.WriteLine(&amp;quot;=============&amp;gt; Closure&amp;quot;);
    Console.WriteLine(&amp;quot;{0}&amp;quot;, withdraw(20));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Why bother will all of this--why not just write it as a generalized method like O-O folks have done since the beginning of time? Because we want that &amp;quot;balance&amp;quot; tucked away somewhere where Reflection can&apos;t find it. So the double-level of function indirection is necessary; to cap things off, we don&apos;t want to have to write a one-use &amp;quot;maker&amp;quot; function every time.&lt;/p&gt;
&lt;h2 id=&quot;constructor-function&quot;&gt;Constructor Function&lt;/h2&gt;
&quot;You are creating a Function as Object using a Closure. How do you create instances of the object? [M]ake a function that returns your Function as Object. Give the function an Intention Revealing Name (Beck) such as make-object.&quot;
&lt;h3 id=&quot;scheme-2&quot;&gt;Scheme:&lt;/h3&gt;
Now things get more interesting, because the Scheme code is defining &quot;make-withdraw&quot; to be a lambda that in turn nests a lambda inside of it. This makes the syntax a little weird--since the returned value from &quot;make-withdraw&quot; is a lambda, the bound lambda must be executed in order to do the actual withdrawal.
&lt;pre&gt;&lt;code&gt;(define make-withdraw
  (lambda (balance)
    (lambda (amount)
      (if (&amp;gt;= balance amount)  ;; balance is still bound,
        (begin                 ;; but to a new object on each call
          (set! balance (- balance amount))
          balance)
        (error &amp;quot;Insufficient funds&amp;quot; balance)))
    ))
(define account-for-eugene (make-withdraw 100))
(account-for-eugene 20)    =&amp;gt; 80
(define account-for-tom (make-withdraw 1000))
(account-for-tom 20)       =&amp;gt; 980
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;javascript-3&quot;&gt;JavaScript:&lt;/h3&gt;
It&apos;s pretty common in JavaScript to create a function that returns a function, and that&apos;s the heart of what Constructor Function is doing: returning a function:
&lt;pre&gt;&lt;code&gt;(function() {
  out(&amp;quot;constructorFunction ========&amp;quot;)

  var makeWithdraw = function(balance) {
    return function(amount) {
      if (balance &amp;gt;= amount) {
        balance -= amount
        return balance
      }
      else
        throw new Error(&amp;quot;Insufficient funds&amp;quot;)
    }
  }
  var acctForEugene = makeWithdraw(100)
  out(acctForEugene(20))
  var acctForTed = makeWithdraw(1000)
  out(acctForTed(20))
})()
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;scala-3&quot;&gt;Scala:&lt;/h3&gt;
Ditto for Scala, though the idiom/pattern of function-literal-returning- function-literal isn&apos;t always quite this obvious in Scala:
&lt;pre&gt;&lt;code&gt;  def constructorFunction() = {
    def makeWithdraw(bal : Int) = {
      var balance = bal
      (amt : Int) =&amp;gt; {
        if (balance &amp;gt;= amt) {
          balance = (balance - amt) 
          balance
        }
        else 
          throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
      }
    }
    val acctForEugene = makeWithdraw(100)
    println(acctForEugene(20))
    val acctForTed = makeWithdraw(1000)
    println(acctForTed(20))
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;f-3&quot;&gt;F#:&lt;/h3&gt;
Really, not any different from the other languages: a function binding that returns a function, with the passed-in &quot;balance&quot; captured as a reference (see the earlier pattern element discussion for why it&apos;s a ref) inside the outer function scope, and used from the inner function scope.
&lt;pre&gt;&lt;code&gt;let constructorFunction = fun () -&amp;gt;
    let makeAccount =
        fun bal -&amp;gt;
            let balance = ref bal
            fun amt -&amp;gt;
                if amt &amp;lt;= !balance then
                    balance := (!balance) - amt
                    !balance
                else
                    raise (Exception(&amp;quot;Insufficient funds&amp;quot;))                
            
    Console.WriteLine &amp;quot;=========&amp;gt; Constructor Function&amp;quot;
    let acctForEugene = makeAccount 100
    printfn &amp;quot;%d&amp;quot; (acctForEugene 20)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;yeti-ml-2&quot;&gt;Yeti (ML):&lt;/h3&gt;
Same exercise--a function binding that returns a function, with the passed-in &quot;balance&quot; stored as a variable (var) inside the outer function scope, such that it is closed over by the inner function scope.
&lt;pre&gt;&lt;code&gt;makeWithdraw =
  (do bal:
    var balance = bal;
    do amt:
      if amt &amp;lt;= balance then
        balance := balance - amt;
        balance
      else
        throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
      fi
    done;
  done;);

acctForEugene = makeWithdraw 100;
println (acctForEugene 10);   // 90
println (acctForEugene 10);   // 80
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;jaskell-haskell-2&quot;&gt;Jaskell (Haskell):&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;c-3&quot;&gt;C#:&lt;/h3&gt;
The constructor function must be explicitly typed, again, but we gain a tiny bit of brevity by changing the &quot;delegate&quot; literals into (slightly) shorter C# lambdas:
&lt;pre&gt;&lt;code&gt;static void ConstructorFunction()
{
    Func&amp;lt;int,Func&amp;lt;int, int&amp;gt; makeAccount = 
        ((Func&amp;lt;int,Func&amp;lt;int,int&amp;gt;)( (bal) =&amp;gt; {
            var balance = bal;
            return (int amount) =&amp;gt;
            {
                if (balance &amp;gt;= amount)
                {
                    balance -= amount;
                    return balance;
                }
                else
                    throw new Exception(&amp;quot;Insufficient funds&amp;quot;);
            };
        }));

    Console.WriteLine(&amp;quot;=============&amp;gt; Closure&amp;quot;);
    var acctForEugene = makeAccount(100);
    Console.WriteLine(&amp;quot;{0}&amp;quot;, acctForEugene(20));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Were it not for the implicitly-typed local variable declaration syntax around &amp;quot;acctForEugene&amp;quot;, it would be acutely obvious that &amp;quot;makeAccount&amp;quot; isn&apos;t creating any kind of object at all, but a function to be executed. Even so, the explicit typing requirement for the lambdas is kind of annoying, and will only get worse as we move through the pattern language.&lt;/p&gt;
&lt;h2 id=&quot;method-selector&quot;&gt;Method Selector&lt;/h2&gt;
&quot;You are creating a Function as Object using a Closure. A Constructor Function creates new instances of the object. How do you provide shared access to the closure&apos;s state?&quot; After all, an account can do more than just withdraw, but all of the operations on the account have to share the same state--the account balance--without violating encapsulation.
&lt;h3 id=&quot;scheme-3&quot;&gt;Scheme:&lt;/h3&gt;
Again we see the nested lambdas, but now there&apos;s a third level of nesting; the first invocation (make-account) returns a second invocation that will take a single string, switch on the string, and return a third lambda that will do the actual work of manipulating the balance.
&lt;pre&gt;&lt;code&gt;(define make-account
  (lambda (balance)
    (lambda (transaction)
      (case transaction
        (&apos;withdraw
          (lambda (amount)
            (if (&amp;gt;= balance amount)
              (begin
                (set! balance (- balance amount)
                balance)
              (error &amp;quot;Insufficient funds&amp;quot; balance)))))
        (&apos;deposit
          (lambda (amount)
            (set! balance (+ balance amount))
            balance))
        (&apos;balance
          (lambda ()
            balance))
        (else
          (error &amp;quot;Unknown request -- ACCOUNT&amp;quot;
            transaction))))
  ))
(define account-for-eugene (make-account 100))
((account-for-eugene &apos;withdraw) 10)  =&amp;gt; 90
((account-for-eugene &apos;withdraw) 10)  =&amp;gt; 80
((account-for-eugene &apos;deposit) 100)  =&amp;gt; 180
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;javascript-4&quot;&gt;JavaScript:&lt;/h3&gt;
Doing this in JavaScript is, again, straightforward, though it does seem a little too subtle for idiomatic JavaScript:
&lt;pre&gt;&lt;code&gt;(function() {
  out(&amp;quot;methodSelector ========&amp;quot;)

  var makeAccount = function(bal) {
    var balance = bal
    return function(transaction) {
      if (transaction === &amp;quot;withdraw&amp;quot;) {
        return function(amount) {
          if (balance &amp;gt;= amount)
            return (balance = (balance - amount))
          else
            throw new Error(&amp;quot;Insufficient funds&amp;quot;)
        }
      }
      else if (transaction === &amp;quot;deposit&amp;quot;) {
        return function(amount) {
          return (balance = (balance + amount))
        }
      }
      else if (transaction === &amp;quot;balance&amp;quot;) {
        return function() {
          return balance
        }
      }
      else {
        throw new Error(&amp;quot;Insufficient funds&amp;quot;)
      }
    }
  }
  var acctForEugene = makeAccount(100)
  out(acctForEugene(&amp;quot;withdraw&amp;quot;)(20))
  out(acctForEugene(&amp;quot;balance&amp;quot;)())
})();
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;scala-4&quot;&gt;Scala:&lt;/h3&gt;
This style of interface--passing in a string and a variable list of arguments--really isn&apos;t quite Scala&apos;s style, since (being a strongly- typed language) it prefers to be able to compile-time-check as much as it can, but that doesn&apos;t mean we can&apos;t build it when the need and opportunity mesh:
&lt;pre&gt;&lt;code&gt;  def methodSelector() = {
    def makeAccount(bal : Int) = {
      var balance = bal
      (transaction : String) =&amp;gt; {
        transaction match {
          case &amp;quot;withdraw&amp;quot; =&amp;gt;
            (amt : Int) =&amp;gt; {
              if (balance &amp;gt;= amt) {
                balance = (balance - amt) 
                balance
              }
              else 
                throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
            }
          case &amp;quot;deposit&amp;quot; =&amp;gt; {
            (amt : Int) =&amp;gt; {
              balance += amt
              balance
            }
          }
          case _ =&amp;gt; 
            throw new RuntimeException(&amp;quot;Unknown request&amp;quot;)
        }
      }
    }
    val acctForEugene = makeAccount(100)
    println(acctForEugene(&amp;quot;deposit&amp;quot;)(50))
    val acctForTed = makeAccount(100)
    println(acctForTed(&amp;quot;withdraw&amp;quot;)(50))
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;f-4&quot;&gt;F#:&lt;/h3&gt;
This is, again, like the Yeti version and the Scala version, going to require some sacrifice in terms of flexibility in order to stay true to the original Scheme version--in F#, like in Scala and other statically-typed languages, we have to make sure that all branches of a pattern-match yield the same type of result, so the &quot;balance&quot; branch has to yield a function that takes a parameter (and it must be of the same type of parameter as the other two branches), even though &quot;balance&quot; never makes use of it. This also means that when calling the return value from &quot;makeAccount&quot;, even for balance, we have to pass along some parameter that will be ignored.
&lt;pre&gt;&lt;code&gt;let methodSelector = fun () -&amp;gt;
    let makeAccount =
        fun (bal : int) -&amp;gt;
            let balance = ref bal
            fun transaction -&amp;gt;
                match transaction with
                | &amp;quot;balance&amp;quot; -&amp;gt;
                    fun _ -&amp;gt; !balance
                | &amp;quot;deposit&amp;quot; -&amp;gt;
                    fun (amt : int) -&amp;gt;
                        balance := (!balance) + amt
                        !balance
                | &amp;quot;withdraw&amp;quot; -&amp;gt;
                    fun (amt : int) -&amp;gt;
                        if amt &amp;lt;= !balance then
                            balance := (!balance) - amt
                            !balance
                        else
                            raise (Exception(&amp;quot;Insufficient funds&amp;quot;))
                | _ -&amp;gt;
                    raise (Exception(&amp;quot;Unrecognized operation&amp;quot; + transaction))
                            
    Console.WriteLine &amp;quot;=========&amp;gt; Method Selector&amp;quot;
    let acctForEugene = makeAccount 100
    printfn &amp;quot;%d&amp;quot; ((acctForEugene &amp;quot;withdraw&amp;quot;) 20)
    printfn &amp;quot;%d&amp;quot; ((acctForEugene &amp;quot;balance&amp;quot;) 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can address this required-uniformity-of-access a little bit more consistently with the next pattern element, but whether it&apos;s an improvement is debatable.&lt;/p&gt;
&lt;h3 id=&quot;yeti-ml-3&quot;&gt;Yeti (ML):&lt;/h3&gt;
Nothing new here: the makeAccount function now nests three function literals, just like the JavaScript and Scala ones do. Like the other languages, we use a pattern-match/switch-case construct to decide between the different action strings (&quot;deposit&quot;, &quot;withdraw&quot;, &quot;balance&quot;) and then return the appropriate function literal for further execution. Note that Yeti, like JavaScript, actually has a way of returning an &quot;object&quot; here (a structure, which is a data type the contains one or more named fields, a la objects in JavaScript or case classes in Scala), but since the goal is to remain as faithful as possible to the original Scheme implementation, I stick with the more &quot;functional-only&quot; approach.
&lt;pre&gt;&lt;code&gt;makeAccount =
  (do bal:
    var balance = bal;
    do action:
      case action of
        &amp;quot;withdraw&amp;quot;: 
          do amt:
            if amt &amp;lt;= balance then
              balance := balance - amt;
              balance
            else
              throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
            fi
          done;
        &amp;quot;deposit&amp;quot;: 
          do amt: 
            balance := balance + amt;
            balance;
          done;
        &amp;quot;balance&amp;quot;: 
          do: 
            balance; 
          done;
        _ : throw new RuntimeException(&amp;quot;Unknown operation&amp;quot;)
      esac
    done;
  done;);

acctForEugene = makeAccount 100;
println ((acctForEugene &amp;quot;withdraw&amp;quot;) 20);
println ((acctForEugene &amp;quot;deposit&amp;quot;) 20);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;jaskell-haskell-3&quot;&gt;Jaskell (Haskell):&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;c-4&quot;&gt;C#:&lt;/h3&gt;
If you stopped reading right here, I wouldn&apos;t blame you; this is some ugly C#, without question, particularly considering that there are other ways to accomplishing this same effect without requiring quite so much nesting.
&lt;pre&gt;&lt;code&gt;static void MethodSelector()
{
    Func&amp;lt;int, Func&amp;lt;string, Func&amp;lt;int, int&amp;gt; makeAccount =
        ((Func&amp;lt;int, Func&amp;lt;string, Func&amp;lt;int, int&amp;gt;)((bal) =&amp;gt;
        {
            var balance = bal;
            return (string transaction) =&amp;gt;
                {
                    switch (transaction)
                    {
                        case &amp;quot;deposit&amp;quot;:
                            return (int amount) =&amp;gt;
                                {
                                    if (balance &amp;gt;= amount)
                                    {
                                        balance -= amount;
                                        return balance;
                                    }
                                    else
                                        throw new Exception(&amp;quot;Insufficient funds&amp;quot;);
                                };
                        case &amp;quot;withdraw&amp;quot;:
                            return (int amount) =&amp;gt;
                                {
                                    balance += amount;
                                    return balance;
                                };
                        case &amp;quot;balance&amp;quot;:
                            return (int unused) =&amp;gt;
                                {
                                    return balance;
                                };
                        default:
                            throw new Exception(&amp;quot;Illegal operation&amp;quot;);
                    }
                };
        }));
    Console.WriteLine(&amp;quot;=============&amp;gt; MethodSelector&amp;quot;);
    var acctForEugene = makeAccount(100);
    Console.WriteLine(&amp;quot;{0}&amp;quot;, acctForEugene(&amp;quot;deposit&amp;quot;)(20));
    Console.WriteLine(&amp;quot;{0}&amp;quot;, acctForEugene(&amp;quot;withdraw&amp;quot;)(20));
    Console.WriteLine(&amp;quot;{0}&amp;quot;, acctForEugene(&amp;quot;balance&amp;quot;)(0));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bear in mind, too, that there are some other ways to accomplish what the C# code here tries to do, one using dynamic types (from 4.0):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;static void MethodSelector2()
{
    Func&amp;lt;int, dynamic&amp;gt; makeAccount = (int bal) =&amp;gt;
    {
        var balance = bal;
        dynamic result = new System.Dynamic.ExpandoObject();
        result.withdraw = (Func&amp;lt;int, int&amp;gt;)((amount) =&amp;gt; {
            if (balance &amp;gt;= amount)
            {
                balance -= amount;
                return balance;
            }
            else
                throw new Exception(&amp;quot;Insufficient funds&amp;quot;);
        });
        result.deposit = (Func&amp;lt;int, int&amp;gt;)((amount) =&amp;gt;
        {
            balance += amount;
            return balance;
        });
        result.balance = (Func&amp;lt;int&amp;gt;)(() =&amp;gt; balance);
        return result;
    };

    Console.WriteLine(&amp;quot;=============&amp;gt; MethodSelector2&amp;quot;);
    var acctForEugene = makeAccount(100);
    Console.WriteLine(&amp;quot;{0}&amp;quot;, acctForEugene.deposit(20));
    Console.WriteLine(&amp;quot;{0}&amp;quot;, acctForEugene.balance());
    var acctForTed = makeAccount(100);
    Console.WriteLine(&amp;quot;{0}&amp;quot;, acctForTed.withdraw(10));
    Console.WriteLine(&amp;quot;{0}&amp;quot;, acctForTed.balance());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... or even using ye old plain ol&apos; Dictionary type, taking a string as a key and yielding Func&amp;lt;&amp;gt; as values for execution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;static void MethodSelector3()
{
    Func&amp;lt;int, Dictionary&amp;lt;string,Func&amp;lt;int,int&amp;gt; makeAccount = 
    (int bal) =&amp;gt;
    {
        var balance = bal;
        var result = new Dictionary&amp;lt;string, Func&amp;lt;int,int&amp;gt;();
        result[&amp;quot;withdraw&amp;quot;] = (Func&amp;lt;int, int&amp;gt;)((amount) =&amp;gt;
        {
            if (balance &amp;gt;= amount)
            {
                balance -= amount;
                return balance;
            }
            else
                throw new Exception(&amp;quot;Insufficient funds&amp;quot;);
        });
        result[&amp;quot;deposit&amp;quot;] = (Func&amp;lt;int, int&amp;gt;)((amount) =&amp;gt;
        {
            balance += amount;
            return balance;
        });
        result[&amp;quot;balance&amp;quot;] = (Func&amp;lt;int, int&amp;gt;)((unused) =&amp;gt; balance);
        return result;
    };

    Console.WriteLine(&amp;quot;=============&amp;gt; MethodSelector3&amp;quot;);
    var acctForEugene = makeAccount(100);
    Console.WriteLine(&amp;quot;{0}&amp;quot;, acctForEugene[&amp;quot;deposit&amp;quot;](20));
    Console.WriteLine(&amp;quot;{0}&amp;quot;, acctForEugene[&amp;quot;balance&amp;quot;](0));
    var acctForTed = makeAccount(100);
    Console.WriteLine(&amp;quot;{0}&amp;quot;, acctForTed[&amp;quot;withdraw&amp;quot;](10));
    Console.WriteLine(&amp;quot;{0}&amp;quot;, acctForTed[&amp;quot;balance&amp;quot;](0));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The second of these two is closer to strict intent of Method Selector from the Scheme example, but the first allows for flexible arity (numbers of parameters) in the functions handed back when dereferenced (so that &amp;quot;balance&amp;quot; doesn&apos;t have to take a bogus unused parameter). Frankly, had I to choose, I&apos;d probably go with the dynamic version, just because of that flexibility.&lt;/p&gt;
&lt;h2 id=&quot;message-passing-interface&quot;&gt;Message-Passing Interface&lt;/h2&gt;
&quot;You have created a Method Selector for a Function as Object. You prefer to use your object in code that has an object-oriented feel. How do you invoke the methods of an object? [P]rovide a simple message-passing interface for using the closure.&quot;
&lt;h3 id=&quot;scheme-4&quot;&gt;Scheme:&lt;/h3&gt;
Everything in a Lisp is a list, and the Scheme implementation uses that to full effect by taking the argument list passed in to &quot;send&quot; and splits it up into the object (the account), message (withdraw/deposit/etc), and the arguments (if any) that are left.
&lt;pre&gt;&lt;code&gt;(define send
  (lambda argument-list
    (let ((object  (car argument-list))
          (message (car (cdr argument-list)))
          (args    (cdr (cdr argument-list))))
      (apply (get-method object message) args))
  ))
(define get-method
  (lambda (object selector)
    (object selector)
  ))
(define account-for-eugene (make-account 100))
(send account-for-eugene &apos;withdraw 50)  =&amp;gt; 50
(send account-for-eugene &apos;deposit 100)  =&amp;gt; 150
(send account-for-eugene &apos;balance)      =&amp;gt; 150
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;javascript-5&quot;&gt;JavaScript:&lt;/h3&gt;
In JavaScript, peeling off the head and tail of the arguments reference is trickier here, because unlike Scheme, JavaScript sees &quot;arguments&quot; as an array, not a list. While I could&apos;ve created &quot;car&quot; and &quot;cdr&quot; functions in JavaScript to perform the relevant operations on an array, it felt more idiomatic to provide a function &quot;slice&quot; to do the &quot;slicing&quot; (which is actually a copy) of elements off the end of the array instead. More importantly, &quot;slice&quot; is a primitive method on Array objects in ECMAScript 5, though neither Node nor Rhino in Java 6 recognize it (I suspect because neither is a compliant ECMAScript 5 environment yet), and if this code ever gets run in a ECMAScript 5 world, then it would/should use that version, instead, since it&apos;ll likely be faster than mine.
&lt;p&gt;The other interesting tidbit in here is that when I wrote it the first time, when doing a deposit, the &amp;quot;balance&amp;quot; became &amp;quot;8020&amp;quot;, instead of the mathematically-correct &amp;quot;100&amp;quot;. JavaScript&apos;s &amp;quot;promiscuous typing&amp;quot; thought that the &amp;quot;+&amp;quot; operator wanted to do a string concatenation, instead of a mathematical add of two numbers, so I had to convince it that the value coming out of arguments[1] was, in fact, a number, and the easiest way (it seemed to me at the time) was to just do a quick redundant math operation on it (multiply by 10, then divide by 10 again). There&apos;s likely a more idiomatic way to do that, I suspect.&lt;/p&gt;
&lt;p&gt;I also note that getMethod() in JavaScript is a bit unnecessary; we could inline its functionality directly inside of send().&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(function() {
  out(&amp;quot;messagePassingInterface ========&amp;quot;)

  var slice = function(src, start, end) {
    var returnVal = []
    var j = 0
    if (end === undefined)
      end = src.length
    for (var i = start; i &amp;lt; end; i++) {
      if (src.length &amp;gt; i)
        returnVal[j++] = src[i]
    }
    return returnVal;
  }
  
  var makeAccount = function(bal) {
    var balance = bal
    return function(transaction) {
      if (transaction === &amp;quot;withdraw&amp;quot;) {
        return function(amount) {
          if (balance &amp;gt;= amount)
            return (balance = (balance - amount))
          else
            throw new Error(&amp;quot;Insufficient funds&amp;quot;)
        }
      }
      else if (transaction === &amp;quot;deposit&amp;quot;) {
        return function(amount) {
          return (balance = (balance + (amount * 10.0 / 10.0)))
        }
      }
      else if (transaction === &amp;quot;balance&amp;quot;) {
        return function() {
          return balance
        }
      }
      else {
        throw new Error(&amp;quot;Insufficient funds&amp;quot;)
      }
    }
  }
  var getMethod = function(object, selector) {
    return object(selector)
  }
  var send = function(object, message) {
    return (getMethod(object, message))(slice(arguments, 2))
  }
  var acctForEugene = makeAccount(100)
  out(send(acctForEugene, &amp;quot;withdraw&amp;quot;, 20)) // 80
  out(send(acctForEugene, &amp;quot;balance&amp;quot;))      // 80
  out(send(acctForEugene, &amp;quot;deposit&amp;quot;, 20))  // 100
  out(send(acctForEugene, &amp;quot;balance&amp;quot;))      // 100
})();
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;scala-5&quot;&gt;Scala:&lt;/h3&gt;
The Scala version of this follows the JavaScript version in that it works off of a variable-argument list, but since Scala doesn&apos;t give us the built-in &quot;arguments&quot; reference, we have to specify it at the method declaration:
&lt;pre&gt;&lt;code&gt;  def messagePassingInterface() = {
    def makeAccount(bal : Int) = {
      var balance = bal
      def send(key:String, args:Any*) = {
        key match {
          case &amp;quot;withdraw&amp;quot; =&amp;gt; {
            val amt = args.head.asInstanceOf[Int]
            if (balance &amp;gt;= amt) {
              balance = (balance - amt) 
              balance
            }
            else 
              throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
          }
          case &amp;quot;deposit&amp;quot; =&amp;gt; {
            val amt = args.head.asInstanceOf[Int]
            balance += amt
            balance
          }
        }
      }
      send _
    }
    val acctForEugene = makeAccount(100)
    println(acctForEugene(&amp;quot;withdraw&amp;quot;, 10))
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;f-5&quot;&gt;F#:&lt;/h3&gt;
By now taking an &quot;obj list&quot; for the parameters, we unify all of the calls to the account to take a consistent parameter list that still allows for a flexible number of parameters, but.... It still requires that callers that don&apos;t want to pass any arguments have to pass an empty list. And, on top of that, it doesn&apos;t really feel &quot;F#-ish&quot;.
&lt;pre&gt;&lt;code&gt;let messagePassingInterface = fun () -&amp;gt;
    let makeAccount =
        fun (bal : int) -&amp;gt;
            let balance = ref bal
            fun transaction -&amp;gt;
                match transaction with
                | &amp;quot;balance&amp;quot; -&amp;gt;
                    fun _ -&amp;gt; !balance
                | &amp;quot;deposit&amp;quot; -&amp;gt;
                    fun (arglist : obj list) -&amp;gt;
                        let amt = arglist.Head :?&amp;gt; int
                        balance := (!balance) + amt
                        !balance
                | &amp;quot;withdraw&amp;quot; -&amp;gt;
                    fun (arglist : obj list) -&amp;gt;
                        let amt = arglist.Head :?&amp;gt; int
                        if amt &amp;lt;= !balance then
                            balance := (!balance) - amt
                            !balance
                        else
                            raise (Exception(&amp;quot;Insufficient funds&amp;quot;))
                | _ -&amp;gt;
                    raise (Exception(&amp;quot;Unrecognized operation&amp;quot; + transaction))
    let getMethod = fun (acct : string -&amp;gt; obj list -&amp;gt; int) selector -&amp;gt; acct selector
    let send = 
        fun (acct : string -&amp;gt; obj list -&amp;gt; int) (message : string) (arglist : obj list) -&amp;gt;
            (getMethod acct message)(arglist)

    Console.WriteLine &amp;quot;=========&amp;gt; Message Passing Interface&amp;quot;
    let acctForEugene = makeAccount 100
    printfn &amp;quot;%d&amp;quot; (send acctForEugene &amp;quot;withdraw&amp;quot; [20])
    printfn &amp;quot;%d&amp;quot; (send acctForEugene &amp;quot;balance&amp;quot; [])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that F# does have language facilities for allowing a &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd233213.aspx&quot;&gt;variable-argument list&lt;/a&gt; to be passed, but it only works on method members:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// From the MSDN documentation
open System

type X() =
    member this.F([&amp;lt;ParamArray&amp;gt;] args: Object[]) =
        for arg in args do
            printfn &amp;quot;%A&amp;quot; arg

[&amp;lt;EntryPoint&amp;gt;]
let main _ =
    // call a .NET method that takes a parameter array, passing values of various types
    Console.WriteLine(&amp;quot;a {0} {1} {2} {3} {4}&amp;quot;, 1, 10.0, &amp;quot;Hello world&amp;quot;, 1u, true)

    let xobj = new X()
    // call an F# method that takes a parameter array, passing values of various types
    xobj.F(&amp;quot;a&amp;quot;, 1, 10.0, &amp;quot;Hello world&amp;quot;, 1u, true)
    0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We could go back and rewrite all of the F# samples to be class member methods (that is, return actual objects), but that sort of gets away from the spirit of what the blog exercise is trying to do, so I&apos;ll leave that as an exercise to the reader. (Which, by the way, is author-speak for &amp;quot;I&apos;m feeling lazy and I don&apos;t want to bother&amp;quot;.)&lt;/p&gt;
&lt;h3 id=&quot;yeti-ml-4&quot;&gt;Yeti (ML):&lt;/h3&gt;
Unfortunately, while Yeti (like most functional languages) has a built-in list type, it doesn&apos;t recognize arguments to a function as a list, so we either have to explicitly put the arguments in, or we have to explicitly state that the arguments to the returned function literal are a list. I choose the latter tactic, even though it&apos;s not the world&apos;s most impressive syntax:
&lt;pre&gt;&lt;code&gt;makeAccount =
  (do bal:
    var balance = bal;
    do action:
      case action of
        &amp;quot;withdraw&amp;quot;:
          do argList:
            amt = head argList;
            if amt &amp;lt;= balance then
              balance := balance - amt;
              balance;
            else
              throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
            fi
          done;
        &amp;quot;deposit&amp;quot;: 
          do argList:
            amt = head argList; 
            balance := balance + amt;
            balance;
          done;
        &amp;quot;balance&amp;quot;: 
          do: 
            balance; 
          done;
        _ : throw new RuntimeException(&amp;quot;Unknown operation&amp;quot;)
      esac
    done;
  done;);

acctForEugene = makeAccount 100;
println  ((acctForEugene &amp;quot;withdraw&amp;quot;)[20]);  // 80
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If there&apos;s a way to get a Yeti function to accept a variable number of arguments, I&apos;ve not seen it in the language overview. I don&apos;t know if any ML-derivative has this, to be honest. Of course, the other thing to do, since this is a statically-typed environment, is to just return function literals that expect the proper number of arguments, which will get us the compile-time safety that these languages are supposed to provide; the below does exactly that--the last line will fail to compile if you uncomment it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;makeAccount =
  (do bal:
    var balance = bal;
    do action:
      case action of
        &amp;quot;withdraw&amp;quot;:
          do amt:
            if amt &amp;lt;= balance then
              balance := balance - amt;
              balance;
            else
              throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
            fi
          done;
        &amp;quot;deposit&amp;quot;: 
          do amt:
            balance := balance + amt;
            balance;
          done;
        &amp;quot;balance&amp;quot;: 
          do: 
            balance; 
          done;
        _ : throw new RuntimeException(&amp;quot;Unknown operation&amp;quot;)
      esac
    done;
  done;);

acctForEugene = makeAccount 100;
println ((acctForEugene &amp;quot;withdraw&amp;quot;) 20);      // 80
println ((acctForEugene &amp;quot;balance&amp;quot;) 0);        // 80
//println ((acctForEugene &amp;quot;withdraw&amp;quot;) &amp;quot;fred&amp;quot;);  // won&apos;t compile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Truthfully, we should do this for the Scala version, too.) This choice is going to cause us a little bit of heartache, though, because in order to use &amp;quot;balance&amp;quot;, we have to pass in a number--if we leave off the &amp;quot;_&amp;quot; in the function literal returned from the &amp;quot;balance&amp;quot; arm of the selector, we don&apos;t need to pass &amp;quot;0&amp;quot; when we invoke it, but what&apos;s returned isn&apos;t a number, but a function. I can&apos;t figure out how to make Yeti take that function and just invoke it--the syntax guide doesn&apos;t seem to say out loud exactly how I can invoke that function without having to pass in a number argument. If I&apos;d left it as taking a list, then I could pass an empty list and all would look consistent, if a little weird.&lt;/p&gt;
&lt;p&gt;(Note that this is deliberately opposite what I chose to do for the F# version.)&lt;/p&gt;
&lt;h3 id=&quot;jaskell-haskell-4&quot;&gt;Jaskell (Haskell):&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;c-5&quot;&gt;C#:&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;generic-function&quot;&gt;Generic Function&lt;/h2&gt;
&quot;You have created a Method Selector for a Function as Object. You want to take full advantage of the tools available in your functional language. How do you invoke the methods of an object? ... [P]rovide a simple interface to the Method Selector that more closely follows the functional style.&quot;
&lt;h3 id=&quot;scheme-5&quot;&gt;Scheme:&lt;/h3&gt;
In the Scheme implementation, it&apos;s interesting that having written the send function in the last element of the pattern language, we don&apos;t really use it here, but instead just inline its functionality in each of the named functions (which, in turn, take the argument list, peel off the head of the argument list as the account object, and pass the remainder of the arguments on to the selected function):
&lt;pre&gt;&lt;code&gt;(define withdraw
  (lambda argument-list
    (let ((object (car argument-list))
          (withdraw-arguments (cdr argument-list)))
      (apply (object &apos;withdraw) withdraw-arguments)
    )))
(define deposit
  (lambda argument-list
    (let ((object (car arguments))
          (deposit-arguments (cdr arguments)))
      (apply (object &apos;deposit) deposit-arguments)
    )))
(define balance
  (lambda (object)
    (object &apos;balance)
  ))
  
(define account-for-eugene (make-account 100))
(withdraw account-for-eugene 10)
(map  (lambda (account) (deposit account 10)) account-for-eugene)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Interestingly enough, I sort of expected the Scheme version to use &amp;quot;deposit&amp;quot; directly, rather than write a trampoline that calls &amp;quot;deposit&amp;quot;, since we could&apos;ve avoided the Generic Function part of the language just by using &amp;quot;send&amp;quot; directly, as well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(map  (lambda (account) (send account &apos;deposit 10)) account-for-eugene)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And, to be honest, calling &amp;quot;map&amp;quot; on a single object doesn&apos;t really seem to be a profoundly functional experience, so in my examples I&apos;m going to create a collection of accounts (called a &amp;quot;bank&amp;quot;, naturally enough), and map across that collection.&lt;/p&gt;
&lt;h3 id=&quot;javascript-6&quot;&gt;JavaScript:&lt;/h3&gt;
The JavaScript version of this is, again, pretty similar to the Scheme version. Again, ECMAScript 5 environments are supposed to have a &quot;map&quot; function natively built in, but previous environments don&apos;t, so I have to write one to verify that we can, in fact, use the named functions as the mapped operation. I also write a &quot;map2&quot;, another version of map that takes the function to apply to the collection but also takes any additional arguments after that and passes them to the function being applied across the collection; it allows me to use &quot;deposit&quot; directly, instead of having to write a trampoline for it, and besides, it&apos;s trivial to write in JavaScript:
&lt;pre&gt;&lt;code&gt;(function() {
  out(&amp;quot;genericFunction ==============&amp;quot;)

  var slice = function(src, start, end) {
    var returnVal = []
    var j = 0
    if (end === undefined)
      end = src.length
    for (var i = start; i &amp;lt; end; i++) {
      if (src.length &amp;gt; i)
        returnVal[j++] = src[i]
    }
    return returnVal
  }
  
  var map = function(fn, src) {
    var retVal = []
    for (i in src)
      retVal[i] = fn(src[i])
    return retVal
  }
  var map2 = function(src, fn) {
    var retVal = []
    for (i in src)
      retVal[i] = fn(src[i], slice(arguments, 2))
    return retVal
  }
  
  var makeAccount = function(bal) {
    var balance = bal
    return function(transaction) {
      if (transaction === &amp;quot;withdraw&amp;quot;) {
        return function(amount) {
          if (balance &amp;gt;= amount)
            return (balance = (balance - amount))
          else
            throw new Error(&amp;quot;Insufficient funds&amp;quot;)
        }
      }
      else if (transaction === &amp;quot;deposit&amp;quot;) {
        return function(amount) {
          return (balance = (balance + (amount * 10.0 / 10.0)))
        }
      }
      else if (transaction === &amp;quot;balance&amp;quot;) {
        return function() {
          return balance
        }
      }
      else {
        throw new Error(&amp;quot;Insufficient funds&amp;quot;)
      }
    }
  }
  var withdraw = function() {
    var object = arguments[0]
    var argumentList = slice(arguments, 1)
    return object(&amp;quot;withdraw&amp;quot;)(argumentList)
  }
  var deposit = function() {
    var object = arguments[0]
    var argumentList = slice(arguments, 1)
    return object(&amp;quot;deposit&amp;quot;)(argumentList)
  }
  var balance = function(object) {
    return object(&amp;quot;balance&amp;quot;)()
  }

  var acctForEugene = makeAccount(100)
  out(withdraw(acctForEugene, 20))
  out(deposit(acctForEugene, 20))
  
  var bank = [
    makeAccount(100),  // acctForEugene
    makeAccount(1000)  // acctForTed
  ]
  map(function(it) { deposit(it, 20) }, bank)
  out(balance(bank[0]))
  out(balance(bank[1]))
  
  map2(bank, deposit, 20)
  out(balance(bank[0]))
  out(balance(bank[1]))
})();
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;scala-6&quot;&gt;Scala:&lt;/h3&gt;
Scala, of course, has functional methods built onto its List type (which we can use instead of an array, since Scala has much better support for lists than arrays):
&lt;pre&gt;&lt;code&gt;  def genericFunction() = {
    def makeAccount(bal : Int) = {
      var balance = bal
      def send(key:String, args:Any*) = {
        key match {
          case &amp;quot;withdraw&amp;quot; =&amp;gt; {
            val amt = args.head.asInstanceOf[Int]
            if (balance &amp;gt;= amt) {
              balance = (balance - amt) 
              balance
            }
            else 
              throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
          }
          case &amp;quot;deposit&amp;quot; =&amp;gt; {
            val amt = args.head.asInstanceOf[Int]
            balance += amt
            balance
          }
          case &amp;quot;balance&amp;quot; =&amp;gt; {
            balance
          }
          case _ =&amp;gt;
            throw new RuntimeException(&amp;quot;Unknown request&amp;quot;)
        }
      }
      send _
    }
    def withdraw(account : (String, Any*) =&amp;gt; Int, amount : Int) = {
      account(&amp;quot;withdraw&amp;quot;, amount)
    }
    def deposit(account : (String, Any*) =&amp;gt; Int, amount : Int) = {
      account(&amp;quot;deposit&amp;quot;, amount)
    }
    def balance(account : (String, Any*) =&amp;gt; Int) = {
      account(&amp;quot;balance&amp;quot;)
    }
    val accounts = List(makeAccount(100), makeAccount(200), makeAccount(300))
    accounts.foreach(withdraw(_, 20))
    accounts.foreach((in) =&amp;gt; { println(balance(in)) })
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;f-6&quot;&gt;F#:&lt;/h3&gt;
The F# version helps clean up some of the syntax a little, sort of:
&lt;pre&gt;&lt;code&gt;let genericFunction = fun () -&amp;gt;
    let makeAccount =
        fun (bal : int) -&amp;gt;
            let balance = ref bal
            fun transaction -&amp;gt;
                match transaction with
                | &amp;quot;balance&amp;quot; -&amp;gt;
                    fun _ -&amp;gt; !balance
                | &amp;quot;deposit&amp;quot; -&amp;gt;
                    fun (arglist : obj list) -&amp;gt;
                        let amt = arglist.Head :?&amp;gt; int
                        balance := (!balance) + amt
                        !balance
                | &amp;quot;withdraw&amp;quot; -&amp;gt;
                    fun (arglist : obj list) -&amp;gt;
                        let amt = arglist.Head :?&amp;gt; int
                        if amt &amp;lt;= !balance then
                            balance := (!balance) - amt
                            !balance
                        else
                            raise (Exception(&amp;quot;Insufficient funds&amp;quot;))
                | _ -&amp;gt;
                    raise (Exception(&amp;quot;Unrecognized operation&amp;quot; + transaction))
    let deposit = 
        fun amt acct-&amp;gt;
            acct &amp;quot;deposit&amp;quot; [amt :&amp;gt; obj]
    let withdraw =
        fun amt acct -&amp;gt;
            acct &amp;quot;withdraw&amp;quot; [amt :&amp;gt; obj]
    let balance =
        fun acct -&amp;gt;
            acct &amp;quot;balance&amp;quot; []

    Console.WriteLine &amp;quot;=========&amp;gt; Generic Function&amp;quot;
    let bank = [ makeAccount 100; makeAccount 200; makeAccount 300 ]
    let balances = List.map (fun it -&amp;gt; deposit 20 it) bank
    List.iter (fun it -&amp;gt; printfn &amp;quot;%d&amp;quot; it) balances
    let balances = List.map (deposit 20) bank
    List.iter (printfn &amp;quot;%d&amp;quot;) balances
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that by putting the account counter-intuitively as the last parameter to the generic &amp;quot;deposit&amp;quot; and &amp;quot;withdraw&amp;quot; functions, we can avoid having to write the &amp;quot;trampoline&amp;quot; function that we would&apos;ve had to write when using &amp;quot;map&amp;quot;; the account gets curried from the List directly (as shown in the second example). We could do the same thing in the Scala version, too, and then wouldn&apos;t have to use the explicit &amp;quot;_&amp;quot; syntax that Scala provides. Of course, if the desire is instead to pass the amount in a curried fashion, instead of the account, then the original ordering of the parameters is better.&lt;/p&gt;
&lt;h3 id=&quot;yeti-ml-5&quot;&gt;Yeti (ML):&lt;/h3&gt;
Writing this in Yeti/ML is definitely trickier than it was in JavaScript, despite the built-in &quot;map&quot; and other functions, because getting the arguments to &quot;trampoline&quot; right is a little harder. Fortunately, the generic method hides the &quot;balance 0&quot; weirdness from the last pattern element, making it a tad easier to use:
&lt;pre&gt;&lt;code&gt;makeAccount =
  (do bal:
    var balance = bal;
    do action:
      case action of
        &amp;quot;withdraw&amp;quot;:
          do amt:
            if amt &amp;lt;= balance then
              balance := balance - amt;
              balance
            else
              throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
            fi
          done;
        &amp;quot;deposit&amp;quot;: 
          do amt:
            balance := balance + amt;
            balance
          done;
        &amp;quot;balance&amp;quot;: 
          do: 
            balance
          done;
        _ : throw new RuntimeException(&amp;quot;Unknown operation&amp;quot;)
      esac
    done;
  done;);

withdraw =
  (do acct amt:
    (acct &amp;quot;withdraw&amp;quot;) amt;
  done;);
deposit =
  (do acct amt:
    (acct &amp;quot;deposit&amp;quot;) amt;
  done;);
balance =
  (do acct:
    acct &amp;quot;balance&amp;quot; 0;
  done;);

acctForEugene = makeAccount 100;
println (withdraw acctForEugene 20);      // 80
println (deposit acctForEugene 20);       // 100
println (balance acctForEugene);          // 100

accounts = [(makeAccount 100), (makeAccount 200), (makeAccount 300)];
balances = map (do acct: (deposit acct 20) done) accounts;
for accounts do acct: println(deposit acct 20) done;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yeti complained if I didn&apos;t bind the result of the &amp;quot;map&amp;quot; call to a value, hence the &amp;quot;balances&amp;quot; value there, even though the balances are actually also stored in the relevant closures for each account. Note that the &amp;quot;for&amp;quot; line that follows it actually does the same thing, and prints the results out, to boot. In fact, it&apos;s high time people started to realize that the &amp;quot;for&amp;quot; loop in most imperative languages is just a non-functional way of doing a &amp;quot;map&amp;quot; without yielding a value. Languages like Scala and Yeti/ML essentially blur that line significantly enough to the point where we should just eschew &amp;quot;for&amp;quot; altogether and use &amp;quot;map&amp;quot;, if you ask me.&lt;/p&gt;
&lt;h3 id=&quot;jaskell-haskell-5&quot;&gt;Jaskell (Haskell):&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;c-6&quot;&gt;C#:&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;delegation&quot;&gt;Delegation&lt;/h2&gt;
&quot;You are creating a Function as Object. How do you create a new object that extends the behavior of an existing object? ... [U]se delegation. Make a Function as Object that has an instance variable an instance of the object you want to extend. Implement behaviors specific to the new object as methods in a Method Selector. Pass all other messages onto the instance variable.&quot;
&lt;p&gt;Again, in a traditional O-O language, we&apos;d just inherit, and in an object- functional hybrid, we could do the same. There&apos;s no real point not to, to be honest. But the interesting thing about this implementation is that it demonstrates the runtime relationship between a JavaScript object and its prototype: calling a function passing in the &amp;quot;derived&amp;quot; object causes the &amp;quot;derived&amp;quot; to try its &amp;quot;base&amp;quot; (its prototype) in the event that the method in question isn&apos;t defined on the &amp;quot;derived&amp;quot;.&lt;/p&gt;
&lt;p&gt;Note also that this particular trick is really only feasible because the &amp;quot;object&amp;quot; presents a uniform interface: all interaction with the &amp;quot;object&amp;quot; (whether it is a standard account or an interest-bearing one) is done through the Method Selector mechanism, which allows for this extension without having to modify any sort of base interface. This isn&apos;t so much a knock on O-O as a whole as it is on statically-typed traditional O-O.&lt;/p&gt;
&lt;h3 id=&quot;scheme-6&quot;&gt;Scheme:&lt;/h3&gt;
This is pretty straightforward, if you understood the Message-Passing Interface implementation of earlier.
&lt;pre&gt;&lt;code&gt;(define make-interest-bearing-account
  (lambda (balance interest-rate)
    (let ((my-account (make-account balance)))
      (lambda (transaction)
        (case transaction
          (&apos;accrue-interest
            (lambda ()
              ((my-account &apos;deposit)
                (* ((my-account &apos;balance))
                   interest-rate)) ))
        (else
          (my-account transaction))
        )))
  ))
(define account-for-eugene (make-interest-bearing-account 100 0.05))
((account-for-eugene &apos;balance))         =&amp;gt; 100
((account-for-eugene &apos;deposit) 100)     =&amp;gt; 200
((account-for-eugene &apos;balance))         =&amp;gt; 200
((account-for-eugene &apos;accrue-interest)) =&amp;gt; 210
((account-for-eugene &apos;balance))         =&amp;gt; 210
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;javascript-7&quot;&gt;JavaScript:&lt;/h3&gt;
Despite the fact that the JavaScript implementation just keeps getting longer and longer, it&apos;s actually not that much harder to add in this delegation functionality--again, as has been the case for a lot of the JavaScript code, it&apos;s almost a direct one-to-one port from the Scheme:
&lt;pre&gt;&lt;code&gt;(function() {
  out(&amp;quot;delegation =======&amp;quot;)
  
  var slice = function(src, start, end) {
    var returnVal = []
    var j = 0
    if (end === undefined)
      end = src.length
    for (var i = start; i &amp;lt; end; i++) {
      if (src.length &amp;gt; i)
        returnVal[j++] = src[i]
    }
    return returnVal
  }
  
  var makeAccount = function(bal) {
    var balance = bal
    return function(transaction) {
      if (transaction === &amp;quot;withdraw&amp;quot;) {
        return function(amount) {
          if (balance &amp;gt;= amount)
            return (balance = (balance - amount))
          else
            throw new Error(&amp;quot;Insufficient funds&amp;quot;)
        }
      }
      else if (transaction === &amp;quot;deposit&amp;quot;) {
        return function(amount) {
          return (balance = (balance + (amount * 10.0 / 10.0)))
        }
      }
      else if (transaction === &amp;quot;balance&amp;quot;) {
        return function() {
          return balance
        }
      }
      else {
        throw new Error(&amp;quot;Insufficient funds&amp;quot;)
      }
    }
  }
  var makeInterestBearingAccount = function(bal, intRate) {
    var myAccount = makeAccount(bal)
    return function(transaction) {
      if (transaction === &amp;quot;accrueInterest&amp;quot;) {
        return function() {
          var balance = myAccount(&amp;quot;balance&amp;quot;)()
          var interest = (balance * intRate)
          return myAccount(&amp;quot;deposit&amp;quot;)(interest)
        }
      }
      else
        return myAccount(transaction)
    }
  }
  
  var acctForEugene = makeInterestBearingAccount(100, 0.05)
  out(acctForEugene(&amp;quot;balance&amp;quot;)())
  out(acctForEugene(&amp;quot;deposit&amp;quot;)(20))
  out(acctForEugene(&amp;quot;accrueInterest&amp;quot;)())
  out(acctForEugene(&amp;quot;balance&amp;quot;)())
})();
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;scala-7&quot;&gt;Scala:&lt;/h3&gt;
The Scala version of this is tricky, because it relies on a very subtle bit of Scala syntax; specifically, when we try to pass the &quot;args&quot; sequence (which, in actual implementation, is a WrappedArray) from the &quot;makeInterestBearingAccount&quot; function to the &quot;makeAccount&quot; function (by which I mean, the functions returned from those two functions), if we don&apos;t use the peculiar &quot;: _*&quot; syntax, Scala interprets &quot;args&quot; to be a single parameter (a single parameter whose type is a collection), instead of the intended &quot;pass the arguments through&quot; behavior. (If you&apos;re a Java or C# developer, it&apos;s like having a varargs method calling another varargs method, and passing the array of arguments from the first as an array instead of each element on its own to form the array of arguments in the second. Yeah, I know--it&apos;s a little brain-twisty.)
&lt;pre&gt;&lt;code&gt;  def delegation() = {
    def makeAccount(bal : Int) = {
      var balance = bal
      def send(key:String, args:Any*) = {
        key match {
          case &amp;quot;withdraw&amp;quot; =&amp;gt; {
            val amt = args.head.asInstanceOf[Int]
            if (balance &amp;gt;= amt) {
              balance = (balance - amt) 
              balance
            }
            else 
              throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
          }
          case &amp;quot;deposit&amp;quot; =&amp;gt; {
            val amt = args.head.asInstanceOf[Int]
            balance += amt
            balance
          }
          case &amp;quot;balance&amp;quot; =&amp;gt; {
            balance
          }
          case _ =&amp;gt;
            throw new RuntimeException(&amp;quot;Unknown request&amp;quot;)
        }
      }
      send _
    }
    def makeInterestBearingAccount(bal : Int, intRate : Double) = {
      val account = makeAccount(bal)
      def send(key: String, args:Any*) = {
        key match {
          case &amp;quot;accrueInterest&amp;quot; =&amp;gt; {
            val amt = (int2float(account(&amp;quot;balance&amp;quot;)) * intRate).toInt
            account(&amp;quot;deposit&amp;quot;, amt)
          }
          case _ =&amp;gt;
            account(key, args : _*)
        }
      }
      send _
    }
    val acctForEugene = makeInterestBearingAccount(100, 0.05)
    println(acctForEugene(&amp;quot;deposit&amp;quot;, 20))
    println(acctForEugene(&amp;quot;accrueInterest&amp;quot;))
    println(acctForEugene(&amp;quot;balance&amp;quot;))
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;f-7&quot;&gt;F#:&lt;/h3&gt;
Aside from the aforementioned weirdness about the obj list as a generic parameter mechanism, this is really straightforward:
&lt;pre&gt;&lt;code&gt;let delegation = fun () -&amp;gt;
    let makeAccount =
        fun (bal : int) -&amp;gt;
            let balance = ref bal
            fun transaction -&amp;gt;
                match transaction with
                | &amp;quot;balance&amp;quot; -&amp;gt;
                    fun _ -&amp;gt; !balance
                | &amp;quot;deposit&amp;quot; -&amp;gt;
                    fun (arglist : obj list) -&amp;gt;
                        let amt = arglist.Head :?&amp;gt; int
                        balance := (!balance) + amt
                        !balance
                | &amp;quot;withdraw&amp;quot; -&amp;gt;
                    fun (arglist : obj list) -&amp;gt;
                        let amt = arglist.Head :?&amp;gt; int
                        if amt &amp;lt;= !balance then
                            balance := (!balance) - amt
                            !balance
                        else
                            raise (Exception(&amp;quot;Insufficient funds&amp;quot;))
                | _ -&amp;gt;
                    raise (Exception(&amp;quot;Unrecognized operation&amp;quot; + transaction))
    let makeInterestBearingAccount =
        fun (bal : int) (intRate : float) -&amp;gt;
            let account = makeAccount bal
            fun transaction -&amp;gt;
                match transaction with
                | &amp;quot;accrueInterest&amp;quot; -&amp;gt;
                    fun _ -&amp;gt;
                        let balance = (account &amp;quot;balance&amp;quot; [])
                        let interest : float = float balance * intRate 
                        account &amp;quot;deposit&amp;quot; [int interest]
                | _ -&amp;gt; account transaction
    Console.WriteLine &amp;quot;=========&amp;gt; Delegation&amp;quot;
    let acctForEugene = makeInterestBearingAccount 100 0.05
    printfn &amp;quot;%d&amp;quot; (acctForEugene &amp;quot;deposit&amp;quot; [20])
    printfn &amp;quot;%d&amp;quot; (acctForEugene &amp;quot;accrueInterest&amp;quot; [])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the explicit casts in the &amp;quot;accrueInterest&amp;quot; code: this is because F#, like a lot of functional languages, won&apos;t do automatic type-promotion for you. So the &amp;quot;int&amp;quot;s have to be explicitly converted to &amp;quot;float&amp;quot;s, and back again.&lt;/p&gt;
&lt;h3 id=&quot;yeti-ml-6&quot;&gt;Yeti (ML):&lt;/h3&gt;
Since we didn&apos;t go down the path of trying to do the variable-argument list in Yeti, we don&apos;t have the same problems the Scala version presented, and the generic methods (the top-level &quot;withdraw&quot;, &quot;deposit&quot; and &quot;balance&quot; functions) actually help hide the syntactic weirdness that we ran into in the last pattern element:
&lt;pre&gt;&lt;code&gt;makeAccount =
  (do bal:
    var balance = bal;
    do action:
      case action of
        &amp;quot;withdraw&amp;quot;:
          do amt:
            if amt &amp;lt;= balance then
              balance := balance - amt;
              balance
            else
              throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
            fi
          done;
        &amp;quot;deposit&amp;quot;: 
          do amt:
            balance := balance + amt;
            balance
          done;
        &amp;quot;balance&amp;quot;: 
          do: 
            balance
          done;
        _ : throw new RuntimeException(&amp;quot;Unknown operation&amp;quot;)
      esac
    done;
  done;);

withdraw =
  (do acct amt:
    (acct &amp;quot;withdraw&amp;quot;) amt;
  done;);
deposit =
  (do acct amt:
    (acct &amp;quot;deposit&amp;quot;) amt;
  done;);
balance =
  (do acct:
    acct &amp;quot;balance&amp;quot; 0;
  done;);

acctForEugene = makeAccount 100;
println (withdraw acctForEugene 20);      // 80
println (deposit acctForEugene 20);       // 100
println (balance acctForEugene);          // 100

accounts = [(makeAccount 100), (makeAccount 200), (makeAccount 300)];
balances = map (do acct: (deposit acct 20) done) accounts;
for accounts do acct: println(deposit acct 20) done;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the last two lines--the &amp;quot;for&amp;quot; construct in most imperative languages is actually akin to the &amp;quot;map&amp;quot; construct in most functional languages, except that in the imperative &amp;quot;for&amp;quot; there&apos;s no return value from the expression, and in a functional &amp;quot;map&amp;quot; there (usually) is. This is why we have to bind the result from the &amp;quot;map&amp;quot; to a name, and we don&apos;t have any results from the &amp;quot;for&amp;quot;. (The &amp;quot;map&amp;quot; also insists on having a returned value--a list of Unit isn&apos;t acceptable, which is what would be returned if we used the &amp;quot;println&amp;quot; expression in the &amp;quot;map&amp;quot;.)&lt;/p&gt;
&lt;h3 id=&quot;jaskell-haskell-6&quot;&gt;Jaskell (Haskell):&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;c-7&quot;&gt;C#:&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;private-method&quot;&gt;Private Method&lt;/h2&gt;
&quot;You have created a Method Selector. How do you factor common behavior out of the methods in the Method Selector? ... [D]efine the common code in a Local Procedure (Wallingford). Invoke this procedure in place of the duplicated code within the Method Selector.&quot;
&lt;h3 id=&quot;scheme-7&quot;&gt;Scheme:&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;(define make-account
  (lambda (balance)
    (let ((transaction-log &apos;())
      (log-transaction
        (lambda type amount)
          (set! transaction-log
                (cons (list type amount)
                      transaction-log)))) )
      (lamba (transaction)
        (case transaction
          (&apos;withdraw
            (lambda (amount)
              (if (&amp;gt;= balance amount)
                (begin
                  (set! balance (- balance amount))
                  (log-transaction &apos;withdraw amount)
                  balance)
                (error &amp;quot;Insufficient funds&amp;quot; balance))))
          (&apos;deposit
            (lambda (amount)
              (set! balance (+ balance amount))
              (log-transaction &apos;deposit amount)
              balance))
        ...))
    ))
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;javascript-8&quot;&gt;JavaScript:&lt;/h3&gt;
Again, in JavaScript, we rely on the fact that anything declared inside the &quot;makeAccount&quot; function but outside the function returned by &quot;makeAccount&quot; is encapsulated, and create both the &quot;transactionLog&quot; (an array, since JavaScript likes those better than lists) and the function to append to it (&quot;logTransaction&quot;) within that &quot;neutral zone&quot;. Just to prove that the transaction log is being written, I add another method to the method selector table, &quot;viewLog&quot;, to return the contents of the transaction log.
&lt;pre&gt;&lt;code&gt;(function() {
  out(&amp;quot;privateMethod ===========&amp;quot;)
  
  var makeAccount = function(bal) {
    var transactionLog = []
    var logTransaction = function(type, amount) {
      transactionLog.push(&amp;quot;Action: &amp;quot; + type + &amp;quot; for &amp;quot; + amount)
    }
    
    var balance = bal
    return function(transaction) {
      if (transaction === &amp;quot;withdraw&amp;quot;) {
        return function(amount) {
          if (balance &amp;gt;= amount) {
            logTransaction(&amp;quot;withdraw&amp;quot;, amount)
            return (balance = (balance - amount))
          }
          else
            throw new Error(&amp;quot;Insufficient funds&amp;quot;)
        }
      }
      else if (transaction === &amp;quot;deposit&amp;quot;) {
        return function(amount) {
          logTransaction(&amp;quot;deposit&amp;quot;, amount)
          return (balance = (balance + (amount * 10.0 / 10.0)))
        }
      }
      else if (transaction === &amp;quot;balance&amp;quot;) {
        return function() {
          logTransaction(&amp;quot;balance&amp;quot;, balance)
          return balance
        }
      }
      else if (transaction === &amp;quot;viewLog&amp;quot;) {
        return function() {
          return (transactionLog)
        }
      }
      else {
        throw new Error(&amp;quot;Insufficient funds&amp;quot;)
      }
    }
  }
  var acctForEugene = makeAccount(100)
  out(acctForEugene(&amp;quot;withdraw&amp;quot;)(20))
  out(acctForEugene(&amp;quot;balance&amp;quot;)())
  out(acctForEugene(&amp;quot;deposit&amp;quot;)(20))
  out(acctForEugene(&amp;quot;balance&amp;quot;)())
  out(acctForEugene(&amp;quot;viewLog&amp;quot;)())
})();
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;scala-8&quot;&gt;Scala:&lt;/h3&gt;
The Scala version is also pretty straightforward--we&apos;ve already seen that Scala supports nested functions, so it is simply a matter of defining the logTransaction() function and an empty List[String] in the same &quot;neutral zone&quot; in which the &quot;balance&quot; variable lives. Instead of adding a new selector to the list, I chose this time to just print the transaction log as part of the &quot;balance&quot; operation.
&lt;pre&gt;&lt;code&gt;  def privateMethod() = {
    def makeAccount(bal : Int) = {
      var balance = bal
      var transactionLog = List[String]()
      def logTransaction(action:String, amount:Int) = {
        val msg = (&amp;quot;Action: &amp;quot; + action + &amp;quot; for &amp;quot; + amount)
        transactionLog = transactionLog :+ msg
      }
      def send(key:String, args:Any*) = {
        key match {
          case &amp;quot;withdraw&amp;quot; =&amp;gt; {
            val amt = args.head.asInstanceOf[Int]
            if (balance &amp;gt;= amt) {
              logTransaction(&amp;quot;withdraw&amp;quot;, amt)
              balance = (balance - amt) 
              balance
            }
            else 
              throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
          }
          case &amp;quot;deposit&amp;quot; =&amp;gt; {
            val amt = args.head.asInstanceOf[Int]
            logTransaction(&amp;quot;deposit&amp;quot;, amt)
            balance += amt
            balance
          }
          case &amp;quot;balance&amp;quot; =&amp;gt; {
            println(transactionLog)
            balance
          }
          case _ =&amp;gt;
            throw new RuntimeException(&amp;quot;Unknown request&amp;quot;)
        }
      }
      send _
    }
    val acctForEugene = makeAccount(100)
    println(acctForEugene(&amp;quot;deposit&amp;quot;, 20))
    println(acctForEugene(&amp;quot;balance&amp;quot;))
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;f-8&quot;&gt;F#:&lt;/h3&gt;
Binding a local function is, by this point, somewhat trivial and uninspiring, but it&apos;s just as easily done in F# as it is in any of the other languages:
&lt;pre&gt;&lt;code&gt;let privateMethod = fun () -&amp;gt;
    let makeAccount =
        fun (bal : int) -&amp;gt;
            let transactionLog = ref []
            let logTransaction act (amt : int) =
                let message = &amp;quot;Action: &amp;quot; + act + &amp;quot; for &amp;quot; + amt.ToString()
                transactionLog := List.append !transactionLog [message]
            let balance = ref bal
            fun transaction -&amp;gt;
                match transaction with
                | &amp;quot;balance&amp;quot; -&amp;gt;
                    fun _ -&amp;gt; 
                        List.iter (printfn &amp;quot;%s&amp;quot;) !transactionLog
                        !balance
                | &amp;quot;deposit&amp;quot; -&amp;gt;
                    fun (arglist : obj list) -&amp;gt;
                        let amt = arglist.Head :?&amp;gt; int
                        balance := (!balance) + amt
                        logTransaction &amp;quot;deposit&amp;quot; amt
                        !balance
                | &amp;quot;withdraw&amp;quot; -&amp;gt;
                    fun (arglist : obj list) -&amp;gt;
                        let amt = arglist.Head :?&amp;gt; int
                        if amt &amp;lt;= !balance then
                            balance := (!balance) - amt
                            logTransaction &amp;quot;withdraw&amp;quot; amt
                            !balance
                        else
                            raise (Exception(&amp;quot;Insufficient funds&amp;quot;))
                | _ -&amp;gt;
                    raise (Exception(&amp;quot;Unrecognized operation&amp;quot; + transaction))
    Console.WriteLine &amp;quot;=========&amp;gt; Private Method&amp;quot;
    let acctForEugene = makeAccount 100
    printfn &amp;quot;%d&amp;quot; (acctForEugene &amp;quot;deposit&amp;quot; [20])
    printfn &amp;quot;%d&amp;quot; (acctForEugene &amp;quot;withdraw&amp;quot; [50])
    printfn &amp;quot;%d&amp;quot; (acctForEugene &amp;quot;balance&amp;quot; [])
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;yeti-ml-7&quot;&gt;Yeti (ML):&lt;/h3&gt;
The private method in Yeti is, again, just a nested function hiding out in the closure that is returned by &quot;makeAccount&quot;; the fact that Yeti supports expressions embedded inside of strings makes it easy to create the transaction log string:
&lt;pre&gt;&lt;code&gt;makeAccount =
  (do bal:
    var balance = bal;
    var transactionLog is list&amp;lt;string&amp;gt; = [];
    logTransaction action amount = 
      transactionLog := &amp;quot;Action: \(action) for \(amount)&amp;quot; :: transactionLog;
    do action:
      case action of
        &amp;quot;withdraw&amp;quot;:
          do amt:
            if amt &amp;lt;= balance then
              logTransaction &amp;quot;withdraw&amp;quot; amt;
              balance := balance - amt;
              balance
            else
              throw new RuntimeException(&amp;quot;Insufficient funds&amp;quot;)
            fi
          done;
        &amp;quot;deposit&amp;quot;: 
          do amt:
            logTransaction &amp;quot;deposit&amp;quot; amt;
            balance := balance + amt;
            balance
          done;
        &amp;quot;balance&amp;quot;: 
          do: 
            println transactionLog;
            balance
          done;
        _ : throw new RuntimeException(&amp;quot;Unknown operation&amp;quot;)
      esac
    done;
  done;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;jaskell-haskell-7&quot;&gt;Jaskell (Haskell):&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;c-8&quot;&gt;C#:&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
JavaScript is, of course, the de-facto golden child right now.
&lt;p&gt;And Scala is, undoubtedly, one of my favorites. It&apos;s syntax is a little quirky in places, but no more so than any other language I&apos;ve used.&lt;/p&gt;
&lt;p&gt;I like the Yeti code style and syntax, and could definitely see doing some small projects in it, particularly some service-y kinds of things with it, a la Web or REST services; the Yeti source code has some examples of how to create (for example) servlets and WARs, and it&apos;s a nice syntax. I don&apos;t know that I&apos;d want to create a full-fledged MVC framework on top of Yeti, but as something that&apos;s basically taking input, doing processing and sending back JSON or XML results, it&apos;s not a bad approach. Considering you can also create classes in Yeti, which puts it into the same grounds as F#, it&apos;s worth looking into if you&apos;ve got some ML in your background and want to go back to it while staying on top of the JVM.&lt;/p&gt;
&lt;p&gt;The F# version is a nice mix of ML and objects, though the casting operators are definitely a syntax that only a mother could love, and the distinction between what is allowed on functions vs. methods (such as the parameter arrays) feels a little arbitrary at times. (I&apos;m sure there&apos;s good reasons for it, but it still feels a little arbitrary, at least to me.) The &amp;quot;cannot close over local variables, use refs instead&amp;quot; rule is also a little annoying, although it does make it explicitly clear that now you&apos;re closing over a reference, not the actual value, so now the &amp;quot;what happens if I modify the closed-over value&amp;quot; question becomes self-explanatory. (This sometimes trips people up in other languages that don&apos;t make the by-value or by-reference closing-over semantics explicit.)&lt;/p&gt;
&lt;p&gt;Honestly, I don&apos;t really expect that anyone reading this piece is going to immediately turn around, abandon all their domain objects, and take up this approach as a replacement--in some cases, taking this &amp;quot;all functional&amp;quot; style creates more angst than it really provides benefits--but we can use parts of it to generate some really interesting new patterns.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>On Knowledge</title>
      <link>http://blogs.newardassociates.com/blog/2012/on-knowledge.html</link>
      <pubDate>Thu, 29 Nov 2012 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2012/on-knowledge.html</guid>
      	<description>
	&lt;p&gt;Back during the Bush-Jr Administration, Donald Rumsfeld drew quite a bit of fire for his discussion of knowledge, in which he said (loosely paraphrasing) &amp;quot;There are three kinds of knowledge: what you know you know, what you know you don&apos;t know, and what you don&apos;t know you don&apos;t know&amp;quot;. Lots of Americans, particularly those who were not kindly disposed towards &amp;quot;Rummy&amp;quot; in the first place, took this to be canonical Washington doublespeak, and berated him for it.&lt;/p&gt;
&lt;p&gt;I actually think that was one of the few things Rumsfeld said that was worth listening to, and I have a slight amendment to the statement; but first, let&apos;s level-set and make sure we&apos;re all on the same page about what those first three categories mean, in real life, with a few assumptions along the way to simplify the discussion (as best we can, anyway):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;What you know you know.&lt;/strong&gt; This is the category of information that the individual in question has studied to some level of depth: for a student of International Relations (as I was), this would be the various classes that they took and received (presumably) a passing grade in. For you, the reader of my blog, that would probably be some programming language and/or platform. This is knowledge that you have, in some depth, at a degree that most people would consider &amp;quot;factually accurate&amp;quot;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;What you know you don&apos;t know.&lt;/strong&gt; This is the category of information that the individual in question has heard about, but has never studied to any level or degree: for the student of International Relations, this might be the subject of biochemistry or electrical engineering. For you, the reader of my blog, it might be certain languages that you&apos;ve heard of, perhaps through this blog (Erlang, F#, Scala, Clojure, Haskell, etc) or data-storage systems (Cassandra, CouchDB, Riak, Redis, etc) that you&apos;ve never investigated or even sat through a lecture about. This is knowledge that you realize you don&apos;t have.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;What you don&apos;t know you don&apos;t know.&lt;/strong&gt; This is the category of information that the individual in question has never even heard about, and so therefore, by definition, has not only the lack of knowledge of the subject, but lacks the realization that they lack the knowledge of the subject. For the student of International Relations, this might be phrenology or Schrodinger&apos;s Cat. For you, the reader of my blog, it might be languages like Dylan, Crack, Brainf*ck, Ook, or Shakespeare (which I&apos;m guessing is going to trigger a few Google searches) or platforms like BeOS (if you&apos;re in your early 20&apos;s now), AmigaOS (if you&apos;re in your early 30&apos;s now) or database tools/platforms/environments like Pick or Paradox. This is knowledge that you didn&apos;t realize you don&apos;t have (but, paradoxically, now that you know you don&apos;t have it, it moves into the &amp;quot;know you don&apos;t know&amp;quot; category).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Typically, this discussion comes up in my &amp;quot;Pragmatic Architecture&amp;quot; talk, because an architect needs to have a very clear realization of what technologies and/or platforms are in which of those three categories, and (IMHO) push as many of them from category #3 (don&apos;t know that you don&apos;t know) into category #2 (know you don&apos;t know) or, ideally, category #1 (know you know). Note that category #1 doesn&apos;t mean that you are the world&apos;s foremost expert on the thing, but you have some working knowledge of the thing in question--I don&apos;t consider myself to be an expert on Cassandra, for example, but I know enough that I can talk reasonably intelligently to it, and I know where I can get more in the way of details if that becomes important, so therefore I peg it in category #1.&lt;/p&gt;
&lt;p&gt;But what if I&apos;m wrong?&lt;/p&gt;
&lt;p&gt;See, here&apos;s where I think there&apos;s a new level of knowledge, and it&apos;s one I think every software developer needs to admit exists, at least for various things in their own mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What you think you know.&lt;/strong&gt; (Or, perhaps, another variant of &amp;quot;What you don&apos;t know that you don&apos;t know.&amp;quot;) This is knowledge that you believe, in your heart of hearts, you have about a given subject, and it is flat-out incorrect and wrong.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Be honest with yourself: we&apos;ve all met somebody in this industry who claims to have knowledge/expertise on a subject, and damn if they can&apos;t talk a good game. They genuinely believe, in fact, that they know the subject in question, and speak with the confidence and assurance that comes with that belief. (I&apos;m assuming that the speaker in question isn&apos;t trying to deliberately deceive anyone, which may, in some cases, be a naive and/or false assumption, but I&apos;m leaving that aside for now.) But, after a while, it becomes apparent, either to themselves or to the others around them, that the knowledge they have is either incorrect, out of date, out of context, or some combination of all three.&lt;/p&gt;
&lt;p&gt;As much as &amp;quot;what you don&apos;t know you don&apos;t know&amp;quot; information is dangerous, &amp;quot;what you think you know&amp;quot; information is far, far more so, particularly because until you demonstrate to yourself that your information is actually correct, you&apos;re a danger and a liability to anyone who listens to you. Without regularly challenging yourself to some form of external review/challenge, you&apos;ll never exactly know whether what you know is real, or just made up from your head.&lt;/p&gt;
&lt;p&gt;This is why, at every turn, your assumption should be that any information you have is some or all incorrect until proven otherwise. Find out &lt;strong&gt;why&lt;/strong&gt; you know something--what combination of facts/data lead you to believe that this is the case?--and you will quickly begin to discover whether that knowledge is real, or just some kind of elaborate self-deception.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>On Equality</title>
      <link>http://blogs.newardassociates.com/blog/2012/on-equality.html</link>
      <pubDate>Fri, 12 Oct 2012 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2012/on-equality.html</guid>
      	<description>
	&lt;p&gt;Recently (over the last half-decade, so far as I know) there&apos;s been a concern about the numbers of women in the IT industry, and in particular the noticeable absence of women leaders and/or industry icons in the space. All of the popular languages (C, C++, Java, C#, Scala, Groovy, Ruby, you name it) have been invented by or are represented publicly by men. The industry speakers at conferences are nearly all men. The rank-and-file that populate the industry are men. And this strikes many as a bad thing.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;&lt;em&gt;(&lt;strong&gt;UPDATE 2021:&lt;/strong&gt; As part of porting this post over to the new system, I took a hard look at this post, and find that I&apos;m feeling a little differently than what I expressed a decade prior. I leave it here for posterity, but some of my statements below are definitely not what I&apos;d say today, and will post a followup at some point down the road to get deeper into the nuance of my current belief.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Honestly, I used to be a lot more concerned than I am today. While I&apos;m sure that many will see my statements and position that follows as misogynistic and/or discriminatory, let me be the first to suggest quite plainly that I have nothing against any woman who wants to be a programmer, who wants to be an industry speaker, or who wants to create a startup and/or language and/or library and/or framework and/or tool and/or any other role of leadership and authority within the industry. I have always felt that this industry is more merit-based than any other I have ever had direct or indirect contact with. There is no need for physical strength, there is no need for dexterity or mobility, there is no need for any sort of physical stress tolerances (such as the G forces fighter pilots incur during aerial combat which, by the way, women are actually scientifically better at handling than men), there really even is no reason that somebody who is physically challenged couldn&apos;t excel here. So long as you can type (or, quite frankly, have some other mechanism by which you can put characters into an IDE), you can program.&lt;/p&gt;
&lt;p&gt;And no, I have no illusions that somehow men are biologically wired better to be leaders. In fact, I think that as time progresses, we will find that the stereotypical characteristics that we ascribe to each of the genders (male competitiveness and female nuturing) each serve incredibly useful purposes in the IT world. &lt;a href=&quot;http://www.prenia.com&quot;&gt;Cathi Gero&lt;/a&gt;, for example, was once referred to by a client in my presence as &amp;quot;the Mom of the IT department&amp;quot;--by which they meant, Cathi would simply not rest until everything was exactly as it should be, a characteristic that they found incredibly comforting and supportive. Exactly the kind of characteristic you would want from a highly-paid consultant: that they will stick with you through all the mess until the problem is solved.&lt;/p&gt;
&lt;p&gt;And no, I also have no illusions that somehow I understand what it&apos;s been like to be a woman in IT. I&apos;ve never experienced the kind of &amp;quot;automatic discrimination&amp;quot; that women describe, being mistaken for recruiters at a technical conference, rather than as a programmer. I won&apos;t even begin to try and pretend that I know what that&apos;s like.&lt;/p&gt;
&lt;p&gt;Unless, of course, I can understand it by analogy, such as when a woman sees me walking down the street, and crosses the street ahead of me so that she won&apos;t have to share the sidewalk, for even a second, with a long-haired, goateed six-foot-plus stranger. She has no reason to assume I represent any threat to her other than my physical appearance, but still, her brain makes the association, and she chooses to avoid the potential possibility of threat. Still, that&apos;s probably not the same.&lt;/p&gt;
&lt;p&gt;What I do think, quite bluntly, is that one of the reasons we don&apos;t have more women in IT is because women simply choose not to be here.&lt;/p&gt;
&lt;p&gt;Yes, I know, there are dozens of stories of misogynistic behavior at conferences, and dozens more stories of discriminatory behavior. Dozens of stories of &amp;quot;good ol&apos; boys behavior&amp;quot; making women feel isolated, and dozens of stories of women feeling like they had to over-compensate for their gender in order to be heard and respected. But for each conference story where a woman felt offended by a speakers&apos; use of a sexual epithet or joke, there are dozens of conferences where no such story ever emerges.&lt;/p&gt;
&lt;p&gt;I&apos;m reminded of a story, perhaps an urban myth, of a speaker at a leadership conference that stood in front of a crowd, took a black marker, made a small circle in the middle of a flip board, and asked a person in the first row what they saw. &amp;quot;A black spot&amp;quot;, they replied. A second person said the same thing, and a third. Finally, after about a half-dozen responses of &amp;quot;a block spot&amp;quot;, the speaker said, &amp;quot;All of you said you saw the same thing: a black spot. I&apos;m curious as to why none of you saw the white background behind it&amp;quot;.&lt;/p&gt;
&lt;p&gt;It&apos;s easy for us to focus on the outlier and give that attention. It&apos;s even easier when we see several of them, and if they come in a cluster, we call it a &amp;quot;dangerous trend&amp;quot; and &amp;quot;something that must be addressed&amp;quot;. But how easy it is, then, to miss the rest of the field, in the name of focusing on the outlier.&lt;/p&gt;
&lt;p&gt;My ex-apprentice &lt;a href=&quot;http://blog.jessitron.com/2012/10/why-and-how.html&quot;&gt;wants us to proactively hire women instead of men&lt;/a&gt; in order to address this lack:&lt;/p&gt;
&lt;blockquote&gt;
Bring women to the forefront of the field. If you&apos;re selecting a leader and the best woman you can find is not as qualified as the best man you can find, (1) check your numbers to make sure unintentional bias isn&apos;t working against her, and (2) hire her anyway. She is smart and she will rise to the occasion. She is not as experienced because women haven&apos;t been given these opportunities in the past. So give it to her. Next round, she will be the most qualified.
&lt;p&gt;Am I advocating affirmative action in hiring? No, I&apos;m advocating blind hiring as much as is feasible. This has worked for conferences that do blind session selection and seek out submissions from women. However, I am advocating deliberate bias in favor of a woman in promotions, committee selection, writing and speaking solicitation, all technical leadership positions. The small biases have multiplied until there are almost no women in the highest technical levels of the field.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But you can&apos;t claim that you&apos;re advocating &amp;quot;blind hiring&amp;quot; while you&apos;re saying &amp;quot;hire her anyway&amp;quot; if she &amp;quot;is not as qualified as the best man you can find&amp;quot;. This is, by definition, affirmative action, and while it does put women into those positions, it doesn&apos;t address the underlying problem--that she isn&apos;t as qualified. There is no reason that she shouldn&apos;t be as qualified as the man, so why are we giving her a pass? Why is it this company&apos;s responsibility to fix the industry at a cost to themselves? (I&apos;m assuming, of course, that there is a lost productivity or lost innovation or some other cost to not hiring the best candidate they can find; if such a loss doesn&apos;t exist, then there&apos;s no basis for assuming that she isn&apos;t equally qualified as the man.)&lt;/p&gt;
&lt;p&gt;Did women routinely get &amp;quot;railroaded&amp;quot; out of technical directions (math and science) and into more &amp;quot;soft areas&amp;quot; (English and fine arts) in schools back when I was a kid? Yep. Studies prove that. My wife herself tells me that she was &amp;quot;strongly encouraged&amp;quot; to take more English classes than math or science back in Junior high and high school, even when her grades in math and science were better than those in English. That bias happened. But does it happen with girls today? Studies I&apos;m reading about third-hand suggest not appreciably. And even if you were discriminated against back then, what stops you now? If you&apos;re reading this, you have a computer, so what stops you now from pursuing that career path? Programming today is not about math and science--it&apos;s about picking up a book, downloading a free SDK and/or IDE, and diving in. My background was in International Relations--I was never formally trained, either. Has it held me back? You betcha--there are a few places that refused to hire me because I didn&apos;t have the formal CS background to be able to select the right algorithm or do big-O analysis. Didn&apos;t seem to stop me--I just went and interviewed someplace else.&lt;/p&gt;
&lt;p&gt;Equality means equality. If a woman wants to be given the same respect as a man, then she has to earn it the same way he does, by being equally qualified and equally professional. It is this &amp;quot;we should strengthen the weak&amp;quot; mentality that leads to soccer games with no score kept, because &amp;quot;we&apos;re all winners&amp;quot;. That in turn leads to children that then can&apos;t handle it when they actually do lose at something, which they must, eventually, because life is not fair. It never will be. Pretending otherwise just does a disservice to the women who have put in the blood, sweat, and tears to achieve the positions of prominence and respect that they earned.&lt;/p&gt;
&lt;p&gt;Am I saying this because I worry that preferential treatment to women speakers at conferences and in writing will somehow mean there are fewer opportunities for me, a man? Some will accuse me of such, but those who do probably don&apos;t realize that I turn down more conferences than I accept these days, and more writing opportunities as well. In fact, regardless of your gender, there are dozens, if not hundreds, of online portals and magazines that are desperate for authors to write quality work--if you&apos;re at all stumped trying to write for somebody, then you&apos;re not trying very hard. And every week user groups across the country are canceled for a lack of a speaker--if you&apos;re trying to speak and you&apos;re not, then you&apos;re either setting your bar too high (&amp;quot;If I don&apos;t get into TechEd, having never spoken before in my life, it must be because I&apos;m a woman, not that I&apos;m not a qualified speaker!&amp;quot;) or you&apos;re really not trying (&amp;quot;Why aren&apos;t the conferences calling me about speaking there?&amp;quot;).&lt;/p&gt;
&lt;p&gt;If you&apos;re a woman, and you&apos;re thinking about a career in IT, more power to you. This industry offers more opportunity and room for growth than any other I&apos;ve yet come across. There are dozens of meetings and meetups and conferences that are springing into place to encourage you and help you earn that distinction. Yes, as you go you will want and/or need help. So did I. You need people that will help you sharpen your skills and improve your abilities, yes. But a specific and concrete bias in your favor? No. You don&apos;t need somebody&apos;s charity.&lt;/p&gt;
&lt;p&gt;Because if you do, then it means that you&apos;re admitting that you can&apos;t do it on your own, and you aren&apos;t really equal. And that, I think, would be the biggest tragedy of the whole issue.&lt;/p&gt;
&lt;p&gt;Flame away.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Just Say No to SSNs</title>
      <link>http://blogs.newardassociates.com/blog/2012/just-say-no-to-ssns.html</link>
      <pubDate>Fri, 16 Mar 2012 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2012/just-say-no-to-ssns.html</guid>
      	<description>
	&lt;p&gt;Two things conspire to bring you this blog post.&lt;/p&gt;
&lt;h2&gt;Of Contracts and Contracts&lt;/h2&gt;
&lt;p&gt;First, a few months ago, I was asked to participate in an architectural review for a project being done for one of the states here in the US. It was a project dealing with some sensitive information (Child Welfare Services), and I was required to sign a document basically promising not to do anything bad with the data. Not a problem to sign, since I was going to be more focused on the architecture and code anyway, and would stay away from the production servers and data as much as I possibly could. But then the state agency asked for my social security number, and when I pushed back asking why, they told me it was “mandatory” in order to work on the project. I suspect it was for a background check—but when I asked how long they were going to hold on to the number and what their privacy policy was regarding my data, they refused to answer, and I never heard from them again. Which, quite frankly, was something of a relief.
&lt;p&gt;Second, just tonight there was a thread on the Seattle Tech Startup mailing list about SSNs again. This time, a contractor who participates on the list was being asked by the contracting agency for his SSN, not for any tax document form, but... just because. This sounded fishy. It turned out that the contract was going to be with AT&amp;amp;T, and that they commonly use a contractor’s SSN as a way of identifying the contractor in their vendor database. It was also noted that many companies do this, and that it was likely that many more would do so in the future. One poster pointed out that when the state’s attorney general’s office was contacted about this practice, it isn’t illegal.&lt;/p&gt;
&lt;p&gt;Folks, this practice has to stop. For both your sake, and the company’s.&lt;/p&gt;
&lt;h2&gt;Of Data and Integrity&lt;/h2&gt;
&lt;p&gt;Using SSNs in your database is just a bad idea from top to bottom. For starters, it makes your otherwise-unassuming enterprise application a ripe target for hackers, who seek to gather legitimate SSNs as part of the digital fingerprinting of potential victims for identity theft. What’s worse, any time I’ve ever seen any company store the SSNs, they’re almost always stored in plaintext form (“These aren’t credit cards!”), and they’re often used as a primary key to uniquely identify individuals.&lt;/p&gt;
&lt;p&gt;There’s so many things wrong with this idea from a data management perspective, it’s shameful.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SSNs were never intended for identification purposes.&lt;/strong&gt; Yeah, this is a weak argument now, given all the &lt;em&gt;de facto&lt;/em&gt; uses to which they are put already, but when FDR passed the Social Security program back in the 30s, he promised the country that they would never be used for identification purposes. This is, in fact, why the card reads “This number not to be used for identification purposes” across the bottom. Granted, every financial institution with whom I’ve ever done business has ignored that promise for as long as I’ve been alive, but that doesn’t strike me as a reason to continue doing so.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SSNs are not unique.&lt;/strong&gt; There’s rumors of two different people being issued the same SSN, and while I can’t confirm or deny this based on personal experience, it doesn’t take a rocket scientist to figure out that if there are 300 million people living in the US, and the SSN is a nine-digit number, that means that there are 999,999,999 potential numbers in the best case (which isn’t possible, because the first three digits are a stratification mechanism—-for example, California-issued numbers are generally in the 5xx range, while East Coast-issued numbers are in the 0xx range). What I can say for certain is that SSNs are, in fact, recycled—-so your new baby may (and very likely will) end up with some recently-deceased individual’s SSN. As we start to see databases extending to a second and possibly even third generation of individuals, these kinds of conflicts are going to become even more common. As US population continues to rise, and immigration brings even more people into the country to work, how soon before we start seeing the US government sweat the problems associated with trying to go to a 10- or 11-digit SSN? It’s going to make the IPv4 and IPv6 problems look trivial by comparison. (Look for that to be the moment when the US government formally adopts a hexadecimal system for SSNs.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SSNs are sensitive data.&lt;/strong&gt; You knew this already. But what you may not realize is that data not only has a tendency to escape the organization that gathered it (databases are often sold, acquired, or stolen), but that said data frequently lives far, far longer than it needs to. Look around in your own company—how many databases are still online, in use, even though the data isn’t really relevant anymore, just because “there’s no cost to keeping it”? More importantly, companies are increasingly being held accountable for sensitive information breaches, and it’s just a matter of time before a creative lawyer seeking to tap into the public’s sensitivities to things they don’t understand leads him/her takes a company to court, suing them for damages for such a breach. And there’s very likely more than a few sympathetic judges in the country to the idea. Do you really want to be hauled up on the witness stand to defend your use of the SSN in your database?&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Given that SSNs aren’t unique, and therefore fail as their primary purpose in a data management scheme, and that they represent a huge liability because of their sensitive nature, why on earth would you want them in your database?&lt;/p&gt;
&lt;h2&gt;A Call&lt;/h2&gt;
&lt;p&gt;But more importantly, companies aren’t going to stop using them for these kinds of purposes until we &lt;em&gt;make&lt;/em&gt; them stop. Any time a company asks you for your SSN, challenge them. Ask them why they need it, if the transaction can be completed without it, and if they insist on having it, a formal declaration of their sensitive information policy and what kind of notification and compensation you can expect when they suffer a sensitive data breach. It may take a while to find somebody within the company who can answer your questions at the places that legitimately need the information, but you’ll get there eventually. And for the rest of the companies that gather it “just in case”, well, if it starts turning into a huge PITA to get them, they’ll find other ways to figure out who you are.&lt;/p&gt;
&lt;p&gt;This is a call to arms, folks: Just say NO to handing over your SSN.&lt;/p&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Leveling Up &apos;DDD&apos;</title>
      <link>http://blogs.newardassociates.com/blog/2012/leveling-up-ddd.html</link>
      <pubDate>Fri, 2 Mar 2012 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2012/leveling-up-ddd.html</guid>
      	<description>
	&lt;p&gt;Eric Evans, a number of years ago, wrote a book on “Domain Driven Design”. Around the same time, Martin Fowler coined the “Rich Domain Model” pattern.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Ever since then, people have been going bat-shit nutso over building these large domain object models, then twisting and contorting them in all these various ways to make them work across different contexts—-across tiers, for example, and into databases, and so on. It created a cottage industry of infrastructure tools, toolkits, libraries and frameworks, all designed somehow to make your objects less twisted and more usable and less tightly-coupled to infrastructure (I’ll pause for a moment to let you think about the absurdity of that—infrastructure designed to reduce coupling to other infrastructure—before we go on), and so on.&lt;/p&gt;
&lt;p&gt;All the time, though, we were shying away from really taking the plunge, and thinking about domain entities in domain terms.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://jessitron.blogspot.com/2012/03/strong-typing-in-java-religious.html&quot; target=&quot;_blank&quot;&gt;Jessica Kerr nails it, on the head&lt;/a&gt;. Her post is in the context of Java (with, ironically, some F# thrown in for clarity), but the fact is, the Java parts could’ve been written in C# or C++ and the discussion would be the exact same.&lt;/p&gt;
&lt;p&gt;To think about building domain objects, if you are really looking to build a domain model, means to think beyond the implementation language you’re building them in. That means you have to stop thinking in terms of “Strings” and “ints”, but in terms of “FirstName” and “Age” types. Ironically, Java is ill-suited as a language to support this. C# is not great about this, but it is easier than Java. C++, ironically, may be best suited for this, given the ease with which we can set up “aliased” types, via either the typedef or even the lowly preprocessor macro (though it hurts me to say that).&lt;/p&gt;
&lt;p&gt;I disagree with her when she says that it’s a problem that FirstName can’t inherit from String—-frankly, I hold the position that having FirstName inherit from String would be putting too much implementation detail into FirstName then, and would hurt FirstName’s chances for evolution and enhancement—-but the rest of the post is so spot-on, it’s scary.&lt;/p&gt;
&lt;p&gt;And the really ironic thing? I remember having this conversation nearly twenty years ago, in the context of C++ at the time.&lt;/p&gt;
&lt;p&gt;Want another mind-warping discussion around DDD and how to think about domain objects correctly? Read Allen Holub’s “&lt;a href=&quot;http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html&quot; target=&quot;_blank&quot;&gt;Getters and Setters Considered Harmful&lt;/a&gt;” article of nine (!) years ago.&lt;/p&gt;
&lt;p&gt;Read those two entries, think on them for a bit, then give it a whirl in your own projects. Or as a research spike. I think you’ll start to find a lot of that infrastructure code starting to drop away and become unnecessary. And that will let you get back to the essence of objects, and level up your DDD.&lt;/p&gt;
&lt;p&gt;(Unfortunately, I don’t know what leveled-up DDD is called. DDD++, maybe?)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Is Programming Less Exciting Today?</title>
      <link>http://blogs.newardassociates.com/blog/2012/is-programming-less-exciting-today.html</link>
      <pubDate>Wed, 25 Jan 2012 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2012/is-programming-less-exciting-today.html</guid>
      	<description>
	&lt;p&gt;As discriminatory as this is going to sound, this one is for the old-timers. If you started programming after the turn of the milennium, I don’t know if you’re going to be able to follow the trend of this post—not out of any serious deficiency on your part, hardly that. But I think this is something only the old-timers are going to identify with. (And thus, do I alienate probably 80% of my readership, but so be it.)&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Is it me, or is programming just less interesting today than it was two decades ago?&lt;/p&gt;
&lt;p&gt;By all means, shake your smartphones and other mobile devices at me and say, “Dude, how can you say that?”, but in many ways programming for Android and iOS reminds me of programming for Windows and Mac OS two decades ago. HTML 5 and JavaScript remind me of ten years ago, the first time HTML and JavaScript came around. The discussions around programming languages remind me of the discussions around C++. The discussions around NoSQL remind me of the arguments both for and against relational databases. It all feels like we’ve been here before, with only the names having changed.&lt;/p&gt;
&lt;p&gt;Don’t get me wrong—-if any of you comment on the differences between HTML 5 now and HTML 3.2 then, or the degree of the various browser companies agreeing to the standard today against the “browser wars” of a decade ago, I’ll agree with you. This isn’t so much of a rational and logical discussion as it is an emotive and intuitive one. It just &lt;em&gt;feels&lt;/em&gt; similar.&lt;/p&gt;
&lt;p&gt;To be honest, I get this sense that across the entire industry right now, there’s a sort of malaise, a general sort of “Bah, nothing really all that new is going on anymore”. NoSQL is re-introducing storage ideas that had been around before but were discarded (perhaps injudiciously and too quickly) in favor of the relational model. Functional languages have obviously been in place since the 50’s (in Lisp). And so on.&lt;/p&gt;
&lt;p&gt;More importantly, look at the Java community: what truly innovative ideas have emerged here in the last five years? Every new open-source project or commercial endeavor either seems to be a refinement of an idea before it (how many different times are we going to create a new Web framework, guys?) or an attempt to leverage an idea coming from somewhere else (be it from .NET or from Ruby or from JavaScript or….). With the upcoming .NET 4.5 release and Windows 8, Microsoft is holding out very little “new and exciting” bits for the community to invest emotionally in: we hear about “async” in C# 5 (something that F# has had already, thank you), and of course there is WinRT (another platform or virtual machine… sort of), and… well, honestly, didn’t we just do this a decade ago? Where is the WCFs, the WPFs, the Silverlights, the things that would get us fired up? Hell, even a new approach to data access might stir some excitement. Node.js feels like an attempt to reinvent the app server, but if you look back far enough you see that the app server itself was reinvented once (in the Java world) in Spring and other lightweight frameworks, and before that by people who actually thought to write their own web servers in straight Java. (And, for the record, the whole event-driven I/O thing is something that’s been done in both Java and .NET a long time before now.)&lt;/p&gt;
&lt;p&gt;And as much as this is going to probably just throw fat on the fire, all the excitement around JavaScript as a language reminds me of the excitement about Ruby as a language. Does nobody remember that Sun did this once already, with Phobos? Or that Netscape did this with LiveScript? JavaScript on the server end is not new, folks. It’s just new to the people who’d never seen it before.&lt;/p&gt;
&lt;p&gt;In years past, there has always seemed to be something deeper, something more exciting and more innovative that drives the industry in strange ways. Artificial Intelligence was one such thing: the search to try and bring computers to a state of human-like sentience drove a lot of interesting ideas and concepts forward, but over the last decade or two, AI seems to have lost almost all of its luster and momentum. User interfaces—specifically, GUIs—were another force for a while, until GUIs got to the point where they were so common and so deeply rooted in their chosen pasts (the single-button of the Mac, the menubar-per-window of Windows, etc) that they left themselves so little room for maneuver. At least this is one area where Microsoft is (maybe) putting the fatted sacred cow to the butcher’s knife, with their Metro UI moves in Windows 8... but only up to a point.&lt;/p&gt;
&lt;p&gt;Maybe I’m just old and tired and should hang up my keyboard and go take up farming, then go retire to my front porch’s rocking chair and practice my &lt;em&gt;Hey you kids! Getoffamylawn!&lt;/em&gt; or something. But before you dismiss me entirely, do me a favor and tell me: what gets you excited these days? If you’ve been programming for twenty years, what about the industry today gets your blood moving and your mind sharpened?&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2012 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2012/2012-tech-predictions.html</link>
      <pubDate>Sun, 1 Jan 2012 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2012/2012-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;Here we go again: the annual review of last year&apos;s predictions, and a set of new ones for the new year.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Well, friends, another year has come and gone, and it&apos;s time for me to put my crystal ball into place and see what the upcoming year has for us. But, of course, in the long-standing tradition of these predictions, I also need to put my spectacles on (I did turn 40 last year, after all) and have a look at how well I did &lt;a href=&quot;../2011/2011-tech-predictions.html&quot;&gt;in this same activity twelve months ago&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s see what unbelievable gobs of hooey I slung last year came even remotely to pass. For 2011, I said....&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;
&lt;strong&gt;THEN:&lt;/strong&gt; &lt;em&gt;Android’s penetration into the mobile space is going to rise, then plateau around the middle of the year.&lt;/em&gt; Android phones, collectively, have outpaced iPhone sales. That’s a pretty significant statistic—and it means that there’s fewer customers buying smartphones in the coming year. More importantly, the first generation of Android slates (including the Galaxy Tab, which I own), are less-than-sublime, and not really an “iPad Killer” device by any stretch of the imagination. And I think that will slow down people buying Android slates and phones, particularly since Google has all but promised that Android releases will start slowing down.
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Well, I think I get a point for saying that Android&apos;s penetration will rise... but then I lose it for suggesting that it would slow down. Wow, was I wrong on that. Once Amazon put the Kindle Fire out, suddenly for the first time Android tablets began to appear in peoples&apos; hands in record numbers. The drawback here is that most people using the Fire don&apos;t realize it&apos;s an Android tablet, which certainly hurts Google&apos;s brand-awareness (not that Amazon really seems to mind), but the upshot is simple: people are still buying devices, even though they may already own one. Which amazes me.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;THEN:&lt;/strong&gt; &lt;em&gt;Windows Phone 7 penetration into the mobile space will appear huge, then slow down towards the middle of the year.&lt;/em&gt; Microsoft is getting some pretty decent numbers now, from what I can piece together, and I think that’s largely the “I love Microsoft” crowd buying in. But it’s a pretty crowded place right now with Android and iPhone, and I’m not sure if the much-easier Office and/or Exchange integration is enough to woo consumers (who care about Office) or business types (who care about Exchange) away from their Androids and iPhones.
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Despite the catastrophic implosion of RIM (thus creating a huge market of people looking to trade their Blackberrys in for other mobile phones, ones which won&apos;t all go down when a RIM server implodes), WP7 has definitely not emerged as the &quot;third player&quot; in the mobile space; or, perhaps more precisely, they feel like a distant third, rather than a creditable alternative to the other two. In fact, more and more it just feels like this is a two-horse race and Microsoft is in it still because they&apos;re willing to throw loss after loss to stay in it. (For what reason, I&apos;m not sure--it&apos;s not clear to me that they can ever reach a point of profitability here, even once Nokia makes the transition to WP7, which is supposedly going to take years. On the order of a half-decade or so.) Even living here in Redmon, where I would expect the WP7 concentration to be much, much higher than anywhere else in the world, it&apos;s still more common to see iPhones and &apos;droids in peoples&apos; hands than it is to see WP7 phones.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;THEN:&lt;/strong&gt; &lt;em&gt;Android, iOS and/or Windows Phone 7 becomes a developer requirement.&lt;/em&gt; Developers, if you haven’t taken the time to learn how to program one of these three platforms, you are electing to remove yourself from a growing market that desperately wants people with these skills. I see the “mobile native app development” space as every bit as hot as the “Internet/Web development” space was back in 2000. If you don’t have a device, buy one. If you have a device, get the tools—in all three cases they’re free downloads—and start writing stupid little apps that nobody cares about, so you can have some skills on the platform when somebody cares about it.
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Wow, yes. Right now, if you are a developer and you haven&apos;t spent at least a little time learning mobile development, you are excluding yourself from a development &quot;boom&quot; that rivals the one around Web sites in the mid-90&apos;s. Seriously: remember when everybody had to have a website? That&apos;s the mentality right now with a ton of different companies--&quot;we have to have a mobile app!&quot; &quot;But we sell condom lubricant!&quot; &quot;Doesn&apos;t matter! We need a mobile app! Build us something! Go go go go go!&quot;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;THEN:&lt;/strong&gt; &lt;em&gt;The Windows 7 slates will suck.&lt;/em&gt; This isn’t a prediction, this is established fact. I played with an “ExoPC” 10” form factor slate running Windows 7 (Dell I think was the manufacturer), and it was a horrible experience. Windows 7, like most OSes, really expects a keyboard to be present, and a slate doesn’t have one—so the OS was hacked to put a “keyboard” button at the top of the screen that would slide out to let you touch-type on the slate. I tried to fire up Notepad and type out a haiku, and it was an unbelievably awkward process. Android and iOS clearly own the slate market for the forseeable future, and if Dell has any brains in its corporate head, it will phone up Google tomorrow and start talking about putting Android on that hardware.
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Yeah, that was something of a &quot;gimme&quot; point (but I&apos;ll take it). Windows7 on a slate was a Bad Idea, and I&apos;m pretty sure the sales reflect that. Conduct your own anecdotal poll: see if you can find a store somewhere in your town or city that will actually sell you a Windows7 slate. Can&apos;t find one? I can--it&apos;s the Microsoft store in town, and I&apos;m not entirely sure they still stock them. Certainly our local Best Buy doesn&apos;t.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;THEN:&lt;/strong&gt; &lt;em&gt;DSLs mostly disappear from the buzz.&lt;/em&gt; I still see no strawman (no “pet store” equivalent), and none of the traditional builders-of-strawmen (Microsoft, Oracle, etc) appear interested in DSLs much anymore, so I think 2010 will mark the last year that we spent any time talking about the concept.
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; I&apos;m going to claim a point here, too. DSLs have pretty much left us hanging. Without a strawman for developers to &quot;get&quot;, the DSL movement has more or less largely died out. I still sometimes hear people refer to something that isn&apos;t a programming language but does something technical as a &quot;DSL&quot; (&quot;That shipping label? That&apos;s a DSL!&quot;), and that just tells me that the concept never really took root.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;THEN:&lt;/strong&gt; &lt;em&gt;Facebook becomes more of a developer requirement than before.&lt;/em&gt; I don’t like Mark Zuckerburg. I don’t like Facebook’s privacy policies. I don’t particularly like the way Facebook approaches the Facebook Connect experience. But Facebook owns enough people to be the fourth-largest nation on the planet, and probably commands an economy of roughly that size to boot. If your app is aimed at the Facebook demographic (that is, everybody who’s not on Twitter), you have to know how to reach these people, and that means developing at least some part of your system to integrate with it.
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Facebook, if anything, has become more important through 2011, particularly for startups looking to get some exposure and recognition. Facebook continues to screw with their user experience, though, and they keep screwing with their security policies, and as &quot;big&quot; a presence as they have, it&apos;s not invulnerable, and if they&apos;re not careful, they&apos;re going to find themselves on the other side of the relevance curve.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;THEN:&lt;/strong&gt; Twitter becomes more of a developer requirement, too. Anybody who’s not on Facebook is on Twitter. Or dead. So to reach the other half of the online community, you have to know how to connect out with Twitter.
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Twitter&apos;s impact has become deeper, but more muted in some ways--people don&apos;t think of Twitter as a &quot;new&quot; channel, but one that they&apos;ve come to expect and get used to. At the same time, how Twitter is supposed to factor into different applications isn&apos;t always clear, which hinders Twitter&apos;s acceptance and &quot;must-have&quot;-ness. Of course, Twitter could care less, it seems, though it still confuses me how they actually make money.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;THEN:&lt;/strong&gt; XMPP becomes more of a developer requirement. XMPP hasn’t crossed a lot of people’s radar screen before, but Facebook decided to adopt it as their chat system communication protocol, and Google’s already been using it, and suddenly there’s a whole lotta traffic going over XMPP. More importantly, it offers a two-way communication experience that is in some scenarios vastly better than what HTTP offers, yet running in a very “Internet-friendly” way just as HTTP does. I suspect that XMPP is going to start cropping up in a number of places as a useful alternative and/or complement to using HTTP.
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Well, unfortunately, XMPP still hides underneath other names and still doesn&apos;t come to mind when people are thinking about communication, leaving this one way unfulfilled. *sigh* Maybe someday we will learn that not everything has to go over HTTP, but it didn&apos;t happen in 2011. &lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;THEN:&lt;/strong&gt; “Gamification” starts making serious inroads into non-gaming systems. Maybe it’s just because I’ve been talking more about gaming, game design, and game implementation last year, but all of a sudden “gamification”—the process of putting game-like concepts into non-game applications—is cresting in a big way. FourSquare, Yelp, Gowalla, suddenly all these systems are offering achievement badges and scoring systems for people who want to play in their worlds. How long is it before a developer is pulled into a meeting and told that “we need to put achievement badges into the call-center support application”? Or the online e-commerce portal? It’ll start either this year or next.
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Gamification is emerging, but slowly and under the radar. It&apos;s certainly not as strong as I thought it would be, but gamification concepts are sneaking their way into a variety of different scenarios (beyond games themselves). Probably can&apos;t claim a point here, no.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;THEN:&lt;/strong&gt; Functional languages will hit a make-or-break point. I know, I said it last year. But the buzz keeps growing, and when that happens, it usually means that it’s either going to reach a critical mass and explode, or it’s going to implode—and the longer the buzz grows, the faster it explodes or implodes, accordingly. My personal guess is that the “F/O hybrids”—F#, Scala, etc—will continue to grow until they explode, particularly since the suggested v.Next changes to both Java and C# have to be done as language changes, whereas futures for F# frequently are either built as libraries masquerading as syntax (such as asynchronous workflows, introduced in 2.0) or as back-end library hooks that anybody can plug in (such as type providers, introduced at PDC a few months ago), neither of which require any language revs—and no concerns about backwards compatibility with existing code. This makes the F/O hybrids vastly more flexible and stable. In fact, I suspect that within five years or so, we’ll start seeing a gradual shift away from pure O-O systems, into systems that use a lot more functional concepts—and that will propel the F/O languages into the center of the developer mindshare.
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; More than any of my other predictions (or subjects of interest), functional languages stump me the most. On the one hand, there doesn&apos;t seem to be a drop-off of interest in the subject, based on a variety of anecdotal evidence (books, articles, etc), but on the other hand, they don&apos;t seem to be crossing over into the &quot;mainstream&quot; programming worlds, either. At best, we can say that they are entering the mindset of senior programmers and/or project leads and/or architects, but certainly they don&apos;t seem to be turning in to the &quot;go-to&quot; language for projects being done in 2011.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;THEN:&lt;/strong&gt; &lt;em&gt;The Microsoft Kinect will lose its shine.&lt;/em&gt; I hate to say it, but I just don’t see where the excitement is coming from. Remember when the Wii nunchucks were the most amazing thing anybody had ever seen? Frankly, after a slew of initial releases for the Wii that made use of them in interesting ways, the buzz has dropped off, and more importantly, the nunchucks turned out to be just another way to move an arrow around on the screen—in other words, we haven’t found particularly novel and interesting/game-changing ways to use the things. That’s what I think will happen with the Kinect. Sure, it’s really freakin’ cool that you can use your body as the controller—but how precise is it, how quickly can it react to my body movements, and most of all, what new user interface metaphors are people going to have to come up with in order to avoid the “me-too” dancing-game clones that are charging down the pipeline right now?
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Kinect still makes for a great Christmas or birthday present, but nobody seems to be all that amazed by the idea anymore. Certainly we aren&apos;t seeing a huge surge in using Kinect as a general user interface device, at least not yet. Maybe it needed more time for people to develop those new metaphors, but at the same time, I would&apos;ve expected at least a few more games to make use of it, and I haven&apos;t seen any this past year.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;THEN:&lt;/strong&gt; &lt;em&gt;There will be no clear victor in the Silverlight-vs-HTML5 war.&lt;/em&gt; And make no mistake about it, a war is brewing. Microsoft, I think, finds itself in the inenviable position of having two very clearly useful technologies, each one’s “sphere of utility” (meaning, the range of answers to the “where would I use it?” question) very clearly overlapping. It’s sort of like being a football team with both Brett Favre and Tom Brady on your roster—both of them are superstars, but you know, deep down, that you have to cut one, because you can’t devote the same degree of time and energy to both. Microsoft is going to take most of 2011 and probably part of 2012 trying to support both, making a mess of it, offering up conflicting rationale and reasoning, in the end achieving nothing but confusing developers and harming their relationship with the Microsoft developer community in the process. Personally, I think Microsoft has no choice but to get behind HTML 5, but I like a lot of the features of Silverlight and think that it has a lot of mojo that HTML 5 lacks, and would actually be in favor of Microsoft keeping both—so long as they make it very clear to the developer community when and where each should be used. In other words, the executives in charge of each should be locked into a room and not allowed out until they’ve hammered out a business strategy that is then printed and handed out to every developer within a 3-continent radius of Redmond. (Chances of this happening: .01%)
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Well, this was accurate all the way up until the last couple of months, when Microsoft made it fairly clear that Silverlight was being effectively &quot;put behind&quot; HTML 5, despite shipping another version of Silverlight. In the meantime, though, they&apos;ve tried to support both (and some Silverlighters tell me that the Silverlight team is still looking forward to continuing supporting it, though I&apos;m not sure at this point what is rumor and what is fact anymore), and yes, they confused the hell out of everybody. I&apos;m surprised they pulled the trigger on it in 2011, though--I expected it to go a version or two more before they finally pulled the rug out. &lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;THEN:&lt;/strong&gt; &lt;em&gt;Apple starts feeling the pressure to deliver a developer experience that isn’t mired in mid-90’s metaphor.&lt;/em&gt; Don’t look now, Apple, but a lot of software developers are coming to your platform from Java and .NET, and they’re bringing their expectations for what and how a developer IDE should look like, perform, and do, with them. Xcode is not a modern IDE, all the Apple fan-boy love for it notwithstanding, and this means that a few things will happen:
        &lt;ul&gt;
            &lt;li&gt;&lt;em&gt;Eclipse gets an iOS plugin.&lt;/em&gt; Yes, I know, it wouldn’t work (for the most part) on a Windows-based Eclipse installation, but if Eclipse can have a native C/C++ developer experience, then there’s no reason why a Mac Eclipse install couldn’t have an Objective-C plugin, and that opens up the idea of using Eclipse to write iOS and/or native Mac apps (which will be critical when the Mac App Store debuts somewhere in 2011 or 2012).&lt;/li&gt;
            &lt;li&gt;&lt;em&gt;Rumors will abound about Microsoft bringing Visual Studio to the Mac.&lt;/em&gt; Silverlight already runs on the Mac; why not bring the native development experience there? I’m not saying they’ll actually do it, and certainly not in 2011, but the rumors, they will be flyin….&lt;/li&gt;
            &lt;li&gt;&lt;em&gt;Other third-party alternatives to Xcode will emerge and/or grow.&lt;/em&gt; MonoTouch is just one example. There’s opportunity here, just as the fledgling Java IDE market looked back in ‘96, and people will come to fill it.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Xcode 4 is &quot;better&quot;, but it&apos;s still not what I would call comparable to the Microsoft Visual Studio or JetBrains IDEA experience. LLVM is definitely a better platform for the company&apos;s development efforts, long-term, and it&apos;s encouraging that they&apos;re investing so heavily into it, but I still wish the overall development experience was stronger. Meanwhile, though, no Eclipse plugin has emerged (that I&apos;m aware of), which surprised me, and neither did we see Microsoft trying to step into that world, which doesn&apos;t surprise me, but disappoints me just a little. I realize that Microsoft&apos;s developer tools are generally designed to support the Windows operating system first, but Microsoft has to cut loose from that perspective if they&apos;re going to survive as a company. More on that later.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;THEN:&lt;/strong&gt; &lt;em&gt;NoSQL buzz grows.&lt;/em&gt; The NoSQL movement, which sort of got started last year, will reach significant states of buzz this year. NoSQL databases have a lot to offer, particularly in areas that relational databases are weak, such as hierarchical kinds of storage requirements, for example. That buzz will reach a fever pitch this year, and the relational database moguls (Microsoft, Oracle, IBM) will start to fight back.
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Well, the buzz certainly grew, and it surprised me that the big storage guys (Microsoft, IBM, Oracle) didn&apos;t do more to address it; I was expecting features to emerge in their database products to address some of the features present in MongoDB or CouchDB or some of the others, such as &quot;schemaless&quot; or map/reduce-style queries. Even just incorporating JavaScript into the engine somewhere would&apos;ve generated a reaction.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Overall, it appears I&apos;m running at about my usual 50/50 levels of prognostication. So be it. Let&apos;s see what the ol&apos; crystal ball has in mind for 2012:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;em&gt;Lisps will be the languages to watch.&lt;/em&gt; With Clojure leading the way, Lisps (that is, languages that are more or less loosely based on Common Lisp or one of its variants) are slowly clawing their way back into the limelight. Lisps are both functional languages as well as dynamic languages, which gives them a significant reason for interest. Clojure runs on top of the JVM, which makes it highly interoperable with other JVM languages/systems, and Clojure/CLR is the version of Clojure for the CLR platform, though there seems to be less interest in it in the .NET world (which is a mistake, if you ask me).&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Functional languages will.... I have no idea.&lt;/em&gt; As I said above, I&apos;m kind of stymied on the whole functional-language thing and their future. I keep thinking they will either &quot;take off&quot; or &quot;drop off&quot;, and they keep tacking to the middle, doing neither, just sort of hanging in there as a concept for programmers to take and run with. Mind you, I like functional languages, and I want to see them become mainstream, or at least more so, but I keep wondering if the mainstream programming public is ready to accept the ideas and concepts hiding therein. So this year, let&apos;s try something different: I predict that they will remain exactly where they are, neither &quot;done&quot; nor &quot;accepted&quot;, but continue next year to sort of hang out in the middle.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;F#&apos;s type providers will show up in C# v.Next.&lt;/em&gt; This one is actually a &quot;gimme&quot;, if you look across the history of F# and C#: for almost every version of F# v.&quot;N&quot;, features from that version show up in C# v.&quot;N+1&quot;. More importantly, F# 3.0&apos;s type provider feature is an amazing idea, and one that I think will open up language research in some &lt;em&gt;very&lt;/em&gt; interesting ways. (Not sure what F#&apos;s type providers are or what they&apos;ll do for you? Check out &lt;a href=&quot;http://channel9.msdn.com/Events/BUILD/BUILD2011/SAC-904T&quot;&gt;Don Syme&apos;s talk on it&lt;/a&gt; at BUILD last year.)&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Windows8 will generate a lot of chatter.&lt;/em&gt; As 2012 progresses, Microsoft will try to force a lot of buzz around it by keeping things under wraps until various points in the year that feel strategic (TechEd, BUILD, etc). In doing so, though, they will annoy a number of people by not talking about them more openly or transparently. What&apos;s more....&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Windows8 (&quot;Metro&quot;)-style apps won&apos;t impress at first.&lt;/em&gt; The more I think about it, the more I&apos;m becoming convinced that Metro-style apps on a desktop machine are going to collectively underwhelm. The UI simply isn&apos;t designed for keyboard-and-mouse kinds of interaction, and that&apos;s going to be the hardware setup that most people first experience Windows8 on--contrary to what (I think) Microsoft thinks, people do not just have tablets laying around waiting for Windows 8 to be installed on it, nor are they going to buy a Windows8 tablet just to try it out, at least not until it&apos;s gathered some mojo behind it. Microsoft is going to have to finesse the messaging here very, very finely, and that&apos;s not something they&apos;ve shown themselves to be particularly good at over the last half-decade.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Scala will get bigger, thanks to Heroku.&lt;/em&gt; With the adoption of Scala and Play for their Java apps, Heroku is going to make Scala look attractive as a development platform, and the adoption of Play by Typesafe (the same people who brought you Akka) means that these four--Heroku, Scala, Play and Akka--will combine into a very compelling and interesting platform. I&apos;m looking forward to seeing what comes of that.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Cloud will continue to whip up a lot of air.&lt;/em&gt; For all the hype and money spent on it, it doesn&apos;t really seem like cloud is gathering commensurate amounts of traction, across all the various cloud providers with the possible exception of Amazon&apos;s cloud system. But, as the different cloud platforms start to diversify their platform technology (Microsoft seems to be leading the way here, ironically, with the introduction of Java, Hadoop and some limited NoSQL bits into their Azure offerings), and as we start to get more experience with the pricing and costs of cloud, 2012 might be the year that we start to see mainstream cloud adoption, beyond &quot;just&quot; the usage patterns we&apos;ve seen so far (as a backing server for mobile apps and as an easy way to spin up startups).&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Android tablets will start to gain momentum.&lt;/em&gt; Amazon&apos;s Kindle Fire has hit the market strong, definitely better than any other Android-based tablet before it. The Nooq (the Kindle&apos;s principal competitor, at least in the e-reader world) is also an Android tablet, which means that right now, consumers can get into the Android tablet world for far, far less than what an iPad costs. Apple rumors suggest that they may have a 7&quot; form factor tablet that will price competitively (in the $200/$300 range), but that&apos;s just rumor right now, and Apple has never shown an interest in that form factor, which means the 7&quot; world will remain exclusively Android&apos;s (at least for now), and that&apos;s a nice form factor for a lot of things. This translates well into more sales of Android tablets in general, I think.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Apple will release an iPad 3, and it will be &quot;more of the same&quot;.&lt;/em&gt; Trying to predict Apple is generally a lost cause, particularly when it comes to their vaunted iOS lines, but somewhere around the middle of the year would be ripe for a new iPad, at the very least. (With the iPhone 4S out a few months ago, it&apos;s hard to imagine they&apos;d cannibalize those sales by releasing a new iPhone, until the end of the year at the earliest.) Frankly, though, I don&apos;t expect the iPad 3 to be all that big of a boost, just a faster processor, more storage, and probably about the same size. Probably the only thing I&apos;d want added to the iPad would be a USB port, but that conflicts with the Apple desire to present the iPad as a &quot;device&quot;, rather than as a &quot;computer&quot;. (USB ports smack of &quot;computers&quot;, not self-contained &quot;devices&quot;.)&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Apple will get hauled in front of the US government for... something.&lt;/em&gt; Apple&apos;s recent foray in the legal world, effectively informing Samsung that they can&apos;t make square phones and offering advice as to what will avoid future litigation, smacks of such hubris and arrogance, it makes Microsoft look like a Pollyanna Pushover by comparison. It is pretty much a given, it seems to me, that a confrontation in the legal halls is not far removed, either with the US or with the EU, over anti-cometitive behavior. (And if this kind of behavior continues, and there is no legal action, it&apos;ll be pretty apparent that Apple has a pretty good set of US Congressmen and Senators in their pocket, something they probably learned from watching Microsoft and IBM slug it out rather than just buy them off.)&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;IBM will be entirely irrelevant again.&lt;/em&gt; Look, IBM&apos;s main contribution to the Java world is/was Eclipse, and to a much lesser degree, Harmony. With Eclipse more or less &quot;done&quot; (aside from all the work on plugins being done by third parties), and with IBM abandoning Harmony in favor of OpenJDK, IBM more or less removes themselves from the game, as far as developers are concerned. Which shouldn&apos;t really be surprising--they&apos;ve been more or less irrelevant pretty much ever since the mid-2000s or so.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Oracle will &quot;screw it up&quot; at least once.&lt;/em&gt; Right now, the Java community is poised, like a starving vulture, waiting for Oracle to do something else that demonstrates and befits their Evil Emperor status. The community has already been quick (far too quick, if you ask me) to highlight Oracle&apos;s supposed missteps, such as the JVM-crashing bug (which has already been fixed in the _u1 release of Java7, which garnered no attention from the various Java news sites) and the debacle around Hudson/Jenkins/whatever-the-heck-we-need-to-call-it-this-week. I&apos;ll grant you, the Hudson/Jenkins debacle was deserving of ire, but Oracle is hardly the Evil Emperor the community makes them out to be--at least, so far. (I&apos;ll admit it, though, I&apos;m a touch biased, both because Brian Goetz is a friend of mine and because Oracle TechNet has asked me to write a column for them next year. Still, in the spirit of &quot;innocent until proven guilty&quot;....)&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;VMWare/SpringSource will start pushing their cloud solution in a major way.&lt;/em&gt; Companies like Microsoft and Google are pushing cloud solutions because Software-as-a-Service is a reoccurring revenue model, generating revenue even in years when the product hasn&apos;t incremented. VMWare, being a product company, is in the same boat--the only time they make money is when they sell a new copy of their product, unless they can start pushing their virtualization story onto hardware on behalf of clients--a.k.a. &quot;the cloud&quot;. With SpringSource as the software stack, VMWare has a more-or-less complete cloud play, so it&apos;s surprising that they didn&apos;t push it harder in 2011; I suspect they&apos;ll start cramming it down everybody&apos;s throats in 2012. Expect to see Rod Johnson talking a lot about the cloud as a result.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;JavaScript hype will continue to grow, and by years&apos; end will be at near-backlash levels.&lt;/em&gt; JavaScript (more properly known as ECMAScript, not that anyone seems to care but me) is gaining all kinds of steam as a mainstream development language (as opposed to just-a-browser language), particularly with the release of NodeJS. That hype will continue to escalate, and by the end of the year we may start to see a backlash against it. (Speaking personally, NodeJS is an interesting solution, but suggesting that it will replace your Tomcat or IIS server is a bit far-fetched; event-driven I/O is something both of those servers have been doing for years, and the rest of it is &quot;just&quot; a language discussion. We could pretty easily use JavaScript as the development language inside both servers, as Sun demonstrated years ago with their &quot;Phobos&quot; project--not that anybody really cared back then.)&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;NoSQL buzz will continue to grow, and by years&apos; end will start to generate a backlash.&lt;/em&gt; More and more companies are jumping into NoSQL-based solutions, and this trend will continue to accelerate, until some extremely public failure will start to generate a backlash against it. (This seems to be a pattern that shows up with a lot of technologies, so it seems entirely realistic that it&apos;ll happen here, too.) Mind you, I don&apos;t mean to suggest that the backlash will be factual or correct--usually these sorts of things come from misuing the tool, not from any intrinsic failure in it--but it&apos;ll generate some bad press.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Ted will thoroughly rock the house during his CodeMash keynote.&lt;/em&gt; Yeah, OK, that&apos;s more of a fervent wish than a prediction, but hey, keep a positive attitude and all that, right?&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Ted will continue to enjoy his time working for Neudesic.&lt;/em&gt; So far, it&apos;s been great working for these guys, and I&apos;m looking forward to a great 2012 with them. (Hopefully this will be a prediction I get to tack on for many years to come, too.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope that all of you have enjoyed reading these, and I wish you and yours a very merry, happy, profitable and fulfilling 2012. Thanks for reading.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2011 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2011/2011-tech-predictions.html</link>
      <pubDate>Sat, 1 Jan 2011 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2011/2011-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;Here we go again: the annual review of last year&apos;s predictions, and a set of new ones for the new year.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Long-time readers of this blog know what’s coming next: it’s time for Ted to prognosticate on what the coming year of tech will bring us. But I believe strongly in accountability, even in my offered-up-for-free predictions, so one of the traditions of this space is to go back and revisit my predictions from this time last year. So, without further ado, let’s look back at &lt;a href=&quot;../2010/2010-tech-predictions.html&quot;&gt;Ted’s 2010 predictions&lt;/a&gt;, and see how things played out; 2010 predictions are prefixed with “THEN”, and my thoughts on my predictions are prefixed with “NOW”:&lt;/p&gt;  &lt;p&gt;For 2010, I predicted....&lt;/p&gt;
&lt;ul&gt;   &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;... I will offer 3- and 4-day training classes on F# and Scala, among other things.&lt;/em&gt; OK, that&apos;s not fair—yes, I have the materials, I just need to work out locations and times. Contact me if you&apos;re interested in a private class, by the way.&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Well, I offered them… I just didn’t do much to advertise them or sell them. I got plenty busy just with the other things I had going on. Besides, this and the next prediction were pretty much all advertisement anyway, so I don’t know if anybody really counts these two.&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;... I will publish two books, one on F# and one on Scala.&lt;/em&gt; OK, OK, another plug. Or, rather, more of a resolution. One will be the &amp;quot;Professional F#&amp;quot; I&apos;m doing for Wiley/Wrox, the other isn&apos;t yet finalized. But it&apos;ll either be published through a publisher, or self-published, by JavaOne 2010. &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; “Professional F# 2.0” shipped in Q3 of 2010; the other Scala book I decided not to pursue—too much stuff going on to really put the necessary time into it. (Cue sad trombone.)&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;... DSLs will either &amp;quot;succeed&amp;quot; this year, or begin the short slide into the dustbin of obscure programming ideas.&lt;/em&gt; Domain-specific language advocates have to put up some kind of strawman for developers to learn from and poke at, or the whole concept will just fade away. Martin&apos;s book will help, if it ships this year, but even that might not be enough to generate interest if it doesn&apos;t have some kind of large-scale applicability in it. Patterns and refactoring and enterprise containers all had a huge advantage in that developers could see pretty easily what the problem was they solved; DSLs haven&apos;t made that clear yet. &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; To be honest, this one is hard to call. Martin Fowler published his DSL book, which many people consider to be a good sign of what’s happening in the world, but really, the DSL buzz seems to have dropped off significantly. The strawman hasn’t appeared in any meaningful public way (I still don’t see an example being offered up from anybody), and that leads me to believe that the fading-away has started.&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;... functional languages will start to see a backlash.&lt;/em&gt; I hate to say it, but &amp;quot;getting&amp;quot; the functional mindset is hard, and there&apos;s precious few resources that are making it easy for mainstream (read: O-O) developers make that adjustment, far fewer than there was during the procedural-to-object shift. If the functional community doesn&apos;t want to become mainstream, then mainstream developers will find ways to take functional&apos;s most compelling gateway use-case (parallel/concurrent programming) and find a way to &amp;quot;git &apos;er done&amp;quot; in the traditional O-O approach, probably through software transactional memory, and functional languages like Haskell and Erlang will be relegated to the &amp;quot;What Might Have Been&amp;quot; of computer science history. Not sure what I mean? Try this: walk into a functional language forum, and ask what a monad is. Nobody yet has been able to produce an answer that doesn&apos;t involve math theory, or that does involve a practical domain-object-based example. In fact, nobody has really said why (or if) monads are even still useful. Or catamorphisms. Or any of the other dime-store words that the functional community likes to toss around. &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; I think I have to admit that this hasn’t happened—at least, there’s been no backlash that I’ve seen. In fact, what’s interesting is that there’s been some movement to bring those functional concepts—including monads, which surprised me completely—into other languages like C# or Java for discussion and use. That being said, though, I don’t see Haskell and Erlang taking center stage as application languages—instead, I see them taking supporting-cast kinds of roles building other infrastructure that applications in turn make use of, a la CouchDB (written in Erlang). Monads still remain a mostly-opaque subject for most developers, however, and it’s still unclear if monads are something that people should think about applying in code, or if they are one of those “in theory” kinds of concepts. (You know, one of those ideas that change your brain forever, but you never actually use directly in code.)&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;... Visual Studio 2010 will ship on time, and be one of the buggiest and/or slowest releases in its history.&lt;/em&gt; I hate to make this prediction, because I really don&apos;t want to be right, but there&apos;s just so much happening in the Visual Studio refactoring effort that it makes me incredibly nervous. Widespread adoption of VS2010 will wait until SP1 at the earliest. In fact.... &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;NOW: &lt;/strong&gt;Wow, did I get a few people here in Redmond annoyed with me about that one. And, as it turned out, I was pretty off-base about its stability. (It shipped pretty close if not exactly on the ship date Microsoft promised, as I recall, though I admit I wasn’t paying too much attention to it.)&amp;#160; I’ve been using VS 2010 for a lot of .NET work in the last six months, and I’ve yet (knock on wood) to have it crash on me. /bow Visual Studio team.&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;... Visual Studio 2010 SP 1 will ship within three months of the final product.&lt;/em&gt; Microsoft knows that people wait until SP 1 to think about upgrading, so they&apos;ll just plan for an eager SP 1 release, and hope that managers will be too hung over from the New Year (still) to notice that the necessary shakeout time hasn&apos;t happened. &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Uh…. nope. In fact, SP 1 has just reached a beta/CTP state. As for managers being too hung over, well…&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;... Apple will ship a tablet with multi-touch on it, and it will flop horribly.&lt;/em&gt; Not sure why I think this, but I just don&apos;t think the multi-touch paradigm that Apple has cooked up for the iPhone will carry over to a tablet/laptop device. That won&apos;t stop them from shipping it, and it won&apos;t stop Apple fan-boiz from buying it, but that&apos;s about where the interest will end. &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Oh, WOW did I come so close and yet missed the mark by a mile. Of course, the “tablet” that Apple shipped was the iPad, and it did pretty much everything &lt;em&gt;except&lt;/em&gt; flop horribly. Apple fan-boys bought it… and then about 24 hours later, so did everybody else. My &lt;em&gt;mom&lt;/em&gt; got one, for crying out loud. And folks, the iPad—along with the whole “slate” concept—is pretty clearly here to stay.&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;... JDK 7 closures will be debated for a few weeks, then become a fait accompli as the Java community shrugs its collective shoulders.&lt;/em&gt; Frankly, I think the Java community has exhausted its interest in debating new language features for Java. Recent college grads and open-source groups with an axe to grind will continue to try and make an issue out of this, but I think the overall Java community just... doesn&apos;t... care. They just want to see JDK 7 ship someday. &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Pretty close—except that closures won’t ship as part of JDK 7, largely due to the Oracle acquisition in the middle of the year here. And I was spot-on vis-à-vis the “they want to see JDK 7 ship someday”; when given the chance to wait for a year or so for a Java-with-closures to ship, the community overwhelmingly voted to get something sooner rather than later.&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;... Scala either &amp;quot;pops&amp;quot; in 2010, or begins to fall apart.&lt;/em&gt; By &amp;quot;pops&amp;quot;, I mean reaches a critical mass of developers interested in using it, enough to convince somebody to create a company around it, a la G2One. &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; … and by “somebody”, it turns out I meant Martin Odersky. Scala is pretty clearly a hot topic in the Java space, its buzz being disturbed only by Clojure. Scala and/or Clojure, plus Groovy, makes a really compelling JVM-based stack.&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;... Oracle is going to make a serious &amp;quot;cloud&amp;quot; play, probably by offering an Oracle-hosted version of Azure or AppEngine.&lt;/em&gt; Oracle loves the enterprise space too much, and derives too much money from it, to not at least appear to have some kind of offering here. Now that they own Java, they&apos;ll marry it up against OpenSolaris, the Oracle database, and throw the whole thing into a series of server centers all over the continent, and call it &amp;quot;Oracle 12c&amp;quot; (c for Cloud, of course) or something. &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Oracle made a play, but it was to continue to enhance Java, not build a cloud space. It surprises me that they haven’t made a more forceful move in this space, but I suspect that a huge amount of time and energy went into folding Sun into their corporate environment.&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;... Spring development will slow to a crawl and start to take a left turn toward cloud ideas.&lt;/em&gt; VMWare bought SpringSource for a reason, and I believe it&apos;s entirely centered around VMWare&apos;s movement into the cloud space—they want to be more than &amp;quot;just&amp;quot; a virtualization tool. Spring + Groovy makes a compelling development stack, particularly if VMWare does some interesting hooks-n-hacks to make Spring a virtualization environment in its own right somehow. But from a practical perspective, any community-driven development against Spring is all but basically dead. The source may be downloadable later, like the VMWare Player code is, but making contributions back? Fuhgeddabowdit. &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; The Spring One show definitely played up Cloud stuff, and springsource.com seems to be emphasizing cloud more in a couple of subtle ways. Not sure if I call this one a win or not for me, though.&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;... the explosion of e-book readers brings the Kindle 2009 edition way down to size.&lt;/em&gt; The era of the e-book reader is here, and honestly, while I&apos;m glad I have a Kindle, I&apos;m expecting that I&apos;ll be dusting it off a shelf in a few years. Kinda like I do with my iPods from a few years ago. &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Honestly, can’t say that I’m using my Kindle a lot, but I am reading using the Kindle app on non-Kindle hardware more than I thought I would be. That said, I am eyeing the new Kindle hardware generation with an acquisitive eye…&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;... &amp;quot;social networking&amp;quot; becomes the &amp;quot;Web 2.0&amp;quot; of 2010.&lt;/em&gt; In other words, using the term will basically identify you as a tech wannabe and clearly out of touch with the bleeding edge. &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;NOW: &lt;/strong&gt;Um…. yeah.&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;... Facebook becomes a developer platform requirement.&lt;/em&gt; I don&apos;t pretend to know anything about Facebook—I&apos;m not even on it, which amazes my family to no end—but clearly Facebook is one of those mechanisms by which people reach each other, and before long, it&apos;ll start showing up as a developer requirement for companies looking to hire. If you&apos;re looking to build out your resume to make yourself attractive to companies in 2010, mad Facebook skillz might not be a bad investment. &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; I’m on Facebook, I’ve written some code for it, and given how much the startup scene loves the “Like” button, I think developers who knew Facebook in 2010 did pretty well for themselves.&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;... Nintendo releases an open SDK for building games for its next-gen DS-based device.&lt;/em&gt; With the spectacular success of games on the iPhone, Nintendo clearly must see that they&apos;re missing a huge opportunity every day developers can&apos;t write games for the Nintendo DS that are easily downloadable to the device for playing. Nintendo is not stupid—if they don&apos;t open up the SDK and promote &amp;quot;casual&amp;quot; games like those on the iPhone and those that can now be downloaded to the Zune or the XBox, they risk being marginalized out of existence.&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;NOW:&lt;/strong&gt; Um… yeah. Maybe this was me just being hopeful.&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;In general, it looks like I was more right than wrong, which is not a bad record to have. Of course, a couple of those “wrong”s were “giving up the big play” kind of wrongs, so while I may have a winning record, I still may have a defense that’s given up too many points to be taken seriously. *shrug* Oh, well.&lt;/p&gt;  &lt;p&gt;What portends for 2011?&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;em&gt;Android’s penetration into the mobile space is going to rise, then plateau around the middle of the year.&lt;/em&gt; Android phones, collectively, have outpaced iPhone sales. That’s a pretty significant statistic—and it means that there’s fewer customers buying smartphones in the coming year. More importantly, the first generation of Android slates (including the Galaxy Tab, which I own), are less-than-sublime, and not really an “iPad Killer” device by any stretch of the imagination. And I think that will slow down people buying Android slates and phones, particularly since Google has all but promised that Android releases will start slowing down.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;Windows Phone 7 penetration into the mobile space will appear huge, then slow down towards the middle of the year.&lt;/em&gt; Microsoft is getting some pretty decent numbers now, from what I can piece together, and I think that’s largely the “I love Microsoft” crowd buying in. But it’s a pretty crowded place right now with Android and iPhone, and I’m not sure if the much-easier Office and/or Exchange integration is enough to woo consumers (who care about Office) or business types (who care about Exchange) away from their Androids and iPhones.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;Android, iOS and/or Windows Phone 7 becomes a developer requirement.&lt;/em&gt; Developers, if you haven’t taken the time to learn how to program one of these three platforms, you are electing to remove yourself from a growing market that desperately wants people with these skills. I see the “mobile native app development” space as every bit as hot as the “Internet/Web development” space was back in 2000. If you don’t have a device, buy one. If you have a device, get the tools—in all three cases they’re free downloads—and start writing stupid little apps that nobody cares about, so you can have some skills on the platform when somebody cares about it.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;The Windows 7 slates will suck.&lt;/em&gt; This isn’t a prediction, this is established fact. I played with an “ExoPC” 10” form factor slate running Windows 7 (Dell I think was the manufacturer), and it was a horrible experience. Windows 7, like most OSes, really expects a keyboard to be present, and a slate doesn’t have one—so the OS was hacked to put a “keyboard” button at the top of the screen that would slide out to let you touch-type on the slate. I tried to fire up Notepad and type out a haiku, and it was an unbelievably awkward process. Android and iOS clearly own the slate market for the forseeable future, and if Dell has any brains in its corporate head, it will phone up Google tomorrow and start talking about putting Android on that hardware.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;DSLs mostly disappear from the buzz.&lt;/em&gt; I still see no strawman (no “pet store” equivalent), and none of the traditional builders-of-strawmen (Microsoft, Oracle, etc) appear interested in DSLs much anymore, so I think 2010 will mark the last year that we spent any time talking about the concept.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;Facebook becomes more of a developer requirement than before.&lt;/em&gt; I don’t like Mark Zuckerburg. I don’t like Facebook’s privacy policies. I don’t particularly like the way Facebook approaches the Facebook Connect experience. But Facebook owns enough people to be the fourth-largest nation on the planet, and probably commands an economy of roughly that size to boot. If your app is aimed at the Facebook demographic (that is, everybody who’s not on Twitter), you have to know how to reach these people, and that means developing at least some part of your system to integrate with it.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;Twitter becomes more of a developer requirement, too.&lt;/em&gt; Anybody who’s not on Facebook is on Twitter. Or dead. So to reach the other half of the online community, you have to know how to connect out with Twitter.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;XMPP becomes more of a developer requirement.&lt;/em&gt; XMPP hasn’t crossed a lot of people’s radar screen before, but Facebook decided to adopt it as their chat system communication protocol, and Google’s already been using it, and suddenly there’s a whole lotta traffic going over XMPP. More importantly, it offers a two-way communication experience that is in some scenarios vastly better than what HTTP offers, yet running in a very “Internet-friendly” way just as HTTP does. I suspect that XMPP is going to start cropping up in a number of places as a useful alternative and/or complement to using HTTP.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;“Gamification” starts making serious inroads into non-gaming systems.&lt;/em&gt; Maybe it’s just because I’ve been talking more about gaming, game design, and game implementation last year, but all of a sudden “gamification”—the process of putting game-like concepts into non-game applications—is cresting in a big way. FourSquare, Yelp, Gowalla, suddenly all these systems are offering achievement badges and scoring systems for people who want to play in their worlds. How long is it before a developer is pulled into a meeting and told that “we need to put achievement badges into the call-center support application”? Or the online e-commerce portal? It’ll start either this year or next.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;Functional languages will hit a make-or-break point.&lt;/em&gt; I know, I said it last year. But the buzz keeps growing, and when that happens, it usually means that it’s either going to reach a critical mass and explode, or it’s going to implode—and the longer the buzz grows, the faster it explodes or implodes, accordingly. My personal guess is that the “F/O hybrids”—F#, Scala, etc—will continue to grow until they explode, particularly since the suggested v.Next changes to both Java and C# have to be done as language changes, whereas futures for F# frequently are either built as libraries masquerading as syntax (such as asynchronous workflows, introduced in 2.0) or as back-end library hooks that anybody can plug in (such as type providers, introduced at PDC a few months ago), neither of which require any language revs—and no concerns about backwards compatibility with existing code. This makes the F/O hybrids vastly more flexible and stable. In fact, I suspect that within five years or so, we’ll start seeing a gradual shift away from pure O-O systems, into systems that use a lot more functional concepts—and that will propel the F/O languages into the center of the developer mindshare.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;The Microsoft Kinect will lose its shine.&lt;/em&gt; I hate to say it, but I just don’t see where the excitement is coming from. Remember when the Wii nunchucks were the most amazing thing anybody had ever seen? Frankly, after a slew of initial releases for the Wii that made use of them in interesting ways, the buzz has dropped off, and more importantly, the nunchucks turned out to be just another way to move an arrow around on the screen—in other words, we haven’t found particularly novel and interesting/game-changing ways to use the things. That’s what I think will happen with the Kinect. Sure, it’s really freakin’ cool that you can use your body as the controller—but how precise is it, how quickly can it react to my body movements, and most of all, what new user interface metaphors are people going to have to come up with in order to avoid the “me-too” dancing-game clones that are charging down the pipeline right now?&lt;/li&gt;    &lt;li&gt;&lt;em&gt;There will be no clear victor in the Silverlight-vs-HTML5 war.&lt;/em&gt; And make no mistake about it, a war is brewing. Microsoft, I think, finds itself in the inenviable position of having two very clearly useful technologies, each one’s “sphere of utility” (meaning, the range of answers to the “where would I use it?” question) very clearly overlapping. It’s sort of like being a football team with both Brett Favre and Tom Brady on your roster—both of them are superstars, but you &lt;em&gt;know&lt;/em&gt;, deep down, that you have to cut one, because you can’t devote the same degree of time and energy to both. Microsoft is going to take most of 2011 and probably part of 2012 trying to support both, making a mess of it, offering up conflicting rationale and reasoning, in the end achieving nothing but confusing developers and harming their relationship with the Microsoft developer community in the process. Personally, I think Microsoft has no choice but to get behind HTML 5, but I like a lot of the features of Silverlight and think that it has a lot of mojo that HTML 5 lacks, and would actually be in favor of Microsoft keeping both—so long as they make it &lt;em&gt;very&lt;/em&gt; clear to the developer community when and where each should be used. In other words, the executives in charge of each should be locked into a room and not allowed out until they’ve hammered out a business strategy that is then printed and handed out to every developer within a 3-continent radius of Redmond. (Chances of this happening: .01%)&lt;/li&gt;    &lt;li&gt;&lt;em&gt;Apple starts feeling the pressure to deliver a developer experience that isn’t mired in mid-90’s metaphor.&lt;/em&gt; Don’t look now, Apple, but a lot of software developers are coming to your platform from Java and .NET, and they’re bringing their expectations for what and how a developer IDE should look like, perform, and do, with them. Xcode is not a modern IDE, all the Apple fan-boy love for it notwithstanding, and this means that a few things will happen:&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;em&gt;Eclipse gets an iOS plugin.&lt;/em&gt; Yes, I know, it wouldn’t work (for the most part) on a Windows-based Eclipse installation, but if Eclipse can have a native C/C++ developer experience, then there’s no reason why a Mac Eclipse install couldn’t have an Objective-C plugin, and that opens up the idea of using Eclipse to write iOS and/or native Mac apps (which will be critical when the Mac App Store debuts somewhere in 2011 or 2012).&lt;/li&gt;      &lt;li&gt;&lt;em&gt;Rumors will abound about Microsoft bringing Visual Studio to the Mac&lt;/em&gt;. Silverlight already runs on the Mac; why not bring the native development experience there? I’m not saying they’ll actually do it, and certainly not in 2011, but the rumors, they will be flyin….&lt;/li&gt;      &lt;li&gt;&lt;em&gt;Other third-party alternatives to Xcode will emerge and/or grow.&lt;/em&gt; MonoTouch is just one example. There’s opportunity here, just as the fledgling Java IDE market looked back in ‘96, and people will come to fill it.&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;em&gt;NoSQL buzz grows.&lt;/em&gt; The NoSQL movement, which sort of got started last year, will reach significant states of buzz this year. NoSQL databases have a lot to offer, particularly in areas that relational databases are weak, such as hierarchical kinds of storage requirements, for example. That buzz will reach a fever pitch this year, and the relational database moguls (Microsoft, Oracle, IBM) will start to fight back.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I could probably go on making a few more, but I think these are enough to get me into trouble for the year.&lt;/p&gt;  &lt;p&gt;To all of you who’ve been readers of this blog for the past year, I thank you—blog-gathered statistics tell me that I get, on average, about 7,000 hits a day, which just stuns me—and it is a New Years’ Resolution that I blog more and give you even more reason to stick around. Happy New Year, and may your 2011 be just as peaceful, prosperous, and eventful as you want it to be.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Death to Best Practices</title>
      <link>http://blogs.newardassociates.com/blog/2010/death-to-best-practices.html</link>
      <pubDate>Tue, 10 Aug 2010 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2010/death-to-best-practices.html</guid>
      	<description>
	&lt;p&gt;Can we please put the whole term “Best Practices” to rest now? Apparently, according to &lt;a href=&quot;http://timberry.bplans.com/2010/07/the-sad-truth-about-best-practices.html&quot;&gt;this link&lt;/a&gt; (forwarded to me by John Dietz, thanks!), the very place where it originated (or was best popularized, depending on your interpretation of history) has now seen the whole concept basically debunked:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;For example, Jim Collins’ blockbuster business book &lt;a href=&quot;http://www.amazon.com/exec/obidos/ASIN/0066620996/wwwtimberryco-20&quot;&gt;Good to Great&lt;/a&gt;, published in 2001, featured 11 supposedly great companies. All of them did extraordinarily well on the stock market for 10-20 years. But by 2008, when Steven Levitt posted &lt;a href=&quot;http://freakonomics.blogs.nytimes.com/2008/07/28/from-good-to-great-to-below-average/&quot;&gt;Good to Great to Below Average&lt;/a&gt; on Freakonomics, two of them had died.      &lt;br /&gt;(&lt;em&gt;Read more: &lt;/em&gt;&lt;a href=&quot;http://timberry.bplans.com/2010/07/the-sad-truth-about-best-practices.html#ixzz0wBOxDrkh&quot;&gt;&lt;em&gt;http://timberry.bplans.com/2010/07/the-sad-truth-about-best-practices.html#ixzz0wBOxDrkh&lt;/em&gt;&lt;/a&gt;)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The point is, best practices just don’t exist. They are an attempt to take a solution to a problem out of the context and apply them across the entire spectrum, and that essentially invalidates the entire thing. A solution is only useful when considered in context.&lt;/p&gt;  &lt;p&gt;Don’t believe me? Consider this challenge: when is it &lt;em&gt;not&lt;/em&gt; a best practice to breathe? When you’re under water, of course.&lt;/p&gt;  &lt;p&gt;(Unless you’re a fish. Or a frog. Or maybe a prince turned into a frog.)&lt;/p&gt;  &lt;p&gt;Point is… context matters, folks.&lt;/p&gt;  &lt;p&gt;Blind application of best practices don’t work, as Tim Berry’s article quotes from Jim Collins’ book (my emphasis):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Nine of the eleven companies remain more or less intact. Of these, Nucor is the only one that has dramatically outperformed the stock market since the book came out. Abbott Labs and Wells Fargo have done okay. &lt;em&gt;Overall, a portfolio of the “good to great” companies looks like it would have underperformed the S&amp;amp;P 500.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Still think that the “best practices” idea might work? Prove it to yourself: do a detailed study of CEO performance across any given CEO’s career and across a variety of different companies who changed CEOs. In short windows, yes, you can find scenarios where a CEO had a stellar performance with a particular company for a particular period of time. But when you pan back and look across the CEO’s entire career (during which he/she practiced the same “best practices” at different firms), almost none of them have repeatable successes at a variety of different firms in any consistent manner (despite the millions handed to them).&lt;/p&gt;  &lt;p&gt;In other words, for a good many of them, their success was nothing but blind luck. A monkey could have done just as well. The “superstar CEO” is generally a product of the five or so years in which his one firm was wildly successful.&amp;#160; Attempts to repeat the success at other firms (that is, in a different context) typically have failed or generated mediocre results. (Anybody know what Lee Iacocca is up to these days, he of “I will rescue Chrysler” fame? Come to think of it, can anybody name any of the 70’s or 80’s “superstar CEOs” that is still wildly successful today? Just one?)&lt;/p&gt;  &lt;p&gt;How did this “best practices” thing get to be such a common meme? Because “best practices” mean, essentially, that the questioner doesn’t want to have to think. And it’s a seductive premise—if I just push the right buttons, type the right keywords, call the right methods and/or use the right classes, I can get something that “just works” without having to think about all those nasty little details that seem to trip people up: performance, scalability, security, blah blah blah.&lt;/p&gt;  &lt;p&gt;Here’s the dirty little secret of our industry: &lt;em&gt;Software development is hard.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Computer science is about tradeoffs and hard choices. Optimizing the code or design or architecture one way means taking hits another way. Trading static typing for dynamic typing means losing a set of already-written unit tests in exchange for a degree of flexibility in certain parts of the design. Using inheritance instead of parametric polymorphism offers some benefits but also adds some restrictions, and vice versa. Choosing an agile approach gains you greater feedback and closer connection to your customer (which typically means you’re closer to budget and critical features being completed on time), but requires more work and expertise to pull it off over other, more waterfall-ish, processes. And so on, and so on, and so on.&lt;/p&gt;  &lt;p&gt;Tim says this well:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Don’t ever just blindly follow. You always think about it, consider the options, how it might be different in your case, and then, if it still sounds good, try it. Carefully. &lt;/p&gt;    &lt;p&gt;If I ever give you any advice, I want you to please never take it without thinking first, analyzing, and deciding for yourself whether or not, and how, and to what extent what I say fits your situation. &lt;/p&gt;    &lt;p&gt;(&lt;em&gt;Read more: &lt;/em&gt;&lt;a href=&quot;http://timberry.bplans.com/2010/07/the-sad-truth-about-best-practices.html#ixzz0wBQU3yCB&quot;&gt;&lt;em&gt;http://timberry.bplans.com/2010/07/the-sad-truth-about-best-practices.html#ixzz0wBQU3yCB&lt;/em&gt;&lt;/a&gt;)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;But it’s not just the questioners’ fault: speakers, in their zeal to prove that they were smarter than everybody else, bought into the idea, too, because if I’m the one holding the “best practices”, then clearly I’m the one you want to come to with the development or consulting work. After all, who better to hire than the guy/gal with all the answers? In essence, we fed their addiction by tossing off “best practices” in pithy one-line answers (like “every class a service”) that turned out to be utter B/S pronounced by people who had, in some cases, never actually put that practice into practice for anything other than a demo or an example.&lt;/p&gt;  &lt;p&gt;It’s time to say “no” to “best practices”.&lt;/p&gt;  &lt;p&gt;Speakers: The next time somebody asks you for the “best practices” on a technology, respond with “The best practice you could &lt;em&gt;possibly&lt;/em&gt; employ is to hire me.” That, or else with “There are no such thing. You cannot answer a question about a problem outside of its context.”&lt;/p&gt;  &lt;p&gt;Attendees: The next time a speaker starts talking about “best practices”, walk out, because clearly the speaker is trying to feed you easy answers when in fact there are only hard choices.&lt;/p&gt;  &lt;p&gt;It’s time for our industry to break the habit of taking hits off the &lt;strike&gt;crack&lt;/strike&gt; best practices pipe, and start facing the fact that &lt;em&gt;software development is hard&lt;/em&gt;.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Architectural Katas</title>
      <link>http://blogs.newardassociates.com/blog/2010/architectural-katas.html</link>
      <pubDate>Thu, 17 Jun 2010 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2010/architectural-katas.html</guid>
      	<description>
	&lt;p&gt;By now, the Twitter messages have spread, and the word is out: at Uberconf this year, I did a session (&amp;quot;Pragmatic Architecture&amp;quot;), which I&apos;ve done at other venues before, but this time we made it into a 180-minute workshop instead of a 90-minute session, and the workshop included breaking the room up into small (10-ish, which was still a teensy bit too big) groups and giving each one an &amp;quot;architectural kata&amp;quot; to work on.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;The architectural kata is a take on PragDave&apos;s coding kata, except taken to a higher level: the architectural kata is an exercise in which the group seeks to create an architecture to solve the problem presented. The inspiration for this came from Frederick Brooks&apos; latest book, &lt;em&gt;The Design of Design&lt;/em&gt;, in which he points out that the only way to get great designers is to get them to design. The corollary, of course, is that in order to create great architects, we have to get them to architect. But few architects get a chance to architect a system more than a half-dozen times or so over the lifetime of a career, and that&apos;s only for those who are fortunate to be given the opportunity to architect in the first place. Of course, the problem here is, you have to be an architect in order to get hired as an architect, but if you&apos;re not an architect, then how can you architect in order to become an architect?&lt;/p&gt;
&lt;p&gt;Um... hang on, let me make sure I wrote that right.&lt;/p&gt;
&lt;p&gt;Anyway, the &amp;quot;rules&amp;quot; around the kata (which makes it more difficult to consume the kata but makes the scenario more realistic, IMHO):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;you may ask the instructor questions about the project&lt;/li&gt;
&lt;li&gt;you must be prepared to present a rough architectural vision of the project and defend questions about it&lt;/li&gt;
&lt;li&gt;you must be prepared to ask questions of other participants&apos; presentations&lt;/li&gt;
&lt;li&gt;you may safely make assumptions about technologies you don&apos;t know well as long as those assumptions are clearly defined and spelled out&lt;/li&gt;
&lt;li&gt;you may not assume you have hiring/firing authority over the development team&lt;/li&gt;
&lt;li&gt;any technology is fair game (but you must justify its use)&lt;/li&gt;
&lt;li&gt;any other rules, you may ask about&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The groups were given 30 minutes in which to formulate some ideas, and then three of them were given a few minutes to present their ideas and defend it against some questions from the crowd.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(&lt;strong&gt;UPDATE 2021:&lt;/strong&gt; The full list of katas is available at the &lt;a href=&quot;http://www.architecturalkatas.com&quot;&gt;architectural katas website&lt;/a&gt;, and available for forking as a repository from my &lt;a href=&quot;https://github.com/tedneward/ArchKatas&quot;&gt;Github&lt;/a&gt;. The website code is available &lt;a href=&quot;https://github.com/tedneward/ArchKatasCode&quot;&gt;here&lt;/a&gt; for those who&apos;d like to play with it, but it&apos;s pretty simple and probably much better re-thought from the ground up.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;An example kata is below:&lt;/p&gt;
&lt;blockquote&gt;
**Architectural Kata #5: I&apos;ll have the BLT**
&lt;p&gt;a national sandwich shop wants to enable &amp;quot;fax in your order&amp;quot; but over the Internet instead&lt;/p&gt;
&lt;p&gt;users: millions+&lt;/p&gt;
&lt;p&gt;requirements: users will place their order, then be given a time to pick up their sandwich and directions to the shop (which must integrate with Google Maps); if the shop offers a delivery service, dispatch the driver with the sandwich to the user; mobile-device accessibility; offer national daily promotionals/specials; offer local daily promotionals/specials; accept payment online or in person/on delivery&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As you can tell, it&apos;s vague in some ways, and this is somewhat deliberate--as one group discovered, part of the architect&apos;s job is to ask questions of the project champion (me), and they didn&apos;t, and felt like they failed pretty miserably. (In their defense, the kata they drew--randomly--was pretty much universally thought to be the hardest of the lot.) But overall, the exercise was well-received, lots of people found it a great opportunity to try being an architect, and even the team that failed felt that it was a valuable exercise.&lt;/p&gt;
&lt;p&gt;I&apos;m definitely going to do more of these, and refine the whole thing a little. (Thanks to everyone who participated and gave me great feedback on how to make it better.) If you&apos;re interested in having it done as a practice exercise for your development team before the start of a big project, ping me. I think this would be a &lt;em&gt;great&lt;/em&gt; exercise to do during a user group meeting, too.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Code Kata: RoboStack</title>
      <link>http://blogs.newardassociates.com/blog/2010/code-kata-robostack.html</link>
      <pubDate>Mon, 10 May 2010 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2010/code-kata-robostack.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://codekata.pragprog.com/2007/01/code_katahow_it.html&quot; target=&quot;_blank&quot;&gt;Code Katas&lt;/a&gt; are small, relatively simple exercises designed to give you a problem to try and solve. I like to use them as a way to get my feet wet and help write something more interesting than &amp;quot;Hello World&amp;quot; but less complicated than &amp;quot;The Internet&apos;s Next Killer App&amp;quot;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;This one is from the &lt;a href=&quot;http://uva.onlinejudge.org/index.php?option=com_onlinejudge&amp;amp;Itemid=8&amp;amp;category=3&amp;amp;page=show_problem&amp;amp;problem=37&quot; target=&quot;_blank&quot;&gt;UVa online programming contest judge system&lt;/a&gt;, which I discovered after picking up the book &lt;em&gt;Programming Challenges&lt;/em&gt;, which is highly recommended as a source of code katas, by the way. Much of the advice parts of the book can be skimmed or ignored by the long-time professional developer, but it&apos;s still worth a read, since it can be an interesting source of ideas and approaches when solving real-world scenarios.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; You work for a manufacturing company, and they have just received their newest piece of super-modern hardware, a highly efficient assembly-line mechanized pneumatic item manipulator, also known in some circles as a &amp;quot;robotic arm&amp;quot;. It is driven by a series of commands, and your job is to write the software to drive the arm. The initial test will be to have the arm move a series of blocks around.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Context:&lt;/strong&gt; The test begins with &lt;em&gt;n&lt;/em&gt; number of blocks, laid out sequentially next to each other, each block with a number on it. (You may safely assume that &lt;em&gt;n&lt;/em&gt; never exceeds 25.) So, if &lt;em&gt;n&lt;/em&gt; is 4, then the blocks are laid out (starting from 0) as:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;0: 0&lt;/p&gt;    &lt;p&gt;1: 1&lt;/p&gt;    &lt;p&gt;2: 2&lt;/p&gt;    &lt;p&gt;3: 3&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The display output here is the block-numbered &amp;quot;slot&amp;quot;, then a colon, then the block(s) that are stacked in that slot, lowest to highest in left to right order. Thus, in the following display:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;0:&lt;/p&gt;    &lt;p&gt;1:&lt;/p&gt;    &lt;p&gt;2: 0 1 2 3&lt;/p&gt;    &lt;p&gt;3:&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The 3 block is stacked on top of the 2 block is stacked on top of the 1 block is stacked on top of the 0 block, all in slot 2. This can be shortened to the representation [0:, 1:, 2: 0 1 2 3, 3:] for conciseness.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The arm understands a number of different commands, as well as an optic sensor. (Yeah, the guys who created the arm were good enough to write code that knows how to read the number off a block, but not to actually drive the arm. Go figure.) The commands are as follows, where &lt;em&gt;a&lt;/em&gt; and &lt;em&gt;b&lt;/em&gt; are valid block numbers (meaning they are between 0 and &lt;em&gt;n&lt;/em&gt;-1):&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&amp;quot;move &lt;em&gt;a&lt;/em&gt; onto &lt;em&gt;b&lt;/em&gt;&amp;quot; This command orders the arm to find block &lt;em&gt;a&lt;/em&gt;, and return any blocks stacked on top of it to their original position. Do the same for block &lt;em&gt;b&lt;/em&gt;, then stack block &lt;em&gt;a&lt;/em&gt; on top of &lt;em&gt;b&lt;/em&gt;.&lt;/li&gt;    &lt;li&gt;&amp;quot;move &lt;em&gt;a&lt;/em&gt; over &lt;em&gt;b&lt;/em&gt;&amp;quot; This command orders the arm to find block &lt;em&gt;a&lt;/em&gt;, and return any blocks stacked on top of it to their original position. Then stack block &lt;em&gt;a&lt;/em&gt; on top of the stack of blocks containing &lt;em&gt;b&lt;/em&gt;.&lt;/li&gt;    &lt;li&gt;&amp;quot;pile &lt;em&gt;a&lt;/em&gt; onto &lt;em&gt;b&lt;/em&gt;&amp;quot; This command orders the arm to find the stack of blocks containing block &lt;em&gt;b&lt;/em&gt;, and return any blocks stacked on top of it to their original position. Then the arm must find the stack of blocks containing block &lt;em&gt;a&lt;/em&gt;, and take the stack of blocks starting from &lt;em&gt;a&lt;/em&gt; on upwards (in other words, don&apos;t do anything with any blocks on top of &lt;em&gt;a&lt;/em&gt;) and put that stack on top of block &lt;em&gt;b&lt;/em&gt;.&lt;/li&gt;    &lt;li&gt;&amp;quot;pile &lt;em&gt;a&lt;/em&gt; over &lt;em&gt;b&lt;/em&gt;&amp;quot; This command orders the arm to find the stack of blocks containing block &lt;em&gt;a&lt;/em&gt; and take the stack of blocks starting from &lt;em&gt;a&lt;/em&gt; on upwards (in other words, don&apos;t do anything with any blocks on top of &lt;em&gt;a&lt;/em&gt;) and put that stack on top of the stack of blocks containing block &lt;em&gt;b&lt;/em&gt; (in other words, don&apos;t do anything with the stack of blocks containing &lt;em&gt;b&lt;/em&gt;, either).&lt;/li&gt;    &lt;li&gt;&amp;quot;quit&amp;quot; This command tells the arm to shut down (and thus terminates the simulation).&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Note that if the input command sequence accidentally offers a command where &lt;em&gt;a&lt;/em&gt; and &lt;em&gt;b&lt;/em&gt; are the same value, that command is illegal and should be ignored.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;As an example, then, if we have 4 blocks in the state [0: 0, 1: 1, 2: 2, 3: 3], and run a &amp;quot;move 2 onto 3&amp;quot;, we get [0: 0, 1: 1, 2:, 3: 3 2]. If we then run a &amp;quot;pile 3 over 1&amp;quot;, we should end up with [0: 0, 1: 1 3 2, 2:, 3:]. And so on.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt; n = 10. Run these commands:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;move 9 onto 1&lt;/li&gt;    &lt;li&gt;move 8 over 1&lt;/li&gt;    &lt;li&gt;move 7 over 1&lt;/li&gt;    &lt;li&gt;move 6 over 1&lt;/li&gt;    &lt;li&gt;pile 8 over 6&lt;/li&gt;    &lt;li&gt;pile 8 over 5&lt;/li&gt;    &lt;li&gt;move 2 over 1&lt;/li&gt;    &lt;li&gt;move 4 over 9&lt;/li&gt;    &lt;li&gt;quit&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The result should be [0: 0, 1: 1 9 2 4, 2:, 3: 3, 4:, 5: 5 8 7 6, 6:, 7:, 8:, 9:]&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Challenges:&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Implement the Towers of Hanoi (or as close to it as you can get) using this system.&lt;/li&gt;    &lt;li&gt;Add an optimizer to the arm, in essence reading in the entire program (up to &amp;quot;quit&amp;quot;), finding shorter paths and/or different commands to achieve the same result.&lt;/li&gt;    &lt;li&gt;Add a visual component to the simulation, displaying the arm as it moves over each block and moves blocks around.&lt;/li&gt;    &lt;li&gt;Add another robotic arm, and allow commands to be given simultaneously. This will require some thought—does each arm execute a complete command before allowing the other arm to execute (which reduces the performance having two arms might offer), or can each arm act entirely independently? The two (or more) arms will probably need separate command streams, but you might try running them with one command stream just for grins. Note that deciding how to synchronized the arms so they don&apos;t conflict with one another will probably require adding some kind of synchronization instructions into the stream as well.&lt;/li&gt; &lt;/ul&gt;

	</description>
    </item>
    <item>
      <title>Code Kata: Compressing Lists</title>
      <link>http://blogs.newardassociates.com/blog/2010/code-kata-compressing-lists.html</link>
      <pubDate>Thu, 6 May 2010 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2010/code-kata-compressing-lists.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://codekata.pragprog.com/2007/01/code_katahow_it.html&quot; target=&quot;_blank&quot;&gt;Code Katas&lt;/a&gt; are small, relatively simple exercises designed to give you a problem to try and solve. I like to use them as a way to get my feet wet and help write something more interesting than &amp;quot;Hello World&amp;quot; but less complicated than &amp;quot;The Internet&apos;s Next Killer App&amp;quot;.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;&lt;a href=&quot;http://richardminerich.com/2010/04/the-ted-neward-f-folding-challenge/&quot; target=&quot;_blank&quot;&gt;Rick Minerich&lt;/a&gt; mentioned this one on his blog already, but here is the original &amp;quot;problem&amp;quot;/challenge as it was presented to me and which I in turn shot to him over a Twitter DM:&lt;/p&gt;
&lt;p&gt;I have a list, say something like [4, 4, 4, 4, 2, 2, 2, 3, 3, 2, 2, 2, 2, 1, 1, 1, 5, 5], which consists of varying repetitions of integers. (We can assume that it&apos;s always numbers, and the use of the term &amp;quot;list&amp;quot; here is generic—it could be a list, array, or some other collection class, your choice.) The goal is to take this list of numbers, and &amp;quot;compress&amp;quot; it down into a (theoretically smaller) list of numbers in pairs, where the first of the pair is the occurrence number of the value, which is the second number. So, since the list above has four 4&apos;s, followed by three 2&apos;s, two 3&apos;s, four 2&apos;s, three 1&apos;s and two 5&apos;s, it should compress into [4, 4, 3, 2, 2, 3, 4, 2, 3, 1, 2, 5].&lt;/p&gt;
&lt;p&gt;This is a pretty easy challenge, but I wanted to try and solve it in a functional mindset, which the challenger had never seen before. I also thought it made for an interesting challenge for people who&apos;ve never programming in functional languages before, because it requires a very different approach than the imperative solution.&lt;/p&gt;
&lt;p&gt;Extensions to the kata (a.k.a. &amp;quot;extra credit&amp;quot;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How does the implementation change (if any) to generalize it to a list of any particular type? (Assume the list is of homogenous type—always strings, always ints, always whatever.)&lt;/li&gt;
&lt;li&gt;How does the implementation change (if any) to generalize it to a list of any type? (In other words, a list of strings, ints, Dates, whatever, mixed together within the list: [1, 1, &amp;quot;one&amp;quot;, &amp;quot;one&amp;quot;, &amp;quot;one&amp;quot;, ...] .)&lt;/li&gt;
&lt;li&gt;How does the implementation change (if any) to generate a list of two-item tuples (the first being the occurence, the second being the value) as the result instead? Are there significant advantages to this?&lt;/li&gt;
&lt;li&gt;How does the implementation change (if any) to parallelize/multi-thread it? For your particular language how many elements have to be in the list before doing so yields a significant payoff?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By the way, some of the extension questions make the Kata somewhat interesting even for the imperative/O-O developer; have at, and let me know what you think.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Don&apos;t Fear the dynamic/VARIANT/Reaper...</title>
      <link>http://blogs.newardassociates.com/blog/2010/dont-fear-the-dynamicvariantreaper.html</link>
      <pubDate>Sun, 14 Feb 2010 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2010/dont-fear-the-dynamicvariantreaper.html</guid>
      	<description>
	&lt;p&gt;A couple of days ago, a buddy of mine, Scott Hanselman, wrote &lt;a href=&quot;http://www.hanselman.com/blog/BackToBasicsC4MethodOverloadingAndDynamicTypes.aspx&quot; target=&quot;_blank&quot;&gt;a nice little intro to the &amp;quot;dynamic&amp;quot; type in C# 4.0&lt;/a&gt;. In particular, I like (though don&apos;t necessarily 100% agree with) his one-sentence summation of dynamic as &lt;em&gt;&amp;quot;There&apos;s no way for you or I to know the type of this now, compiler, so let&apos;s hope that the runtime figures it out.&amp;quot;&lt;/em&gt; It&apos;s an interesting characterization, but my disagreement with his characterization is not the point here, at least not of this particular blog entry.&lt;/p&gt;
&lt;p&gt;I&apos;ve been waiting for it for a while, ever since C# 4 was announced, and sure enough, here we go: Scott&apos;s blog is the victim of the &lt;em&gt;Static-Typing Fundamentalist&lt;/em&gt;, the bearded and grizzled veteran of the Static/Dynamic Code Wars, come out to proclaim the sins of dynamic programming, the evils of those who use(d) it, and why C#/C++/Java was so much better than Visual Basic/Ruby/Python/whatever. Be careful of these creatures. They rival Al-Qaeda in their ferocity and zeal, Fox News in their attention to detail and evidence, and George Bush in their pronouncements of gloom and doom for the future if we don&apos;t &lt;em&gt;act now and eliminate this evil&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Allow me to quote (liberally) from &lt;a href=&quot;http://robert-seder.myopenid.com/&quot; target=&quot;_blank&quot;&gt;Rob&lt;/a&gt;&apos;s &lt;a href=&quot;http://www.hanselman.com/blog/CommentView.aspx?guid=FC406BB6-2218-4481-A6BA-CD1E12994D74&quot; target=&quot;_blank&quot;&gt;comment on Scott&apos;s blog&lt;/a&gt;, and comment in turn as we go:  &lt;blockquote&gt;   It&apos;s such a shame that you promote this stuff. You should&apos;ve seen the horrific devastation that &amp;quot;Variant&amp;quot; caused in the old VB days. Variant single-handedly create job security for so many people since the late 90&apos;s, because of the horrible, horrible, horrible things that developers did with that ridiculous, 12-byte data type! &lt;/blockquote&gt;  I just love it when people make comments like &amp;quot;horrific devastation&amp;quot;. Nothing like a little hyperbole to liven things up! I mean, it didn&apos;t cause exceptions, it didn&apos;t make code hard to read, it didn&apos;t make it tricky for developers to modify and refactor safely, it leveled cities! burned forests! slaughtered kittens! and even worse, it was &lt;em&gt;12 bytes in size!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Never mind the fact that Visual Basic developers frequently churned out apps twice, three, five times faster than their C++ cousins did. (I know this—I was one of those C++ developers, and routinely mocked the VB guys across the hall for their crappy language and code.... until they built an app in a few days that I tried to build at home in C++ and gave up after two weeks. And all the damn thing did was basic dialogs-and-data kinds of stuff, too.)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This weak-typing with late-binding is just such a bad idea. I know you&apos;ll say &amp;quot;But wait, these are powerful tools that skilled developers can leverage!&amp;quot; - and maybe so, but 98% of the people that truly use these sorts of techniques out in the real world, are unskilled developers making a mess of software all across this great land, because the compiler is so forgiving.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ah, the &amp;quot;All Developers (Except Me) Are Idiots&amp;quot; argument. I love this one—-the hubris involved here is just too precious for words. I have no doubt that the author of this post, being (of course) the classically-trained object-oriented developer and therefore too smart/disciplined/experienced/whatever to fall into such a ridiculous temptation as to use dynamic typing, would never use this feature except in the Most Dire of Emergencies, but his fellow programmers, all of them being &lt;em&gt;much&lt;/em&gt; less disciplined/smart/trained/whatever than he is, will fall for the temptation and write code that levels cities! burns forests! kills kittens! and worse, uses 12 bytes! (Oh, wait, it&apos;s only 3 bytes, because dynamic is just a placeholder for an object reference, and all object references are 3 bytes in the CLR. Or at least they used to be—-I admit, I haven&apos;t checked in CLR 4.) Those poor souls, they won&apos;t have any hope! There they&apos;ll be, staring at Visual Studio, wanting &lt;em&gt;desperately&lt;/em&gt; to do the Right Thing, and that evil little programmer devil on their shoulder (probably wearing a T-shirt that says, &amp;quot;P3rl is l33t&amp;quot; or something equally blasphemous) will whisper, &amp;quot;You know, if you just make it a dynamic, you can get the compiler to shut up and you can go home early....&amp;quot;&lt;/p&gt;
&lt;p&gt;Oh, right—-sorry, I forgot. That devil will whisper, &amp;quot;You know, if you write this code in Visual Basic .NET, you can make the entire codebase Option Strict Off and Option Explicit Off, make the compiler shut up and you can go home early....&amp;quot; Hell, they&apos;ve been whispering &lt;em&gt;that&lt;/em&gt; bit of subversion since 2001. And ye Gods! The leveled cities! burned forests! cute little kitten bodies! all over the place! It&apos;s fortunate that we C# developers have kept all those Visual Basic developers on the straight-and-narrow path of &lt;strike&gt;true salvation&lt;/strike&gt; static typing.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is a huge step backwards for C#, in my opinion - and creates the same scenario VB always did - where it is so forgiving, that it allows developers to write horrible code and you won&apos;t so much as see a compiler warning!! I&apos;ve always tauted that C# was better, simply because it gave the developer &amp;quot;tough love&amp;quot;, and forced him/her to be better coder and to &amp;quot;make good choices&amp;quot;! :-)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ah, yes, the C# compiler and its &amp;quot;tough love&amp;quot;. The &amp;quot;prefer compile errors over runtime errors&amp;quot; argument, vis-a-vis Scott Meyers&apos; &amp;quot;Effective C++&amp;quot; circa 1994 or so. It&apos;s vastly preferable to see errors early, before the big demo in front of the VP/President/potential customer. (Anybody who disagrees with this obviously hasn&apos;t had a demo fail in front of a VP/President/potential customer.) How fortunate that the C# compiler catches all these ugly errors at compile-time, like&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;static void DoSomething()
{
    List&amp;lt;object&amp;gt; intList = new List&amp;lt;object&amp;gt;();
    intList.Add(5);
    string s = (string) intList[0];
    Console.WriteLine(s);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... because boy, that would be &lt;em&gt;embarrassing&lt;/em&gt; if it didn&apos;t. I mean, can you imagine the horror other disciplined/smart/experienced developers would feel if a lenient compiler actually allowed code like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;class Point
{
    internal int x;
    internal int y;
    public Point(int x, int y) { x = x; y = y; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;class Point
{
    internal int x;
    internal int y;
    public Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
    public override string ToString()
    { return String.Format(&amp;quot;({0},{1})&amp;quot;, x, y); }
}

static void DoSomething()
{
    Point pt = new Point(12, 12);
    pt.GetType()
        .GetField(&amp;quot;x&amp;quot;, BindingFlags.Instance | BindingFlags.NonPublic)
        .SetValue(pt, 24);
    Console.WriteLine(pt);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to compile? Cities! Forests! Kittens! Thank &lt;em&gt;God&lt;/em&gt; C# isn&apos;t that kind of lustfully promiscuous... I mean, &amp;quot;lenient&amp;quot;... compiler!&lt;/p&gt;
&lt;p&gt;(Now if only we could tout blog comment engines with spellcheck....)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Specific to this blog post, if you are doing somewhere where you can&apos;t even quantify what the data type that is coming back? Guess what, you&apos;ve got yourself a bad design.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Wow. There&apos;s just no arguing with that one. I mean, knowing the actual type on which the method is being dispatched is such a &lt;em&gt;huge&lt;/em&gt; part of the C# development experience:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;static void DoSomething()
{
    List&amp;lt;Point&amp;gt; ptList = new List&amp;lt;Point&amp;gt;();
    ptList.Add(new Point(12, 12));
    object o = ptList[0];
    Console.WriteLine(o.ToString());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Gah. Just the &lt;em&gt;thought&lt;/em&gt; of not knowing the concrete type on which the method is being dispatched gives me the heebie-jeebies.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Just because the framework allows you use weak-typing and late-binding, doesn&apos;t mean you should - nor should you endorse it&apos;s use, in my opinion.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Somebody better tell all those users of NHibernate, NUnit, Spring.NET, MEF and all those other Reflection-based tools... including WinForms, ASP.NET, WPF, Workflow and WCF, come to think about it... that they&apos;re using frameworks that clearly were designed by idiots. (The &lt;em&gt;gall&lt;/em&gt; of those people.)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I&apos;m just saying, it&apos;s a shame that popular &amp;quot;nerd celebrities&amp;quot; like you (and I mean zero offense by that!) - endorse all this loosey-goosey typing. I say that becuase I&apos;ve never seen a single case where weak typing or late binding: A) made a design better or B) where it didn&apos;t make the component or application worse, because it was a looser design.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&apos;m so glad you were here to set Scott and me straight, Rob. Because otherwise, we might actually get something done. God &lt;em&gt;forbid&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Little tidbits of thought for those who are still thinking about this one.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://olabini.com/blog/2008/06/fractal-programming/&quot; target=&quot;_blank&quot;&gt;Ola Bini describes the application of the right language at the right level of the stack&lt;/a&gt; as a three-layer pyramid.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Any C# or Java developer who&apos;s not writing unit tests to test their code &amp;quot;because the compiler will catch all those errors&amp;quot; and provide &amp;quot;tough love&amp;quot; needs to be fired. &lt;em&gt;Immediately.&lt;/em&gt; I cannot conceive of a situation where unit tests can be passed over in favor of static typing in a professionally-responsible development project. (Oh, don&apos;t mis-read that, I can see lots of situations where unit tests aren&apos;t necessary. But not on code that&apos;s going to reach Production.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The argument for the degree of static typing in C# or Java is completely indefensible compared to what statically-typed type-inferenced languages like Haskell, F# or Scala provide. And their syntax frequently looks like &lt;code&gt;let x = [ 1; 2; 3; 4; ]&lt;/code&gt;, which isn&apos;t all that far off from what a dynamically-typed language looks like, despite very very different things happening under the compiler&apos;s hood. Until you, the Statically-Typed Fundamentalist, have written code in a Haskell/ML-derived language, you have no right arguing the merits of static typing. (In fact, that&apos;s probably also true if you&apos;ve never written code in Ruby, Python, or PowerShell, either.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There&apos;s lots more arguments the Static-Typing Fundamentalist can throw, by the way. I&apos;m disappointed Rob never mentioned performance, for one—that&apos;s a classic line of attack, too. Never mind the fact that most of those guys are still looping down and doing other silly micro-optimizations because that&apos;s way C++ taught them to do it....&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Oh, and &lt;em&gt;never ever&lt;/em&gt; show the Static Typing Fundamentalist an XML document and using something like XPath to extract data from it. They inevitably fall into XML Schema and the &amp;quot;if we just write the schema flexibly enough&amp;quot; and.... The last time I did that.... I still visit his gravesite, all these years later, and it still hurts, losing him that way.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Java guys argued against dynamic typing for years, too... until they tried Groovy and JRuby and Clojure. Now.... not so much.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Peace out.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2010 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2010/2010-tech-predictions.html</link>
      <pubDate>Tue, 5 Jan 2010 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2010/2010-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;Here we go again: the annual review of last year&apos;s predictions, and a set of new ones for the new year.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Here we go again—another year, another set of predictions revisited and offered up for the next 12 months. And maybe, if I&apos;m feeling really ambitious, I&apos;ll take that shot I thought about last year and try predicting for the decade. Without further ado, I&apos;ll go back and revisit, unedited, my predictions for 2009 (&amp;quot;&lt;strong&gt;THEN&lt;/strong&gt;&amp;quot;), and pontificate on those subjects for 2010 before adding any new material/topics. Just for convenience, &lt;a href=&quot;http://blogs.tedneward.com/2009/2009-tech-predictions.html&quot; target=&quot;_blank&quot;&gt;here&apos;s a link back to last years&apos; predictions&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Last year&apos;s predictions went something like this (complete with basketball-scoring):&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&amp;quot;Cloud&amp;quot; will become the next &amp;quot;ESB&amp;quot; or &amp;quot;SOA&amp;quot;, in that it will be something that everybody will talk about, but few will understand and even fewer will do anything with. (Considering the widespread disparity in the definition of the term, this seems like a no-brainer.) &lt;strong&gt;NOW:&lt;/strong&gt; Oh, yeah. Straight up. I get two points for this one. Does &lt;em&gt;anyone&lt;/em&gt; have a working definition of &amp;quot;cloud&amp;quot; that applies to all of the major vendors&apos; implementations? &lt;em&gt;Ted, 2; Wrongness, 0&lt;/em&gt;.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;Interest in Scala will continue to rise, as will the number of detractors who point out that Scala is too hard to learn. &lt;strong&gt;NOW:&lt;/strong&gt; Two points for this one, too. Not a hard one, mind you, but one of those &amp;quot;pass-and-shoot&amp;quot; jumpers from twelve feet out. James Strachan even tweeted about this earlier today, pointing out this comparison. As more Java developers who think of themselves as smart people try to pick up Scala and fail, the numbers of sour grapes responses like &amp;quot;Scala&apos;s too complex, and who needs that functional stuff anyway?&amp;quot; will continue to rise in 2010. &lt;em&gt;Ted, 4; Wrongness, 0&lt;/em&gt;.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;THEN&lt;/strong&gt;: Interest in F# will continue to rise, as will the number of detractors who point out that F# is too hard to learn. (Hey, the two really are cousins, and the fortunes of one will serve as a pretty good indication of the fortunes of the other, and both really seem to be on the same arc right now.) &lt;strong&gt;NOW:&lt;/strong&gt; Interestingly enough, I haven&apos;t heard as many F# detractors as Scala detractors, possibly because I think F# hasn&apos;t really reached the masses of .NET developers the way that Scala has managed to find its way in front of Java developers. I think that&apos;ll change mighty quickly in 2010, though, once VS 2010 hits the streets. &lt;em&gt;Ted, 4; Wrongness 2&lt;/em&gt;.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;THEN&lt;/strong&gt;&lt;em&gt;:&lt;/em&gt; Interest in all kinds of functional languages will continue to rise, and more than one person will take a hint from Bob &amp;quot;crazybob&amp;quot; Lee and liken functional programming to AOP, for good and for ill. People who took classes on Haskell in college will find themselves reaching for their old college textbooks again. &lt;strong&gt;NOW:&lt;/strong&gt; Yep, I&apos;m claiming two points on this one, if only because a bunch of Haskell books shipped this year, and they&apos;ll be the last to do so for about five years after this. (By the way, does anybody still remember aspects?) But I&apos;m going the opposite way with this one now; yes, there&apos;s Haskell, and yes, there&apos;s Erlang, and yes, there&apos;s a lot of other functional languages out there, but who cares? They&apos;re hard to learn, they don&apos;t always translate well to other languages, and developers want languages that work on the platform they use on a daily basis, and that means F# and Scala or Clojure, or its simply not an option. &lt;em&gt;Ted 6; Wrongness 2&lt;/em&gt;.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;THEN&lt;/strong&gt;&lt;em&gt;:&lt;/em&gt; The iPhone is going to be hailed as &amp;quot;the enterprise development platform of the future&amp;quot;, and companies will be rolling out apps to it. Look for Quicken iPhone edition, PowerPoint and/or Keynote iPhone edition, along with connectors to hook the iPhone up to a presentation device, and (I&apos;ll bet) a World of Warcraft iPhone client (legit or otherwise). iPhone is the new hotness in the mobile space, and people will flock to it madly. &lt;strong&gt;NOW:&lt;/strong&gt; Two more points, but let&apos;s be honest—this was a fast-break layup, no work required on my part. &lt;em&gt;Ted 8; Wrongness 2.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;THEN&lt;/strong&gt;: Another Oslo CTP will come out, and it will bear only a superficial resemblance to the one that came out in October at PDC. Betting on Oslo right now is a fools&apos; bet, not because of any inherent weakness in the technology, but just because it&apos;s way too early in the cycle to be thinking about for anything vaguely resembling production code. &lt;strong&gt;NOW:&lt;/strong&gt; If you&apos;ve worked at all with Oslo, you might argue with me, but I&apos;m still taking my two points. The two CTPs were pretty different in a number of ways. &lt;em&gt;Ted 10; Wrongness 2.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;THEN&lt;/strong&gt;: The IronPython and IronRuby teams will find some serious versioning issues as they try to manage the DLR versioning story between themselves and the CLR as a whole. An initial hack will result, which will be codified into a standard practice when .NET 4.0 ships. Then the next release of IPy or IRb will have to try and slip around its restrictions in 2010/2011. By 2012, IPy and IRb will have to be shipping as part of Visual Studio just to put the releases back into lockstep with one another (and the rest of the .NET universe). &lt;strong&gt;NOW:&lt;/strong&gt; Pressure is still building. Let&apos;s see what happens by the time VS 2010 ships, and then see what the IPy/IRb teams start to do to adjust to the versioning issues that arise. &lt;em&gt;Ted 8; Wrongness 2.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;THEN&lt;/strong&gt;: The death of JSR-277 will spark an uprising among the two leading groups hoping to foist it off on the Java community--OSGi and Maven--while the rest of the Java world will breathe a huge sigh of relief and look to see what &amp;quot;modularity&amp;quot; means in Java 7. Some of the alpha geeks in Java will start using--if not building--JDK 7 builds just to get a heads-up on its impact, and be quietly surprised and, I dare say, perhaps even pleased. &lt;strong&gt;NOW:&lt;/strong&gt; Ah, Ted, you really should never underestimate the community&apos;s willingness to take a bad idea, strip all the goodness out of it, and then cycle it back into the mix as something completely different yet somehow just as dangerous and crazy. I give you Project Jigsaw. &lt;em&gt;Ted 10; Wrongness 2;&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;THEN&lt;/strong&gt;: The invokedynamic JSR will leapfrog in importance to the top of the list. &lt;strong&gt;NOW:&lt;/strong&gt; The invokedynamic JSR begat interest in other languages on the JVM. The interest in other languages on the JVM begat the need to start thinking about how to support them in the Java libraries. The need to start thinking about supporting those languages begat a &amp;quot;Holy sh*t moment&amp;quot; somewhere inside Sun and led them to (re-)propose closures for JDK 7. And in local sports news, Ted notched up two more points on the scoreboard. &lt;em&gt;Ted 12; Wrongness 2.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;THEN&lt;/strong&gt;: Another Windows 7 CTP will come out, and it will spawn huge media interest that will eventually be remembered as Microsoft promises, that will eventually be remembered as Microsoft guarantees, that will eventually be remembered as Microsoft FUD and &amp;quot;promising much, delivering little&amp;quot;. Microsoft ain&apos;t always at fault for the inflated expectations people have--sometimes, yes, perhaps even a lot of times, but not always. &lt;strong&gt;NOW:&lt;/strong&gt; And then, just when the game started to turn into a runaway, airballs started to fly. The Windows7 release shipped, and contrary to what I expected, the general response to it was pretty warm. Yes, there were a few issues that emerged, but overall the media liked it, the masses liked it, and Microsoft seemed to have dodged a bullet. &lt;em&gt;Ted 12; Wrongness 5.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;THEN&lt;/strong&gt;: Apple will begin to legally threaten the clone market again, except this time somebody&apos;s going to get the DOJ involved. (Yes, this is the iPhone/iTunes prediction from last year, carrying over. I still expect this to happen.) &lt;strong&gt;NOW:&lt;/strong&gt; What clones? The only people trying to clone Macs are those who are building Hackintosh machines, and Apple can&apos;t sue them so long as they&apos;re using licensed copies of Mac OS X (as far as I know). Which has never stopped them from trying, mind you, and I still think Steve has some part of his brain whispering to him at night, calculating all the hardware sales lost to Hackintosh netbooks out there. But in any event, that&apos;s another shot missed. &lt;em&gt;Ted 12; Wrongness 7.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;THEN&lt;/strong&gt;: Alpha-geek developers will start creating their own languages (even if they&apos;re obscure or bizarre ones like Shakespeare or Ook#) just to have that listed on their resume as the DSL/custom language buzz continues to build. &lt;strong&gt;NOW:&lt;/strong&gt; I give you Ioke. If I&apos;d extended this to include outdated CPU interpreters, I&apos;d have made that three-pointer from half-court instead of just the top of the key. &lt;em&gt;Ted 14; Wrongness 7.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;THEN&lt;/strong&gt;: Roy Fielding will officially disown most of the &amp;quot;REST&amp;quot;ful authors and software packages available. Nobody will care--or worse, somebody looking to make a name for themselves will proclaim that Roy &amp;quot;doesn&apos;t really understand REST&amp;quot;. And they&apos;ll be right--Roy doesn&apos;t understand what &lt;em&gt;they&lt;/em&gt; consider to be REST, and the fact that he created the term will be of no importance anymore. Being &amp;quot;REST&amp;quot;ful will equate to &amp;quot;I did it myself!&amp;quot;, complete with expectations of a gold star and a lollipop. &lt;strong&gt;NOW:&lt;/strong&gt; Does anybody in the REST community care what Roy Fielding wrote way back when? I keep seeing &amp;quot;REST&amp;quot;ful systems that seem to have designers who&apos;ve never heard of Roy, or his thesis. Roy hasn&apos;t officially disowned them, but damn if he doesn&apos;t seem close to it. Still.... No points. &lt;em&gt;Ted 14; Wrongness 9.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;THEN&lt;/strong&gt;: The Parrot guys will make at least one more minor point release. Nobody will notice or care, except for a few doggedly stubborn Perl hackers. They will find themselves having nightmares of previous lives carrying around OS/2 books and Amiga paraphernalia. Perl 6 will celebrate it&apos;s seventh... or is it eighth?... anniversary of being announced, and nobody will notice. &lt;strong&gt;NOW:&lt;/strong&gt; Does anybody still follow Perl 6 development? Has the spec even been written yet? Google on &amp;quot;Perl 6 release&amp;quot;, and you get varying reports: &amp;quot;It&apos;ll ship &apos;when it&apos;s ready&apos;&amp;quot;, &amp;quot;There are no such dates because this isn&apos;t a commericially-backed effort&amp;quot;, and &amp;quot;Spring 2010&amp;quot;. Swish—nothin&apos; but net. &lt;em&gt;Ted 16; Wrongness 9.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;THEN&lt;/strong&gt;: The debate around &amp;quot;Scrum Certification&amp;quot; will rise to a fever pitch as short-sighted money-tight companies start looking for reasons to cut costs and either buy into agile at a superficial level and watch it fail, or start looking to cut the agilists from their company in order to replace them with cheaper labor. &lt;strong&gt;NOW:&lt;/strong&gt; Agile has become another adjective meaning &amp;quot;best practices&amp;quot;, and as such, has essentially lost its meaning. Just ask Scott Bellware. &lt;em&gt;Ted 18; Wrongness 9.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;THEN&lt;/strong&gt;: Adobe will continue to make Flex and AIR look more like C# and the CLR even as Microsoft tries to make Silverlight look more like Flash and AIR. Web designers will now get to experience the same fun that back-end web developers have enjoyed for near-on a decade, as shops begin to artificially partition themselves up as either &amp;quot;Flash&amp;quot; shops or &amp;quot;Silverlight&amp;quot; shops. &lt;strong&gt;NOW:&lt;/strong&gt; Not sure how to score this one—I haven&apos;t seen the explicit partitioning happen yet, but the two environments definitely still seem to be looking to start tromping on each others&apos; turf, particularly when we look at the rapid releases coming from the Silverlight team. &lt;em&gt;Ted 16; Wrongness 11.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;THEN&lt;/strong&gt;: Gartner will still come knocking, looking to hire me for outrageous sums of money to do nothing but blog and wax prophetic. &lt;strong&gt;NOW:&lt;/strong&gt; Still no job offers. Damn. Ah, well. &lt;em&gt;Ted 16; Wrongness 13.&lt;/em&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;A close game. Could&apos;ve gone either way. *shrug* Ah, well. It was silly to try and score it in basketball metaphor, anyway—that&apos;s the last time I watch ESPN before writing this.&lt;/p&gt;  &lt;p&gt;For 2010, I predict....&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;em&gt;... I will offer 3- and 4-day training classes on F# and Scala, among other things.&lt;/em&gt; OK, that&apos;s not fair—yes, I have the materials, I just need to work out locations and times. Contact me if you&apos;re interested in a private class, by the way.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... I will publish two books, one on F# and one on Scala.&lt;/em&gt; OK, OK, another plug. Or, rather, more of a resolution. One will be the &amp;quot;Professional F#&amp;quot; I&apos;m doing for Wiley/Wrox, the other isn&apos;t yet finalized. But it&apos;ll either be published through a publisher, or self-published, by JavaOne 2010.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... DSLs will either &amp;quot;succeed&amp;quot; this year, or begin the short slide into the dustbin of obscure programming ideas.&lt;/em&gt; Domain-specific language advocates have to put up some kind of strawman for developers to learn from and poke at, or the whole concept will just fade away. Martin&apos;s book will help, if it ships this year, but even that might not be enough to generate interest if it doesn&apos;t have some kind of large-scale applicability in it. Patterns and refactoring and enterprise containers all had a huge advantage in that developers could see pretty easily what the problem was they solved; DSLs haven&apos;t made that clear yet.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... functional languages will start to see a backlash.&lt;/em&gt; I hate to say it, but &amp;quot;getting&amp;quot; the functional mindset is hard, and there&apos;s precious few resources that are making it easy for mainstream (read: O-O) developers make that adjustment, far fewer than there was during the procedural-to-object shift. If the functional community doesn&apos;t want to become mainstream, then mainstream developers will find ways to take functional&apos;s most compelling gateway use-case (parallel/concurrent programming) and find a way to &amp;quot;git &apos;er done&amp;quot; in the traditional O-O approach, probably through software transactional memory, and functional languages like Haskell and Erlang will be relegated to the &amp;quot;What Might Have Been&amp;quot; of computer science history. Not sure what I mean? Try this: walk into a functional language forum, and ask what a monad is. Nobody yet has been able to produce an answer that doesn&apos;t involve math theory, or that does involve a practical domain-object-based example. In fact, nobody has really said why (or if) monads are even still useful. Or catamorphisms. Or any of the other dime-store words that the functional community likes to toss around.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... Visual Studio 2010 will ship on time, and be one of the buggiest and/or slowest releases in its history.&lt;/em&gt; I hate to make this prediction, because I really don&apos;t want to be right, but there&apos;s just so much happening in the Visual Studio refactoring effort that it makes me incredibly nervous. Widespread adoption of VS2010 will wait until SP1 at the earliest. In fact....&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... Visual Studio 2010 SP 1 will ship within three months of the final product.&lt;/em&gt; Microsoft knows that people wait until SP 1 to think about upgrading, so they&apos;ll just plan for an eager SP 1 release, and hope that managers will be too hung over from the New Year (still) to notice that the necessary shakeout time hasn&apos;t happened.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... Apple will ship a tablet with multi-touch on it, and it will flop horribly.&lt;/em&gt; Not sure why I think this, but I just don&apos;t think the multi-touch paradigm that Apple has cooked up for the iPhone will carry over to a tablet/laptop device. That won&apos;t stop them from shipping it, and it won&apos;t stop Apple fan-boiz from buying it, but that&apos;s about where the interest will end.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... JDK 7 closures will be debated for a few weeks, then become a fait accompli as the Java community shrugs its collective shoulders.&lt;/em&gt; Frankly, I think the Java community has exhausted its interest in debating new language features for Java. Recent college grads and open-source groups with an axe to grind will continue to try and make an issue out of this, but I think the overall Java community just... doesn&apos;t... care. They just want to see JDK 7 ship someday.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... Scala either &amp;quot;pops&amp;quot; in 2010, or begins to fall apart.&lt;/em&gt; By &amp;quot;pops&amp;quot;, I mean reaches a critical mass of developers interested in using it, enough to convince somebody to create a company around it, a la G2One.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... Oracle is going to make a serious &amp;quot;cloud&amp;quot; play, probably by offering an Oracle-hosted version of Azure or AppEngine.&lt;/em&gt; Oracle loves the enterprise space too much, and derives too much money from it, to not at least appear to have some kind of offering here. Now that they own Java, they&apos;ll marry it up against OpenSolaris, the Oracle database, and throw the whole thing into a series of server centers all over the continent, and call it &amp;quot;Oracle 12c&amp;quot; (c for Cloud, of course) or something.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... Spring development will slow to a crawl and start to take a left turn toward cloud ideas.&lt;/em&gt; VMWare bought SpringSource for a reason, and I believe it&apos;s entirely centered around VMWare&apos;s movement into the cloud space—they want to be more than &amp;quot;just&amp;quot; a virtualization tool. Spring + Groovy makes a compelling development stack, particularly if VMWare does some interesting hooks-n-hacks to make Spring a virtualization environment in its own right somehow. But from a practical perspective, any community-driven development against Spring is all but basically dead. The source may be downloadable later, like the VMWare Player code is, but making contributions back? Fuhgeddabowdit.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... the explosion of e-book readers brings the Kindle 2009 edition way down to size.&lt;/em&gt; The era of the e-book reader is here, and honestly, while I&apos;m glad I have a Kindle, I&apos;m expecting that I&apos;ll be dusting it off a shelf in a few years. Kinda like I do with my iPods from a few years ago.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... &amp;quot;social networking&amp;quot; becomes the &amp;quot;Web 2.0&amp;quot; of 2010.&lt;/em&gt; In other words, using the term will basically identify you as a tech wannabe and clearly out of touch with the bleeding edge.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... Facebook becomes a developer platform requirement.&lt;/em&gt; I don&apos;t pretend to know anything about Facebook—I&apos;m not even on it, which amazes my family to no end—but clearly Facebook is one of those mechanisms by which people reach each other, and before long, it&apos;ll start showing up as a developer requirement for companies looking to hire. If you&apos;re looking to build out your resume to make yourself attractive to companies in 2010, mad Facebook skillz might not be a bad investment.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... Nintendo releases an open SDK for building games for its next-gen DS-based device.&lt;/em&gt; With the spectacular success of games on the iPhone, Nintendo clearly must see that they&apos;re missing a huge opportunity every day developers can&apos;t write games for the Nintendo DS that are easily downloadable to the device for playing. Nintendo is not stupid—if they don&apos;t open up the SDK and promote &amp;quot;casual&amp;quot; games like those on the iPhone and those that can now be downloaded to the Zune or the XBox, they risk being marginalized out of existence.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;And for the next decade, I predict....&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;em&gt;... colleges and unversities will begin issuing e-book reader devices to students.&lt;/em&gt; It&apos;s a helluvalot cheaper than issuing laptops or netbooks, and besides....&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... netbooks and e-book readers will merge before the decade is out.&lt;/em&gt; Let&apos;s be honest—if the e-book reader could do email and browse the web, you have almost the perfect paperback-sized mobile device. As for the credit-card sized mobile device....&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... mobile phones will all but disappear as they turn into what PDAs tried to be.&lt;/em&gt; &amp;quot;The iPhone makes calls? Really? You mean Voice-over-IP, right? No, wait, over cell signal? It can &lt;em&gt;do &lt;/em&gt;that? Wow, there&apos;s really an app for everything, isn&apos;t there?&amp;quot;&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... wireless formats will skyrocket in importance all around the office and home.&lt;/em&gt; Combine the iPhone&apos;s Bluetooth (or something similar yet lower-power-consuming) with an equally-capable (Bluetooth or otherwise) projector, and suddenly many executives can leave their netbook or laptop at home for a business presentation. Throw in the Whispersync-aware e-book reader/netbook-thing, and now most executives have absolutely zero reason to carry anything but their e-book/netbook and their phone/PDA. The day somebody figures out an easy way to combine Bluetooth with PayPal on the iPhone or Android phone, we will have more or less made pocket change irrelevant. And believe me, that day will happen before the end of the decade.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... either Android or Windows Mobile will gain some serious market share against the iPhone the day they figure out how to support an open and unrestricted AppStore-like app acquisition model.&lt;/em&gt; Let&apos;s be honest, the attraction of iTunes and AppStore is that I can see an &amp;quot;Oh, cool!&amp;quot; app on a buddy&apos;s iPhone, and have it on mine less than 30 seconds later. If Android or WinMo can figure out how to offer that same kind of experience without the draconian AppStore policies to go with it, they&apos;ll start making up lost ground on iPhone in a hurry.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... Apple becomes the DOJ target of the decade.&lt;/em&gt; Microsoft was it in the 2000&apos;s, and Apple&apos;s stunning rising success is going to put it squarely in the sights of monopolist accusations before long. Coupled with the unfortunate health distractions that Steve Jobs has to deal with, Apple&apos;s going to get hammered pretty hard by the end of the decade, but it will have mastered enough market share and mindshare to weather it as Microsoft has.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... Google becomes the next Microsoft.&lt;/em&gt; It won&apos;t be anything the founders do, but Google will do &amp;quot;something evil&amp;quot;, and it will be loudly and screechingly pointed out by all of Google&apos;s corporate opponents, and the star will have fallen.&lt;/li&gt;    &lt;li&gt;... &lt;em&gt;Microsoft finds its way again.&lt;/em&gt; Microsoft, as a company, has lost its way. This is a company that&apos;s not used to losing, and like Bill Belichick&apos;s Patriots, they will find ways to adapt and adjust to the changed circumstances of their position to find a way to win again. What that&apos;ll be, I have no idea, but historically, the last decade notwithstanding, betting against Microsoft has historically been a bad idea. My gut tells me they&apos;ll figure something new to get that mojo back.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;... a politician will make himself or herself famous by standing up to the TSA.&lt;/em&gt; The scene will play out like this: during a Congressional hearing on airline security, after some nut/terrorist tries to blow up another plane through nitroglycerine-soaked underwear, the TSA director will suggest all passengers should fly naked in order to preserve safety, the congressman/woman will stare open-mouthed at this suggestion, proclaim, &amp;quot;Have you no sense of decency, sir?&amp;quot; and immediately get a standing ovation and never have to worry about re-election again. Folks, if we want to prevent any chance of loss of life from a terrorist act on an airplane, we have to prevent passengers from getting on them. Otherwise, just accept that it might happen, do a reasonable job of preventing it from happening, and let private insurance start offering flight insurance against the possibility to reassure the paranoid.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;See you all next year.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Book Review: Debug It!</title>
      <link>http://blogs.newardassociates.com/blog/2009/book-review-debug-it-paul-butcher-pragmatic-bookshelf.html</link>
      <pubDate>Sun, 22 Nov 2009 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2009/book-review-debug-it-paul-butcher-pragmatic-bookshelf.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;Debug It!&lt;/em&gt; (Paul Butcher, Pragmatic Bookshelf)&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Paul asked me to review this, his first book, and my comment to him was that he had a pretty high bar to match; being of the same &amp;quot;series&amp;quot; as &lt;em&gt;Release It!&lt;/em&gt;, Mike Nygard&apos;s take on building software ready for production (and, in my repeatedly stated opinion, the most important-to-read book of the decade), &lt;em&gt;Debug It!&lt;/em&gt; had some pretty impressive shoes to fill. Paul&apos;s comment was pretty predictable: &amp;quot;Thanks for keeping the pressure to a minimum.&amp;quot;&lt;/p&gt;
&lt;p&gt;My copy arrived in the mail while I was at the NFJS show in Denver this past weekend, and with a certain amount of dread and excitement, I opened the envelope and sat down to read for a few minutes. I managed to get halfway through it before deciding I had to post a review before I get too caught up in my next trip and forget.&lt;/p&gt;
&lt;h4&gt;&lt;em&gt;Short version&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Debug It!&lt;/em&gt; is a great resource for anyone looking to learn the science of good debugging. It is entirely language- and platform-agnostic, preferring to focus entirely on the &lt;em&gt;process&lt;/em&gt; and &lt;em&gt;mindset&lt;/em&gt; of debugging, rather than on edge cases or command-line switches in a tool or language. Overall, the writing is clear and straightforward without being preachy or judgmental, and is liberally annotated with real-life case stories from both the authors&apos; and the Pragmatic Programmers&apos; own history, which keeps the tone lighter and yet still proving the point of the text. Highly recommended for the junior developers on the team; senior developers will likely find some good tidbits in here as well. &lt;/p&gt;
&lt;h4&gt;&lt;em&gt;Long version&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Debug It!&lt;/em&gt; is an excellently-written and to-the-point description of the process of not only identifying and fixing defects in software, but also of the attitudes required to keep software from failing. Rather than simply tossing off old maxims or warming them over with new terminology (&amp;quot;You should always verify the parameters to your procedure calls&amp;quot; replaced with &amp;quot;You should always verify the parameters entering a method and ensure the fields follow the invariants established in the specification&amp;quot;), Paul ensures that when making a point, his prose is clear, the rationale carefully explained, and the consequences of not following this advice are clearly spelled out. His advice is pragmatic, and takes into account that developers can&apos;t always follow the absolute rules we&apos;d like to—he talks about some of his experiences with &amp;quot;bug priorities&amp;quot; and how users pretty quickly figured out to always set the bug&apos;s priority at the highest level in order to get developer attention, for example, and some ways to try and address that all-too-human failing of bug-tracking systems.&lt;/p&gt;  &lt;p&gt;It needs to be said, right from the beginning, that &lt;em&gt;Debug It!&lt;/em&gt; will not teach you how to use the debugging features of your favorite IDE, however. This is because Paul (deliberately, it seems) takes a platform- and language-agnostic approach to the book—there are no examples of how to set breakpoints in gdb, or how to attach the Visual Studio IDE to a running Windows service, for example. This will likely weed out those readers who are looking for &amp;quot;Google-able&amp;quot; answers to their common debugging problems, and that&apos;s a shame, because those are probably the very readers that need to read this book. Having said that, however, I like this agnostic approach, because these ideas and thought processes, the ones that are entirely independent of the language or platform, are exactly the kinds of things that senior developers carry over with them from one platform to the next. Still, the junior developer who picks this book up is going to still need a reference manual or the user manual for their IDE or toolchain, and will need to practice some with both books in hand if they want to maximize the effectiveness of what&apos;s in here.&lt;/p&gt;  &lt;p&gt;One of the things I like most about this book is that it is liberally adorned with real-life discussions of various scenarios the author team has experienced; the reason I say &amp;quot;author team&amp;quot; here is because although the stories (for the most part) remain unattributed, there are obvious references to &amp;quot;Dave&amp;quot; and &amp;quot;Andy&amp;quot;, which I assume pretty obviously refer to Dave Thomas and Andy Hunt, the Pragmatic Programmers and the owners of Pragmatic Bookshelf. Some of the stories are humorous, and some of them probably would be humorous if they didn&apos;t strike so close to my own bitterly-remembered experiences. All of them do a good job of reinforcing the point, however, thus rendering the prose more effective in communicating the idea without getting to be too preachy or bombastic.&lt;/p&gt;  &lt;p&gt;The book obviously intends to target a junior developer audience, because most senior developers have already intuitively (or experientially) figured out many of the processes described in here. But, quite frankly, I think it would be a shame for senior developers to pass on this one; though the temptation will be to simply toss it aside and say, &amp;quot;I already do all this stuff&amp;quot;, senior developers should resist that urge and read it through cover to cover. If nothing else, it&apos;ll help reinforce certain ideas, bring some of the intuitive process more to light and allow us to analyze what we do right and what we do wrong, and perhaps most importantly, give us a common backdrop against which we can mentor junior developers in the science of debugging.&lt;/p&gt;  &lt;p&gt;One of the chapters I like in particular, &amp;quot;Chapter 7: Pragmatic Zero Tolerance&amp;quot;, is particularly good reading for those shops that currently suffer from a deficit of management support for writing good software. In it, Paul talks specifically about some of the triage process about bugs (&amp;quot;When to fix bugs&amp;quot;), the mental approach developers should have to fixing bugs (&amp;quot;The debugging mind-set&amp;quot;) and how to get started on creating good software out of bad (&amp;quot;How to dig yourself out of a quality hole&amp;quot;). These are techniques that a senior developer can bring to the team and implement at a grass-roots level, in many cases without management even being aware of what&apos;s going on. (It&apos;s a sad state of affairs that we sometimes have to work behind management&apos;s back to write good-quality code, but I know that some developers out there are in exactly that situation, and simply saying, &amp;quot;Quit and find a new job&amp;quot;, although pithy and good for a laugh on a panel, doesn&apos;t really offer much in the way of help. Paul doesn&apos;t take that route here, and that alone makes this book worth reading.)&lt;/p&gt;  &lt;p&gt;Another of the chapters that resonates well with me is the first one in Part III (&amp;quot;Debug Fu&amp;quot;), Chapter 8, entitled &amp;quot;Special Cases&amp;quot;, in which he tackles a number of &amp;quot;advanced&amp;quot; debugging topics, such as &amp;quot;Patching Existing Releases&amp;quot; and &amp;quot;Hesenbugs&amp;quot; (Concurrency-related bugs). I won&apos;t spoil the punchline for you, but suffice it to say that I wish I&apos;d had that chapter on hand to give out to teammates on a few projects I&apos;ve worked on in the past.&lt;/p&gt;  &lt;p&gt;Overall, this book is going to be a huge win, and I think it&apos;s a worthy successor to the &lt;em&gt;Release It!&lt;/em&gt; reputation. Development managers and team leads should get a copy for the junior developers on their team as a Christmas gift, but only after the senior developers have read through it as well. (Senior devs, don&apos;t despair—at 190 pages, you can rip through this in a single night, and I can almost guarantee that you&apos;ll learn a few ideas you can put into practice the next morning to boot.)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Agile is treating the symptoms, not the disease</title>
      <link>http://blogs.newardassociates.com/blog/2009/agile-is-treating-the-symptoms-not-the-disease.html</link>
      <pubDate>Mon, 12 Oct 2009 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2009/agile-is-treating-the-symptoms-not-the-disease.html</guid>
      	<description>
	&lt;p&gt;The above quote was tossed off by Billy Hollis at the patterns&amp;amp;practices Summit this week in Redmond. I passed the quote out to the Twitter masses, along with my +1, and predictably, the comments started coming in shortly thereafter. Rather than limit the thoughts to the 120 or so characters that Twitter limits us to, I thought this subject deserved some greater expansion.&lt;/p&gt;  
&lt;!--more--&gt;
&lt;p&gt;But before I do, let me try (badly) to paraphrase the lightning talk that Billy gave here, which sets context for the discussion:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Keeping track of all the stuff Microsoft is releasing is hard work: LINQ, EF, Silverlight, ASP.NET MVC, Enterprise Library, Azure, Prism, Sparkle, MEF, WCF, WF, WPF, InfoCard, CardSpace, the list goes on and on, and frankly, nobody (and I mean nobody) can track it all.&lt;/li&gt;    &lt;li&gt;Microsoft released all this stuff because they were chasing the &amp;quot;enterprise&amp;quot; part of the developer/business curve, as opposed to the &amp;quot;long tail&amp;quot; part of the curve that they used to chase down. They did this because they believed that this was good business practice—like banks, &amp;quot;enterprises are where the money is&amp;quot;. (If you&apos;re not familiar with this curve, imagine a graph with a single curve asymptotically reaching for both axes, where Y is the number of developers on the project, and X is the number of projects. What you get is a curve of a few high-developer-population projects on the left, to a large number of projects with just 1 or 2 developers. This right-hand portion of the curve is known as &amp;quot;the long tail&amp;quot; of the software industry.)&lt;/li&gt;    &lt;li&gt;A lot of software written back in the 90&apos;s was written by 1 or 2 guys working for just a few months to slam something out and see if it was useful. What chances do those kinds of projects have today? What tools would you use to build them?&lt;/li&gt;    &lt;li&gt;The problem is the complexity of the tools we have available to us today preclude that kind of software development.&lt;/li&gt;    &lt;li&gt;Agile doesn&apos;t solve this problem—the agile movement suggests that we have to create story cards, we have to build unit tests, we have to have a continuous integration server, we have to have standup meetings every day, .... In short, particularly among the agile evangelists (by which we really mean &lt;em&gt;zealots&lt;/em&gt;), if you aren&apos;t doing a full agile process, you are simply failing. &lt;em&gt;(If this is true, how on earth did all those thousands of applications written in FoxPro or Access ever manage to succeed? –-Me)&lt;/em&gt; At one point, an agilist said point-blank, &amp;quot;If you don&apos;t do agile, what happens when your project reaches a thousand users?&amp;quot; As Billy put it, &amp;quot;Think about that for a second: This agile guy is &lt;em&gt;threatening&lt;/em&gt; us with success.&amp;quot;&lt;/li&gt;    &lt;li&gt;Agile is for managing complexity. What we need is to recognize that there is a place for outright simplicity instead.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;By the way, let me say this out loud: if you have not heard Billy Hollis speak, you should. Even if you&apos;re a Java or Ruby developer, you should listen to what he has to say. He&apos;s been developing software for a long time, has seen a lot of these technology-industry trends come and go, and even if you disagree with him, you need to listen to him.&lt;/p&gt;  &lt;p&gt;Let me rephrase Billy&apos;s talk this way:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Where is this decade&apos;s Access?&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;It may seem like a snarky and trolling question, but think about it for a moment: for a decade or so, I was brought into project after project that was designed to essentially rebuild/rearchitect the Access database created by one of the department&apos;s more tech-savvy employees into something that could scale beyond just the department. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;(Actually, in about half of them, the goal wasn&apos;t even to scale it up, it was just to put it on the web. It was only in the subsequent meetings and discussions that the issues of scale came up, and if my memory is accurate, I was the one who raised those issues, not the customer. I wonder now, looking back at it, if that was pure gold-plating on my part.)&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Others, including many people I care about (Rod Paddock, Markus Eggers, Ken Levy, Cathi Gero, for starters) made a healthy living off of building &amp;quot;line of business&amp;quot; applications in FoxPro, which Microsoft has now officially shut down. For those who did Office applications, Visual Basic for Applications has now been officially deprecated in favor of VSTO (Visual Studio Tools for Office), a set of libraries that are available for use by any .NET application language, and of course classic Visual Basic itself has been &amp;quot;brought into the fold&amp;quot; by making it a fully-fledged object-oriented language complete with XML literals and LINQ query capabilities.&lt;/p&gt;  &lt;p&gt;Which means, if somebody working for a small school district in western Pennsylvania wants to build a simple application for tracking students&apos; attendance (rather than tracking it on paper anymore), what do they do?&lt;/p&gt;  &lt;p&gt;Bruce Tate alluded to this in his &lt;em&gt;Beyond Java&lt;/em&gt;, based on the realization that the Java space was no better—to bring a college/university student up to speed on all the necessary technologies required of a &amp;quot;productive&amp;quot; Java developer, he calculated at least five or six weeks of training was required. And that&apos;s not a bad estimate, and might even be a bit on the shortened side. You can maybe get away with less if they&apos;re joining a team which collectively has these skills distributed across the entire team, but if we&apos;re talking about a standalone developer who&apos;s going to be building software by himself, it&apos;s a pretty impressive list. Here&apos;s my back-of-the-envelope calculations:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Week one: Java language. (Nobody ever comes out of college knowing all the Java language they need.)&lt;/li&gt;    &lt;li&gt;Week two: Java virtual machine: threading/concurrency, ClassLoaders, Serialization, RMI, XML parsing, reference types (weak, soft, phantom).&lt;/li&gt;    &lt;li&gt;Week three: Infrastructure: Ant, JUnit, continuous integration, Spring.&lt;/li&gt;    &lt;li&gt;Week four: Data access: JDBC, Hibernate. (Yes, I think you need a full week on Hibernate to be able to use it effectively.)&lt;/li&gt;    &lt;li&gt;Week five: Web: HTTP, HTML, servlets, filters, servlet context and listeners, JSP, model-view-controller, and probably some Ajax to boot.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I could go on (seriously! no JMS? no REST? no Web services?), but you get the point. And lest the .NET community start feeling complacent, put together a similar list for the standalone .NET developer, and you&apos;ll come out to something pretty equivalent. (Just look at the &lt;a href=&quot;http://www.pluralsight.com/main/ilt/Courses.aspx&quot; target=&quot;_blank&quot;&gt;Pluralsight list of courses&lt;/a&gt;—name the &lt;em&gt;one&lt;/em&gt; course you would give that college kid to bring him up to speed. Stumped? Don&apos;t feel bad—I can&apos;t, either. And it&apos;s not them—pick on any of the training companies.)&lt;/p&gt;  &lt;p&gt;Now throw agile into that mix: &lt;em&gt;how does an agile process reduce the complexity load?&lt;/em&gt; And the answer, of course, is that it doesn&apos;t—it simply tries to muddle through as best it can, by doing all of the things that developers need to be doing: gathering as much feedback from every corner of their world as they can, through tests, customer interaction, and frequent releases. &lt;em&gt;All of which is good&lt;/em&gt;. I&apos;m &lt;em&gt;not&lt;/em&gt; here to suggest that we should all give up agile and immediately go back to waterfall and Big Design Up Front. Anybody who uses Billy&apos;s quote as a sound bite to suggest that is a subversive and a terrorist and should have their arguments refuted with &lt;em&gt;extreme prejudice&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;But agile is not going to reduce the technology complexity load, which is the root cause of the problem.&lt;/p&gt;  &lt;p&gt;Or, perhaps, let me ask it this way: your 16-year-old wants to build a system to track the cards in his Magic deck. What language do you teach him?&lt;/p&gt;  &lt;p&gt;We are in &lt;em&gt;desperate&lt;/em&gt; need of simplicity in this industry. Whoever gets that, and gets it right, defines the &amp;quot;Next Big Thing&amp;quot;.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Book Review: Iron Python in Action</title>
      <link>http://blogs.newardassociates.com/blog/2009/book-review-iron-python-in-action-by-michael-foord-and-christian-muirhead.html</link>
      <pubDate>Wed, 1 Jul 2009 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2009/book-review-iron-python-in-action-by-michael-foord-and-christian-muirhead.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;Iron Python in Action&lt;/em&gt; (Michael Foord, Christian Muirhead; Manning)&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;OK, OK, I admit it. Maybe significant whitespace isn&apos;t all bad. (But don&apos;t let me ever catch you quoting me say that.)&lt;/p&gt;  &lt;p&gt;The reason for my (maybe) shift in thinking? Manning Publications sent me a copy of &lt;em&gt;Iron Python in Action&lt;/em&gt;, and I have to say, I like the book and its approach. Getting me to like Python as a primary language for development will probably take more than just one book can give, but... *shrug* Who knows?&lt;/p&gt;  &lt;p&gt;Bear in mind, I have plenty of reasons to like IronPython (Microsoft&apos;s Python implementation for the .NET environment):&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A good friend of mine, Harry Pierson (aka @DevHawk), is the PM on the IPy project, and I&apos;m generally prejudiced in favor of those things that people I know and respect.&lt;/li&gt;    &lt;li&gt;I&apos;m generally a fan of dynamic languages, particularly those that let you do strange and twisted things to the type system and its instances at runtime. (Yes, I&apos;m looking at you, ECMAScript...)&lt;/li&gt;    &lt;li&gt;I spent some quality time with IronPython Studio last year while researching a Visual Studio Extensibility &amp;quot;Deep Dive&amp;quot; paper.&lt;/li&gt;    &lt;li&gt;I&apos;ve known Jim Hugunin (the creator of IronPython, and Jython before that) for some years, ever since his days working on AspectJ, and he&apos;s one of those scary-smart guys that, despite knowing they&apos;re scary-smart, still render me stunned when I listen to them.&lt;/li&gt;    &lt;li&gt;I&apos;m a huge fan of the DLR. It&apos;s like having Parrot, but without having to wait a decade (give or take).&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;But, just to counterbalance the scales, I have plenty of good reasons to dislike IronPython, too:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Significant whitespace.&lt;/li&gt;    &lt;li&gt;The &amp;quot;There&apos;s only one way to do it&amp;quot; oath that Pythonistas seem to hold as religion. (Somebody told me that building C-Python—the original implementation—only works for you if you swear a holy oath to The One True Way on the One True Way Bible. Needless to say, I believe them, and have never tried to build C-Python from sources as a result.)&lt;/li&gt;    &lt;li&gt;Significant whitespace.&lt;/li&gt;    &lt;li&gt;Uh.... did I mention significant whitespace yet?&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I admit, it was with some hesitation that I cracked open the book. Actually, to be honest, I was really ready to just take out all my dislike of significant whitespace and pour it into a heated, vitriolic diatribe on everything that was just &lt;em&gt;wrong&lt;/em&gt; with Python.&lt;/p&gt;  &lt;p&gt;And...?&lt;/p&gt;  &lt;p&gt;Well, OK, I admit it. Maybe significant whitespace isn&apos;t all bad.&lt;/p&gt;  &lt;p&gt;But this is a review of the book, not the technology. So, on we go.&lt;/p&gt;  &lt;h3&gt;What I liked about the book&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;The focus is on both .NET and Python, and doesn&apos;t try to short-change either the &amp;quot;Python&amp;quot;-ness or the &amp;quot;.NET&apos;-ness by trying to be a &amp;quot;Python book (that happens to run on .NET)&amp;quot; or a &amp;quot;.NET book (that happens to use Python for code samples)&amp;quot;. The authors, I think, did a very good job of balancing the two, making this &lt;em&gt;the&lt;/em&gt; book to get if you&apos;re in that area on the Venn diagram where &amp;quot;Python&amp;quot; overlaps with &amp;quot;.NET&amp;quot;.&lt;/li&gt;    &lt;li&gt;Part 2, &lt;em&gt;&amp;quot;Core development techniques&amp;quot;&lt;/em&gt;, starts down the &amp;quot;feed you the Python Kool-Ade&amp;quot; pretty quickly, heading straight into Chapter 4 (&amp;quot;&lt;em&gt;Writing an application and design patterns with IronPython&amp;quot;&lt;/em&gt;) without much of a pause for breath. The authors get into duck typing, protocols, and Model-View-Controller within the first four pages, and begin working on a running example to highlight some of the ideas. (Interestingly enough, they also take a few moments to point out that IronPython on Mono works, and include a couple of screen shots to that effect as we go, though I personally wonder just how many people are really going down this path.) I like the no-holds-barred, show-you-the-code style, but only because they also take time throughout the prose to talk about some of the concepts at work underneath and laced throughout the code. &amp;quot;Show me then tell me&amp;quot; is a time-honored tradition, but too many authors forget the &amp;quot;tell me&amp;quot; part and stop with code. These guys do a good job of following through.&lt;/li&gt;    &lt;li&gt;The chapters in Part 3, &amp;quot;&lt;em&gt;IronPython and advanced .NET&lt;/em&gt;&amp;quot;, form an interesting collection of how IronPython can fit into the rest of the .NET stack, demonstrating how to use IronPython with WPF, ASP.NET, and IronPython&apos;s crowning glory, Silverlight. If you&apos;re into front-end stuff, this is the section where I think you&apos;re going to have the most fun.&lt;/li&gt;    &lt;li&gt;The chapters in Part 4, &amp;quot;&lt;em&gt;Reaching out with IronPython&lt;/em&gt;&amp;quot;, is I think the most important part of the book, showing how to extend IronPython (chapter 14) with C#/VB extensions (similar to how a C-Python developer would extend Python by writing C code, but much much simpler) and the opposite—how to embed IronPython inside of existing C#/VB applications (chapter 15), which is really an exercise in using the DLR Hosting APIs. While the discussion in chapter 15 is good, I wish it&apos;d had a bit more thorough discussion of how the DLR could be hosted regardless of the scripting language, though I admit that&apos;s pretty beyond the scope of this book (which is focused, after all, entirely on IronPython, and as a result &lt;em&gt;should&lt;/em&gt; stay focused on how to host IPy).&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;&lt;strong&gt;What I found &amp;quot;Meh&amp;quot; about the book&lt;/strong&gt;&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;Part 1 (&lt;em&gt;&amp;quot;A new language for .NET&amp;quot;&lt;/em&gt;, &lt;em&gt;&amp;quot;Introduction to Python&amp;quot;&lt;/em&gt;, and &lt;em&gt;&amp;quot;.NET objects and IronPythong&amp;quot;&lt;/em&gt;) does a good job of bringing the rank beginner up to speed, getting some basic Python ideas across in the same breath that they bring .NET home. The only problem is, it only works well if you&apos;re neither a Python programmer nor a .NET programmer. Chapter 1, for example, does a sort of Cannonball-into-the-pool kind of dive into Python, but dives equally into the &amp;quot;Iron&amp;quot; parts as it does the &amp;quot;Python&amp;quot; parts. If you&apos;re either a Pythonista or a .NETter, I suspect you&apos;re going to be tempted to flip pages pretty quickly, and (I suspect) miss a few things. Chapter 2 is all about Python (meaning .NETters will probably spend some time here), but it certainly doesn&apos;t feel like an exhaustive reference, nor does Chapter 3 stand as an exhaustive discussion about all things .NET, either. I almost wish all three chapters had been collapsed into one—suffice it to say, I don&apos;t feel like I know the Python language, and don&apos;t feel like this book could be my Python reference next to me as I learn it, and I know that it&apos;s not a great .NET reference, either. Fortunately, the goal of these three chapters feels pretty clearly to be &amp;quot;Teach you just enough to make you dangerous (and able to understand the rest of the book)&amp;quot;, and once we hit Part 2, rubber meets road pretty quickly.&lt;/li&gt;    &lt;li&gt;By the time you hit Chapter 7, less than halfway through the book, the authors have created a fairly nice, if simplistic, application for later dissection, but it&apos;s not until you hit Chapter 7 that they begin to start unit-testing, even though they insist (on page 17) that &amp;quot;Dynamic language programmers are often proponents of &lt;em&gt;strong testing rather than strong typing&lt;/em&gt;&amp;quot; (a quote they attribute to Bruce Eckel, though I&apos;m relatively certain I heard Dave Thomas and Neal Ford say it with respect to Ruby, long before Eckel started &amp;quot;Thinking in Python... or Flex... or whatever&amp;quot;). If unit-testing is that important, why wait three chapters into the application&apos;s development before writing a single unit-test? This doesn&apos;t jibe with me, somehow.&lt;/li&gt;    &lt;li&gt;If you&apos;re into back-end stuff, chapter 12 on &lt;em&gt;&amp;quot;Databases and web services&amp;quot;&lt;/em&gt; is pretty bland. The fact that the two are combined into a single chapter is indicative, all by itself, of how deep or intensive the coverage goes, and there&apos;s zero mention of anything beyond basic ADO.NET. The coverage on web services covers REST relatively well, but there&apos;s zero coverage of WCF, and the whole of SOAP-based services is all of four or five pages. And Workflow? Doesn&apos;t exist, isn&apos;t even mentioned (except for an appearance in a table, &amp;quot;The major new APIs of .NET 3.0&amp;quot;). Yikes.&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;&lt;strong&gt;What I actively disliked about the book&lt;/strong&gt;&lt;/h3&gt;  &lt;p&gt;Actually, not much. Manning did their usual superb job of arrowed callouts to point out particular concepts in the code listings, the copyediting is professional (meaning there&apos;s no obvious typos or misspellings that just break up the flow of prose, something that not all publishers seem to take seriously), and the graphics flow nicely alongside the prose, not dominating the page but accentuating it.&lt;/p&gt;  &lt;p&gt;In fact, about the only thing I&apos;d care to criticize is the &lt;em&gt;huge&lt;/em&gt; number of footnotes, particularly in the first chapter. (By page 20 in the book, there have already been 30 footnotes.) When you have three footnotes &lt;em&gt;per page&lt;/em&gt;, on average (and sometimes more), it does tend to distract, at least to me it does. It feels like there were ways, for most of them, to inject the idea or concept into the main prose, or leave it out entirely, but that could just be a difference of writing style, too.&lt;/p&gt;  &lt;h3&gt;&lt;strong&gt;Summation&lt;/strong&gt;&lt;/h3&gt;  &lt;p&gt;If you&apos;re a .NET developer interested in learning/using IronPython on your next project, this is a definite winner. If you&apos;re a Python developer looking to see how to break into .NET, I&apos;m not so sure this is your book, but I say that mostly because I&apos;m &lt;em&gt;not&lt;/em&gt; a Pythonista and can&apos;t really speak to how that mindset will find this as an introduction to the .NET space. My intuition tells me that this would be a good springboard into another book on .NET for the Python programmer, but I&apos;ll have to leave that to Pythonistas who&apos;ve read this book to comment one way or another.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Book Review: Programming Clojure</title>
      <link>http://blogs.newardassociates.com/blog/2009/book-review-programming-clojure-by-stu-halloway.html</link>
      <pubDate>Sat, 27 Jun 2009 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2009/book-review-programming-clojure-by-stu-halloway.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;Programming Clojure&lt;/em&gt; (Stu Halloway; Pragmatic Bookshelf)&lt;/p&gt;
&lt;!--more--&gt;
&lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;&lt;strong&gt;(Disclaimer:&lt;/strong&gt; In the spirit of full disclosure, Stu is a friend, fellow NFJS speaker, and former co-worker of mine from DevelopMentor.)&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I present this review to you in two parts.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Short version:&lt;/strong&gt; If you want to learn Clojure, and you&apos;re familiar with at least one programming language, you&apos;ll find this a great resource. If you don&apos;t already know a programming language, or if you already know Clojure, or if you&apos;re looking for &amp;quot;best practices&amp;quot; to cut-and-paste, you&apos;re going to be disappointed.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Long version:&lt;/strong&gt; Recently, fellow NFJS speaker Stu Halloway decided to take up a new language, and came to Clojure. He found the language interesting enough to write a book on it, something he hasn&apos;t done since his Java days, and the result is a nice walk through the language and its environment for experienced Java developers who want to understand Clojure&apos;s language, concurrency concepts, and programming model.&lt;/p&gt;  &lt;p&gt;Now, let&apos;s be 100% honest about this: if you&apos;re coming at this book expecting it to be a language reference, you will probably be disappointed (as &lt;a href=&quot;http://www.amazon.com/review/R3NM9CKFWYFKAE/ref=cm_cr_rdp_perm&quot; target=&quot;_blank&quot;&gt;this guy&lt;/a&gt; obviously is). Stu&apos;s not like that—he&apos;s not going to re-create material that&apos;s available elsewhere, or that can be found with an easy Google search. Stu will not waste your time that way—he wants to tell you a story, one that takes you from &amp;quot;I&apos;m a Java guy, but clueless about Lisp, dynamic languages, functional programming, concurrency, or macros&amp;quot; to &amp;quot;Wow. I know kung-fu.&amp;quot; in the shortest path possible, but without trying to lobotomize you. He wants—no, &lt;em&gt;expects&lt;/em&gt;—the readers of his book to be propping the text open with a cell phone on one side and the dinner plate on the other, craning your neck over to scan the pages and type in the examples into the REPL shell to try them out, see them work, then spend a few minutes experimenting with them before moving on to the next paragraph or page. &lt;/p&gt;  &lt;p&gt;(Oh, I suppose you could just cut and paste them from the PDF version of the book, but where&apos;s the fun in that?)&lt;/p&gt;  &lt;p&gt;The fact is, the &lt;em&gt;concepts&lt;/em&gt; behind Clojure make up what&apos;s important to learn here, and readers of this book will come away like the panda from the movie, realizing that &amp;quot;There is no Secret Ingredient&amp;quot;, that the power of Clojure comes not from its super-secret language sauce or special libraries, but in the way Clojure programmers approach problems and think about programming. And for that reason, if you&apos;re a programmer—even if you don&apos;t program on the JVM—you really want to take a look at what Stu&apos;s talking about (and Rich Hickey is creating).&lt;/p&gt;  &lt;p&gt;Just remember, cellphone and dinner plate. Otherwise you&apos;ll be missing out on so much.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>SSCLI 2.0 Internals</title>
      <link>http://blogs.newardassociates.com/blog/2009/sscli-20-internals.html</link>
      <pubDate>Tue, 26 May 2009 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2009/sscli-20-internals.html</guid>
      	<description>
	&lt;p&gt;Joel&apos;s weblog appears to be down, so in response to some emails I&apos;ve posted my draft copy of &lt;em&gt;SSCLI 2.0 Internals&lt;/em&gt;.&lt;/p&gt;
&lt;!--more--&gt; 
&lt;p&gt;You can find it &lt;a href=&quot;../../files/SSCLI2.pdf&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. I think it&apos;s the same PDF that Joel had on his weblog, but I haven&apos;t made absolutely certain of the fact. :-/&lt;/p&gt;
&lt;p&gt;If you&apos;ve not checked out the first version of SSCLI Internals, it&apos;s cool-—the second edition is basically everything that the first edition is, plus a new chapter on Generics (and how they changed the internals of the CLR to reflect generics all the way through the system), so you&apos;re good. And if you&apos;re not sure where to get the codebase for Rotor 2.0 (the SSCLI), well, &lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?FamilyId=8C09FD61-3F26-4555-AE17-3121B4F51D4D&amp;amp;displaylang=en&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;, I&apos;ll make it easy for you. ;-)&lt;/p&gt;
&lt;p&gt;Gotta say, this is almost without question my favorite book to have written. Just wish Microsoft would&apos;ve kept Rotor up with the successive CLR releases (3.5 SP 1 and now the forthcoming 4.0). Maybe, if I can find that wishing ring....&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE (2016):&lt;/strong&gt; By the way, back in 2008 I wrote:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;[T]he book also marks a turning point, as well: with the release of the FCL source to the wider world of the development community and the lack of significant changes to the execution engine since v2, the Rotor distribution has effectively been &amp;quot;cut loose&amp;quot; by its original creators, to stand on its own within the community, as every open source project must do at some point. This is not a cause for alarm or concern—-the Mono project continues full force, and Microsoft‘s growing comfort with the open-source community leads to the distinct possibility that the commercial CLR source will, one day, stand where Rotor once stood.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Can I call it, or can I call it?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE (2021):&lt;/strong&gt; In case anyone was curious, yes, I&apos;ve looked at the CoreCLR source code, and yes, most of the SSCLI Essentials text remains accurate. Some areas have changed for sure, but the overall &amp;quot;meat&amp;quot; of the text remains useful.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Multi-core Mania: A Rebuttal</title>
      <link>http://blogs.newardassociates.com/blog/2009/multi-core-mania-a-rebuttal.html</link>
      <pubDate>Thu, 2 Apr 2009 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2009/multi-core-mania-a-rebuttal.html</guid>
      	<description>
	&lt;p&gt;The &lt;a href=&quot;http://www.simple-talk.com/newsletter-archive/&quot;&gt;Simple-Talk newsletter&lt;/a&gt; is a monthly e-zine that the folks over at Red Gate Software (makers of some pretty cool toys, including their ANTS Profiler, and recent inheritors of the Reflector utility legacy) produce, usually to good effect.&lt;/p&gt;  
&lt;!--more--&gt;
&lt;p&gt;But &lt;a href=&quot;http://www.simple-talk.com/newsletter/v.aspx?n=144&quot;&gt;this month&lt;/a&gt; carried with it an interesting editorial piece, which I reproduce in its entirety here:&lt;/p&gt;
&lt;blockquote&gt;   &lt;p&gt;When the market is slack, nothing succeeds better at tightening it up than promoting serial group-panic within the community. As an example of this, a wave of multi-core panic spread across the Internet about 18 months ago. IT organizations, it was said, urgently had to improve application performance by an order of magnitude in order to cope with rising demand. We wouldn&apos;t be able to meet that need because we were at the &amp;quot;end of the road&amp;quot; with regard to step changes in processor power and clock speed. Multi-core technology was the only sure route to improving the speed of applications but, unfortunately, our current &amp;quot;serial&amp;quot; programming techniques, and the limited multithreading capabilities of our programming languages and programmers, left us ill-equipped to exploit it. Multi-core mania gripped the industry.&lt;/p&gt;    &lt;p&gt;However, the fever was surprisingly short-lived. Intel&apos;s &amp;quot;largest open-source effort ever&amp;quot; to provide a standard tool for writing multi-threaded code, caused little more than a ripple of interest. Various books, rushed out while the temperature soared, advocated the urgent need for new &amp;quot;multi-core-friendly&amp;quot; programming models, involving such things as &amp;quot;software pipelines&amp;quot;. Interesting as they undoubtedly are, they sit stolidly on bookshelves, unread.&lt;/p&gt;    &lt;p&gt;The truth is that it&apos;s simply not a big issue for the majority of people. Writing truly &amp;quot;concurrent&amp;quot; applications in languages such as C# is difficult, as you get very little help from the language. It means getting involved with low-level concurrency primitives, such as lock statements and so on.&lt;/p&gt;    &lt;p&gt;Many programmers lack the skills to do this, but more pertinently lack the need. Increasingly, programmers work in a web environment. As long as these web applications are deployed to a load-balanced web farm, then page requests can be handled in parallel so all available cores will be used efficiently without the need for the programmer to be concerned with fine-grained parallelism.&lt;/p&gt;    &lt;p&gt;Furthermore, the SQL Server engine behind these web applications is intrinsically &amp;quot;parallel&amp;quot;, and can handle and use effectively about as many cores as you care to throw at it. SQL itself is a declarative rather than procedural language, so it is fundamentally concurrent.&lt;/p&gt;    &lt;p&gt;A minority of programmers, for example games programmers or those who deal with &amp;quot;embarrassingly parallel&amp;quot; desktop applications such as Photoshop, do need to start working with the current tools and &apos;low-level&apos; coding techniques that will allow them to exploit multi-core technology. Although currently perceived to be more of &amp;quot;academic&amp;quot; interest, concurrent languages such as Erlang, and concurrency techniques such as &amp;quot;software transactional memory&amp;quot;, may yet prove to be significant.&lt;/p&gt;    &lt;p&gt;For most programmers and for most web applications, however, the multi-core furore is a storm in a teacup; it&apos;s just not relevant. The web and database platforms already cope with concurrency requirements. We are already doing it.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;My &lt;em&gt;hope&lt;/em&gt; is that this newsletter, sent on April 1st, was intended to be a joke. Having said that, I can’t find any verbage in the email that suggests that it is, in which case, I have to treat it as a legitimate editorial. &lt;/p&gt;  &lt;p&gt;And frankly, I think it’s all crap. &lt;/p&gt;  &lt;p&gt;It&apos;s dangerously ostrichian in nature—it encourages developers to simply bury their heads in the sand and ignore the freight train that&apos;s coming their way. Permit me, if you will, a few minutes of your time, that I may be allowed to go through and demonstrate the reasons why I say this.&lt;/p&gt;  &lt;p&gt;To begin ...&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;When the market is slack, nothing succeeds better at tightening it up than promoting serial group-panic within the community. As an example of this, a wave of multi-core panic spread across the Internet about 18 months ago. IT organizations, it was said, urgently had to improve application performance by an order of magnitude in order to cope with rising demand. [...] Multi-core mania gripped the industry.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Point of fact: The “panic” cited here didn’t start about 18 months ago, it started with Herb Sutter’s most excellent (and not only highly recommended but highly required) article, “The Free Lunch is Over: A Fundamental Turn Toward Concurrency in Software”, appeared in the pages of Dr. Dobb’s Journal in March of 2005. (Herb’s website notes that “a much briefer version under the title “The Concurrency Revolution” appeared in C/C++ User’s Journal” the previous month.) And the panic itself wasn’t rooted in the idea that we weren’t going to be able to cope with rising demand, but that multi-core CPUs, back then a rarity and reserved only for hardware systems in highly-specialized roles, were in fact becoming commonplace in servers, and worse, as they migrated into desktops, they would quickly a fact of life that every developer would need to face. Herb demonstrated this by pointing out that CPU speeds had taken an interesting change of pace in early 2003:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Around the beginning of 2003, &lt;em&gt;[looking at the website Figure 1 graph] &lt;/em&gt;you’ll note a disturbing sharp turn in the previous trend toward ever-faster CPU clock speeds. I’ve added lines to show the limit trends in maximum clock speed; instead of continuing on the previous path, as indicated by the thin dotted line, there is a sharp flattening. It has become harder and harder to exploit higher clock speeds due to not just one but several physical issues, notably heat (too much of it and too hard to dissipate), power consumption (too high), and current leakage problems.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Joe Armstrong, creator of Erlang, noted in a presentation at QCon London 2007 that another of those physical limitations was the speed of light—that for the first time, CPU signal couldn&apos;t get from one end of the chip to the other in a single clock cycle.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Quick: What’s the clock speed on the CPU(s) in your current workstation? Are you running at 10GHz? On Intel chips, we reached 2GHz a long time ago (August 2001), and according to CPU trends before 2003, now in early 2005 we should have the first 10GHz Pentium-family chips.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Just to (re-)emphasize the point, here, now, in early 200&lt;strong&gt;9&lt;/strong&gt;, we should be seeing the first 20 or 40 GHz processors, and clearly we’re still plodding along in the 2 – 3 GHz range. The &amp;quot;Quake Rule&amp;quot; (when asked about perf problems, tell your boss you&apos;ll need eighteen months to get a 2X improvement, then bury yourselves in a closet for 18 months playing Quake until the next gen of Intel hardware comes out) no longer works.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;For the near-term future, meaning for the next few years, the performance gains in new chips will be fueled by three main approaches, only one of which is the same as in the past. The near-term future performance growth drivers are:&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;hyperthreading&lt;/li&gt;      &lt;li&gt;multicore&lt;/li&gt;      &lt;li&gt;cache&lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;Hyperthreading is about running two or more threads in parallel inside a single CPU. Hyperthreaded CPUs are already available today, and they do allow some instructions to run in parallel. A limiting factor, however, is that although a hyper-threaded CPU has some extra hardware including extra registers, it still has just one cache, one integer math unit, one FPU, and in general just one each of most basic CPU features. Hyperthreading is sometimes cited as offering a 5% to 15% performance boost for reasonably well-written multi-threaded applications, or even as much as 40% under ideal conditions for carefully written multi-threaded applications. That’s good, but it’s hardly double, and it doesn’t help single-threaded applications.&lt;/p&gt;    &lt;p&gt;Multicore is about running two or more actual CPUs on one chip. Some chips, including Sparc and PowerPC, have multicore versions available already. The initial Intel and AMD designs, both due in 2005, vary in their level of integration but are functionally similar. AMD’s seems to have some initial performance design advantages, such as better integration of support functions on the same die, whereas Intel’s initial entry basically just glues together two Xeons on a single die. The performance gains should initially be about the same as having a true dual-CPU system (only the system will be cheaper because the motherboard doesn’t have to have two sockets and associated “glue” chippery), which means something less than double the speed even in the ideal case, and just like today it will boost reasonably well-written multi-threaded applications. Not single-threaded ones.&lt;/p&gt;    &lt;p&gt;Finally, on-die cache sizes can be expected to continue to grow, at least in the near term. Of these three areas, only this one will broadly benefit most existing applications. The continuing growth in on-die cache sizes is an incredibly important and highly applicable benefit for many applications, simply because space is speed. Accessing main memory is expensive, and you really don’t want to touch RAM if you can help it. On today’s systems, a cache miss that goes out to main memory often costs 10 to 50 times as much getting the information from the cache; this, incidentally, continues to surprise people because we all think of memory as fast, and it is fast compared to disks and networks, but not compared to on-board cache which runs at faster speeds. If an application’s working set fits into cache, we’re golden, and if it doesn’t, we’re not. That is why increased cache sizes will save some existing applications and breathe life into them for a few more years without requiring significant redesign: As existing applications manipulate more and more data, and as they are incrementally updated to include more code for new features, performance-sensitive operations need to continue to fit into cache. As the Depression-era old-timers will be quick to remind you, “Cache is king.”&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Herb’s article was a pretty serious wake-up call to programmers who hadn’t noticed the trend themselves. (Being one of those who hadn’t noticed, I remember reading his piece, looking at that graph, glancing at the open ad from Fry’s Electronics sitting on the dining room table next to me, and saying to myself, “Holy sh*t, he’s right!”.) Does that qualify it as a “mania”? Perhaps if you’re trying to pooh-pooh the concern, sure. But if you’re a developer who’s wondering where you’re going to get the processing power to address the ever-expanding list of features your users want, something Herb points out as a basic fact of life in the software development world ...&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;There’s an interesting phenomenon that’s known as “Andy giveth, and Bill taketh away.” No matter how fast processors get, software consistently finds new ways to eat up the extra speed. Make a CPU ten times as fast, and software will usually find ten times as much to do (or, in some cases, will feel at liberty to do it ten times less efficiently).&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;...&amp;#160; then eking out the best performance from an application is going to remain at the top of the priority list. Users are classic consumers: they will always want more and more for the same money as before. Ignore this truth of software (actually, of basic microeconomics) at your peril.&lt;/p&gt;  &lt;p&gt;To get back to the editorial, we next come to ...&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;However, the fever was surprisingly short-lived. Intel&apos;s &amp;quot;largest open-source effort ever&amp;quot; to provide a standard tool for writing multi-threaded code, caused little more than a ripple of interest. Various books, rushed out while the temperature soared, advocated the urgent need for new &amp;quot;multi-core-friendly&amp;quot; programming models, involving such things as &amp;quot;software pipelines&amp;quot;. Interesting as they undoubtedly are, they sit stolidly on bookshelves, unread.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Wow. Talk about your pretty aggressive accusation without any supporting evidence or citation whatsoever.&lt;/p&gt;  &lt;p&gt;Intel&apos;s not big into the open-source space, so it doesn&apos;t take much for an open-source project from them to be their &amp;quot;largest open-source effort ever&amp;quot;. (What, they&apos;re going to open-source the schematics for the Intel chipline? Who could read them even if they did? Who would offer up a patch? What good would it do?) The fact that Intel made the software available in the first place meant that they knew the hurdle that had yet to be overcome, and wanted to aid developers in overcoming it. They&apos;re members of the OpenMP group for the same reason.&lt;/p&gt;  &lt;p&gt;Rogue Wave&apos;s software pipelines programming model is another case where real benefits have accrued, backed by case studies. (Disclaimer: I know this because I ghost-wrote an article for them on their Software Pipelines implementation.) Let&apos;s not knock something that&apos;s actually delivered value. Pipelines aren&apos;t going to be the solution to every problem, granted, but they&apos;re a useful way of structuring a design, one that&apos;s curiously similar to what I see in functional programming languages.&lt;/p&gt;  &lt;p&gt;But simply defending Intel&apos;s generosity or the validity of an alternative programming model doesn&apos;t support the idea that concurrency is still a hot topic. No, for that, I need real evidence, something with actual concrete numbers and verifiable fact to it. &lt;/p&gt;  &lt;p&gt;Thus, I point to Brian Goetz’s &lt;em&gt;Java Concurrency in Practice&lt;/em&gt;, one of those “books, rushed out while the temperature soared”, which also turned out to be the best-selling book at Java One 2007, &lt;em&gt;and&lt;/em&gt; the second-best-selling book (behind only Joshua Bloch’s unbelievably good &lt;em&gt;Effective Java (2nd Ed) &lt;/em&gt;) at Java One 2008. Clearly, yes, bestselling concurrency books are just a myth, alongside the magical device that will receive messages from all over the world and play them into your brain (by way of your ears) on demand, or the magical silver bird that can wing its way through the air with no visible means of support as it does so. Myths, clearly, all of them.&lt;/p&gt;  &lt;p&gt;To continue...&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The truth is that it&apos;s simply not a big issue for the majority of people. Writing truly &amp;quot;concurrent&amp;quot; applications in languages such as C# is difficult, as you get very little help from the language. It means getting involved with low-level concurrency primitives, such as lock statements and so on. &lt;/p&gt;    &lt;p&gt;Many programmers lack the skills to do this, but more pertinently lack the need. Increasingly, programmers work in a web environment. As long as these web applications are deployed to a load-balanced web farm, then page requests can be handled in parallel so all available cores will be used efficiently without the need for the programmer to be concerned with fine-grained parallelism.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;He’s right when he says you get very little help from the language, be it C# or Java or C++. And getting involved with low-level concurrency primitives is clearly not in anybody’s best interests, particularly if you’re not a concurrency guru like Brian. (And let’s be honest, even low-level concurrency gurus like Brian, or Joe Duffy, who wrote &lt;em&gt;Concurrent Programming on Windows&lt;/em&gt;, or Mike Woodring, who co-authored &lt;em&gt;Win32 Multithreaded Programming&lt;/em&gt;, have better things to do.) But to say that they “pertinently lack the need” is a rather impertinent statement. “As long as these web applications are deployed to a load-balanced web farm&amp;quot;, which is very likely to continue to happen, “then page requests can be handled in parallel so all available cores will be used …”&lt;/p&gt;  &lt;p&gt;Um... excuse me?&lt;/p&gt;  &lt;p&gt;Didn’t you &lt;em&gt;just&lt;/em&gt; say that programmers &lt;em&gt;didn’t&lt;/em&gt; need to learn concurrency constructs? It would strike me that if their page requests are being handled &lt;em&gt;in parallel&lt;/em&gt; that they have to learn how to write code that won’t break when it’s accessed &lt;em&gt;in parallel&lt;/em&gt; or lead to data-corruption problems or race conditions when their pages are accessed &lt;em&gt;in parallel.&lt;/em&gt; If parallelism is a fundamental part of the Web, don’t you think it’s important for them to learn how to write programs that can behave correctly &lt;em&gt;in parallel&lt;/em&gt;?&lt;/p&gt;  &lt;p&gt;Look for just a moment at the average web application: if data is stored in a per-user collection, and two simultaneous requests come in from a given user (perhaps because the page has AJAX requests being generated by the user on the page, or perhaps because there’s a frameset that’s generating requests for each sub-frame, or ...), what happens if the code is written to read a value from the session, increment it, and store it back? ASP.NET can save you here, a little, in that it used to establish a per-user lock on the entirety of the page request (I don’t know if it still does this—I really have lost any desire to build web apps ever again), but that essentially puts an artificial throttle on the scalability of your system, and makes the end-users’ experience that much slower. Load-balancer going to spray the request all over the farm? So long as the user session state is stored on every machine in the farm, that’ll work... But of course if you store the user’s state in the SQL instance behind each of those machines on the farm, then you take the performance hit of an &lt;em&gt;extra&lt;/em&gt; network round-trip (at which point we’re back to concurrency in the database) ...&lt;/p&gt;  &lt;p&gt;... all because the programmer couldn’t figure out how to make “lock” work? This is progress?&lt;/p&gt;  &lt;p&gt;The Java Servlet specification specifically backed away from this &amp;quot;lock on every request&amp;quot; approach because of the performance implications. I heard a fair amount of wailing and gnashing during the early ASP.NET days over this. I heard the ASP.NET dev team say they made their decision because the average developer can&apos;t figure out concurrency correctly anyway.&lt;/p&gt;  &lt;p&gt;And, by the way folks, this editorial completely ignores XML services. I guess &amp;quot;real&amp;quot; applications don&apos;t write services much, either.&lt;/p&gt;  &lt;p&gt;The next part is even better:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Furthermore, the SQL Server engine behind these web applications is intrinsically &amp;quot;parallel&amp;quot;, and can handle and use effectively about as many cores as you care to throw at it. SQL itself is a declarative rather than procedural language, so it is fundamentally concurrent.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;True… and false. SQL is fundamentally “parallel” (largely because SQL is a non-strict functional language, not just a “declarative” one), but T-SQL isn’t. And how many developers actually know where the line is drawn between SQL and T-SQL? More importantly, though, how many &lt;em&gt;effective&lt;/em&gt; applications can be written with a complete ignorance of the underlying locking model? Why do DBAs spend hours tuning the database’s physical constructs, establishing where isolation levels can be turned down, establishing where the scope of a transaction is too large, putting in indexed columns where necessary, and figuring out where page, row, or table locking will be most efficient? Because despite the view that a relational database presents, these queries are being executed&lt;em&gt; in parallel&lt;/em&gt;, and if a developer wants to avoid writing an application that requires a new server for each and every new user added to the system, they need to learn how to maximize their use of the database’s parallelism. So even if the &lt;em&gt;language&lt;/em&gt; is &amp;quot;fundamentally concurrent&amp;quot; and can thus be relied upon to do the right thing on behalf of the developer, the &lt;em&gt;implementation&lt;/em&gt; isn&apos;t, and needs to be understood in order to be implemented efficiently.&lt;/p&gt;  &lt;p&gt;He finishes:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;For most programmers and for most web applications, however, the multi-core furore is a storm in a teacup; it&apos;s just not relevant. The web and database platforms already cope with concurrency requirements. We are already doing it.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This is one of those times I wish I had a time machine handy—I&apos;d love to step forward five years, have a look around, then come back and report the findings. I&apos;m tempted to close with the challenge to just let’s come back in five years and see what the programming language landscape and hardware landscape looks like. But that&apos;s too easy an &amp;quot;out&amp;quot;, and frankly, doesn&apos;t do much to really instill confidence, in my opinion.&lt;/p&gt;  &lt;p&gt;To ignore the developers building &amp;quot;rich&amp;quot; applications (be they being done in Flex/Flash, Cocoa/iPhone, WinForms, Swing, WPF, or what-have-you) is to also ignore a relatively large segment of the market. Not every application is being built on the web and is backed by a relational database—to simply brush those off and not even consider them as part of the editorial reveals a dangerous bias on the editor&apos;s part. And those applications aren&apos;t hosted in an &amp;quot;intrinsically &apos;parallel&apos;&amp;quot; container that developers can just bury their head inside.&lt;/p&gt;  &lt;p&gt;Like it or not, folks, the path forward isn&apos;t one that you get to choose. Intel, AMD, and other chip manufacturers have already made that clear. They&apos;re &lt;em&gt;not&lt;/em&gt; going to abandon the multicore approach now, not when doing so would mean trying to wrestle with so many problems (including trying to change the speed of light) that simply aren&apos;t there when using a multicore foundation. That isn&apos;t up for debate anymore. Multicore has won for the forseeable future. And, as a result, multicore is going to be a fact of the developer&apos;s life for the forseeable future. Concurrency is thus also a fact of the developer&apos;s life for the forseeable future. &lt;/p&gt;  &lt;p&gt;The web and database platforms “cope” with concurrency requirements by either making &amp;quot;one-size-fits-all&amp;quot; decisions that almost always end up being the wrong decision for high-scale systems (but I&apos;m sure your new startup-based idea, like a system that allows people to push &amp;quot;micro-entries&amp;quot; of no more than 140 characters in length to a publicly-trackable feed would never actually take off and start carrying millions and millions of messages every day, right?), or by punting entirely and forcing developers to dig deeper beneath the covers to see the concurrency there. So if you&apos;re happy with your applications running no faster than 2GHz for the rest of the forseeable future, then sure, you don&apos;t need to worry about learning concurrency-friendly kinds of programming techniques. Bear in mind, by the way, that this essentially locks you in to small-scale, web-plus-database systems for the forseeable future, and clearly nothing with any sort of CPU intensiveness to it whatsoever. Be happy in your niche, and wave to the other COBOL programmers who made the same decision.&lt;/p&gt;  &lt;p&gt;This is a leaky abstraction, full stop, end of story. Anyone who tells you otherwise is either trolling for hits, trying to sell you something, or striving to persuade developers that ignorance isn&apos;t such a bad place to be.&lt;/p&gt;  &lt;p&gt;All you ignorant developers, this is the phrase you will be forced to learn before you start your next job: &amp;quot;Would you like fries with that?&amp;quot;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Laziness in Scala</title>
      <link>http://blogs.newardassociates.com/blog/2009/laziness-in-scala.html</link>
      <pubDate>Sun, 29 Mar 2009 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2009/laziness-in-scala.html</guid>
      	<description>
	&lt;p&gt;While playing around with a recent research-oriented project for myself (more on that later), I discovered something that I haven&apos;t seen mentioned anywhere in the Scala universe before. (OK, not really--as you&apos;ll see towards the end of this piece, it really is documented, but allow me my brief delusions of grandeur as I write this. They&apos;ll get deflated quickly enough.)&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;So the core of the thing was a stack-oriented execution engine; essentially I&apos;m processing commands delivered in a postfix manner. Since some of these commands are relational operators, it&apos;s important that there be two things to relationally operate on the execution stack, after which I want to evaluate the relational operation and push its result (1 if true, 0 if false) back on the stack; this is pretty easily done via the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def compareOp(op : (Int, Int) =&amp;gt; Boolean) = 
{
  checkStack(2)
  val v1 = (execStack.pop()).asInstanceOf[Int]
  val v2 = (execStack.pop()).asInstanceOf[Int]
  val vr = op(v1, v2)
  execStack.push(if (vr) 1 else 0)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where &lt;code&gt;execStack&lt;/code&gt; is a &lt;code&gt;mutable.Stack[Any]&lt;/code&gt; held in an enclosing function.&lt;/p&gt;
&lt;p&gt;Interestingly enough, however, when I wrote this the first time, I wrote it like this, which is a very different sequence of operations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def compareOp(op : (Int, Int) =&amp;gt; Boolean) =
{
  checkStack(2)
  def v1 = (execStack.pop()).asInstanceOf[Int]
  def v2 = (execStack.pop()).asInstanceOf[Int]
  def vr = op(v1, v2)
  execStack.push(if (vr) 1 else 0)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See the difference? Subtle, is it not? But the actual code is significantly different, something that&apos;s more easily seen with a much simpler (and standalone) example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;object App
{
    def main(args : Array[String]) =
    {
        import scala.collection.mutable.Stack
        var stack : Stack[Any] = new Stack()
        stack.push(12)
        stack.push(24)
        def v1 = (stack.pop()).asInstanceOf[Int]
        def v2 = (stack.pop()).asInstanceOf[Int]
        def vr = v1 + v2
        System.out.println(vr)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When run, the console prints out &amp;quot;36&amp;quot;, as we&apos;d well expect.&lt;/p&gt;
&lt;p&gt;But suppose we want to look at those values of v1 and v2 along the way, perhaps as part of a logging operation, or perhaps because you&apos;re just screwing around with some ideas in your head and you don&apos;t want to bother to fire up an IDE with Scala support in it. So you decide to spit those values to a console:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;object App
{
    def main(args : Array[String]) =
    {
        import scala.collection.mutable.Stack
        var stack : Stack[Any] = new Stack()
        stack.push(12)
        stack.push(24)
        def v1 = (stack.pop()).asInstanceOf[Int]
        def v2 = (stack.pop()).asInstanceOf[Int]
        System.out.println(v1)
        System.out.println(v2)
        def vr = v1 + v2
        System.out.println(vr)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then something &lt;em&gt;very&lt;/em&gt; different happens; you get &amp;quot;24&amp;quot;, &amp;quot;12&amp;quot;, and then a NoSuchElementException.&lt;/p&gt;
&lt;p&gt;If you&apos;re like me the first time I ran into this, your first reaction is, &amp;quot;Eh?&amp;quot;. Actually, if you&apos;re like me, when you&apos;re programming, your profanity filters are probaby at an ebb, so your first reaction is &amp;quot;WTF?!?&amp;quot;, said with great gusto and emphasis. Which has a tendency to get some strange looks when you&apos;re at a Denny&apos;s doing your research, I will admit. Particularly when it&apos;s at 3 AM in the morning. And the bar crowd is in full alcoholic haze and slightly nervous about the long-haired, goatee-sporting guy in his headphones, wearing his black leather jacket and swearing like a drunken sailor at his laptop. But I digress.&lt;/p&gt;
&lt;p&gt;What is Scala doing here?&lt;/p&gt;
&lt;p&gt;Turns out this is exactly as the language designers intended, but it&apos;s subtle. (Or maybe it&apos;s just subtle to me at 3AM when I&apos;m pumped full of caffeine.)&lt;/p&gt;
&lt;p&gt;Let&apos;s take this a different way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;object App
{
    def main(args : Array[String]) =
    {
        import scala.collection.mutable.Stack
        var stack : Stack[Any] = new Stack()
        stack.push(12)
        stack.push(24)
        def v1 = (stack.pop()).asInstanceOf[Int]
        def v2 = (stack.pop()).asInstanceOf[Int]
        System.out.println(stack)
    }
} 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When run, the console prints &amp;quot;Stack(12, 24)&amp;quot;, which &lt;em&gt;really&lt;/em&gt; starts to play with your mind when you&apos;re a little short on sleep and a little high on Diet Coke. At first glance, it looks like Scala is broken somehow--after all, those &amp;quot;pop&amp;quot; operations are supposed to modify the Stack against which they&apos;re operating, just as the push()es do. So why is the stack convinced that it still holds the values of 12 and 24?&lt;/p&gt;
&lt;p&gt;Because Scala hasn&apos;t actually executed those pop()s yet.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;def&lt;/code&gt; keyword, it turns out, isn&apos;t what I wanted here--what I wanted (and in retrospect it’s painfully obvious) was a &lt;code&gt;val&lt;/code&gt;, instead, in order to force the execution of those statements and capture the value into a local value (an immutable local variable). The &lt;code&gt;def&lt;/code&gt; keyword, instead, creates a function binding that waits for formal execution before evaluating. So that when I previously said&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;object App
{
    def main(args : Array[String]) =
    {
        import scala.collection.mutable.Stack
        var stack : Stack[Any] = new Stack()
        stack.push(12)
        stack.push(24)
        def v1 = (stack.pop()).asInstanceOf[Int]
        def v2 = (stack.pop()).asInstanceOf[Int]
        def vr = v1 + v2
        System.out.println(vr)
    }
} 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... what in fact I was saying was this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;object App
{
    def main(args : Array[String]) =
    {
        import scala.collection.mutable.Stack
        var stack : Stack[Any] = new Stack()
        stack.push(12)
        stack.push(24)
        def v1 = (stack.pop()).asInstanceOf[Int]
        def v2 = (stack.pop()).asInstanceOf[Int]
        System.out.println(v1 + v2)
    }
} 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... which is the same as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;object App
{
    def main(args : Array[String]) =
    {
        import scala.collection.mutable.Stack
        var stack : Stack[Any] = new Stack()
        stack.push(12)
        stack.push(24)
        System.out.println((stack.pop()).asInstanceOf[Int] + (stack.pop()).asInstanceOf[Int])
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... which, when we look back at my most recent &amp;quot;debugging&amp;quot; version of the code, substituting the &amp;quot;def&amp;quot;ed versions of v1 and v2 (and vr) where they&apos;re used, makes the reason for the NoSuchElementException become entirely more clear:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;object App
{
    def main(args : Array[String]) =
    {
        import scala.collection.mutable.Stack
        var stack : Stack[Any] = new Stack()
        stack.push(12)
        stack.push(24)
        System.out.println((stack.pop()).asInstanceOf[Int])
        System.out.println((stack.pop()).asInstanceOf[Int])
        System.out.println((stack.pop()).asInstanceOf[Int] + (stack.pop()).asInstanceOf[Int])
    }
} 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, normally, this would probably set off all kinds of alarm bells in your head, but the reaction that went off in mine was &amp;quot;COOL!&amp;quot;, the reasons for which revolve around the concept of &amp;quot;laziness&amp;quot;; in a functional language, we frequently don&apos;t want to evaluate the results right away, instead preferring to defer their execution until actually requiring it. In fact, many functional languages—such as Haskell—take laziness to new heights, baking it directly into the language definition and assuming laziness everywhere, so much so that you have to take special steps to avoid it. There’s a variety of reasons why this is advantageous, but I’ll leave those discussions to the Haskellians of the world, like Matt Podwysocki and Simon Peyton-Jones.&lt;/p&gt;
&lt;p&gt;From a Scalist’s perspective, laziness is still a useful tool to have in your toolbox. Suppose you have a really powerful function that calculates PI to a ridiculous number of decimal places. In Java, you might be tempted to do something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class MyMath
{
  public static final double PI = calculatePiToARidiculousNumberOfPlaces();
  private static double calculatePiToARidiculousNumberOfPlaces()
  {
    // implementation left to the reader&apos;s imagination
    // imagine it being &amp;quot;really cool&amp;quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The problem with this is that if that method takes any length of time to execute, it&apos;s being done during class initialization during its ClassLoading phase, and aside from introducing a window of time where the class &lt;em&gt;could&lt;/em&gt; be used before that initialization is finished (it&apos;s subtle, it&apos;s not going to happen very often, but it can, according to older versions of the JVM Spec), the problem is that the time required to do that initialization is paid for &lt;em&gt;regardless of whether you use PI&lt;/em&gt;. In other words, the classic Stroustrup-ian &amp;quot;Don&apos;t pay for it if you don&apos;t use it&amp;quot; principle is being completely tossed aside.&lt;/p&gt;
&lt;p&gt;In Scala, using the &amp;quot;def&amp;quot; keyword here, aside from avoiding the need for the additional decorators, completely eliminates this cost--people won&apos;t need the value of PI until it becomes used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;object App
{
    def PI = calculatePiToARidiculousNumberOfPlaces()
    def calculatePiToARidiculousNumberOfPlaces() =
    {
        System.out.println(&amp;quot;Calculating PI&amp;quot;)
        3 + 0.14
    }
    def main(args : Array[String]) =
    {
        System.out.println(&amp;quot;Entering main&amp;quot;)
        System.out.println(&amp;quot;PI = &amp;quot; + PI)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(In fact, you&apos;d probably just write it without the calculating method definition, since it&apos;s easier that way, but bear with me.)&lt;/p&gt;
&lt;p&gt;When you run this, of course, we see PI being calculated after main()&apos;s been entered, thus proving that PI is being calculated only on demand, not ahead of time, as a public-static-final-constant would be.&lt;/p&gt;
&lt;p&gt;The problem with this approach is, you end up calculating PI on &lt;em&gt;each&lt;/em&gt; access:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;object App
{
    def PI = calculatePiToARidiculousNumberOfPlaces()
    def calculatePiToARidiculousNumberOfPlaces() =
    {
        System.out.println(&amp;quot;Calculating PI&amp;quot;)
        3 + 0.14
    }
    def main(args : Array[String]) =
    {
        System.out.println(&amp;quot;Entering main&amp;quot;)
        System.out.println(&amp;quot;PI = &amp;quot; + PI)
        System.out.println(&amp;quot;PI = &amp;quot; + PI)
            // prints twice! Not good!
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which sort of defeats the advantage of lazy evaluation.&lt;/p&gt;
&lt;p&gt;This got me wondering--in F#, we have lazy as a baked-in concept (sort of), such that when I write&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#light
let sixty = lazy (30 + 30)
System.Console.WriteLine(sixty) 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What I see on the console is not 60, but a Lazy&lt;T&gt; type instance, which effectively defers execution until it&apos;s Force() method is invoked (among other scenarios). This means I can write things like &lt;code&gt;let reallyBigList = lazy ([1..1000000000000] |&amp;gt; complexCalculation |&amp;gt; anotherComplexCalcuation)&lt;/code&gt; without fear of blowing the stack or heap apart, since laziness means the list won&apos;t actually be calculated until it&apos;s forced; we can see this from the following (from the F# interactive console):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; let sixtyWithSideEffect = lazy (printfn &amp;quot;Hello world&amp;quot;; 30+30);;
val sixtyWithSideEffect: Lazy&amp;lt;int&amp;gt;
&amp;gt; sixtyWithSideEffect.Force();;
Hello world
val it : int = 60
&amp;gt; sixtyWithSideEffect.Force();;
val it : int = 60 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Examples taken from the excellent &lt;em&gt;Expert F#&lt;/em&gt; by Syme/Granicz/Cisternino; highly recommended, if a touch out-of-date to the current language definition. I expect Chris Smith’s &lt;em&gt;Programming F#&lt;/em&gt;, from O’Reilly, to correct that before too long.)&lt;/p&gt;
&lt;p&gt;It would be nice if something similar were doable in Scala. Of course, once I start looking for it, it makes itself visible, in the wonderful Venners/Odersky/Spoon book, &lt;em&gt;Programming In Scala&lt;/em&gt;, p. 444:&lt;/p&gt;
&lt;blockquote&gt;
You can use pre-initialized fields to simulate precisely the initialization behavior of class constructor arguments. Sometimes, however, you might prefer to let the system itself sort out how things should be initialized. This can be achieved by making your val definitions lazy. If you prefix a val definition with a lazy modifier, the initializing expression on the right-hand side will only be evaluated the first time the val is used.
&lt;p&gt;...&lt;/p&gt;
&lt;p&gt;This is similar to the situation where x is defined as a parameterless method, using a def. However, unlike a def a lazy val is never evaluated more than once. In fact, after the first evaluation of a lazy val the result of the evaluation is stored, to be reused when the same val is used subsequently.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Perfect! The key, then, is to define PI like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;object App
{
    lazy val PI = calculatePiToARidiculousNumberOfPlaces()
    def calculatePiToARidiculousNumberOfPlaces() =
    {
        System.out.println(&amp;quot;Calculating PI&amp;quot;)
        3 + 0.14
    }
    def main(args : Array[String]) =
    {
        System.out.println(&amp;quot;Entering main&amp;quot;)
        System.out.println(&amp;quot;PI = &amp;quot; + PI)
        System.out.println(&amp;quot;PI = &amp;quot; + PI)
            // prints once! Awesome!
    }
} 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That means, if I apply it to my Stack example from before, I should get the same deferred-execution properties of the &amp;quot;def&amp;quot;-based version ...&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def main(args : Array[String]) =
{
    import scala.collection.mutable.Stack
    var stack : Stack[Any] = new Stack()
    stack.push(12)
    stack.push(24)
    lazy val v1 = (stack.pop()).asInstanceOf[Int]
    lazy val v2 = (stack.pop()).asInstanceOf[Int]
    System.out.println(stack)
        // prints out &amp;quot;Stack(12,24)
} 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... but if I go back to the version that blows up because the stack is empty, using lazy val works exactly the way I would want it to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def main(args : Array[String]) =
{
    import scala.collection.mutable.Stack
    var stack : Stack[Any] = new Stack()
    stack.push(12)
    stack.push(24)
    lazy val v1 = (stack.pop()).asInstanceOf[Int]
    lazy val v2 = (stack.pop()).asInstanceOf[Int]
    System.out.println(v1)
    System.out.println(v2)
    lazy val vr = v1 + v2
    System.out.println(vr)
        // prints 12, 24, then 36
        // and no exception!
} 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nice.&lt;/p&gt;
&lt;p&gt;So, it turns out that my accidental use of &amp;quot;def&amp;quot; inside the compareOp function behaves exactly the way the language designers wanted it to, which is not surprising, and that Scala provides nifty abilities to defer processing or extraction of values until called for.&lt;/p&gt;
&lt;p&gt;Curiously, the two languages differ in how laziness is implemented; in F#, the lazy modifier defines the type to be a Lazy&lt;T&gt; instance, an ordinary type that we can pass around from F# to C# and back again as necessary (in much the same way that C# defined nullable types to be instances of Nullable&lt;T&gt; under the hood). We can see that from the interactive console output above, and from the fact that we call Force() on the instance to evaluate its value.&lt;/p&gt;
&lt;p&gt;In Scala, however, there is no corresponding Lazy[T] type; instead, the PI() method is defined to determine whether or not the value has already been evaluated:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public double PI();
  Code:
   0:   aload_0
   1:   getfield        #135; //Field bitmap$0:I
   4:   iconst_1
   5:   iand
   6:   iconst_0
   7:   if_icmpne       48
   10:  aload_0
   11:  dup
   12:  astore_1
   13:  monitorenter
   14:  aload_0
   15:  getfield        #135; //Field bitmap$0:I
   18:  iconst_1
   19:  iand
   20:  iconst_0
   21:  if_icmpne       42
   24:  aload_0
   25:  aload_0
   26:  invokevirtual   #137; //Method calculatePiToARidiculousNumberOfPlaces:()D
   29:  putfield        #139; //Field PI:D
   32:  aload_0
   33:  aload_0
   34:  getfield        #135; //Field bitmap$0:I
   37:  iconst_1
   38:  ior
   39:  putfield        #135; //Field bitmap$0:I
   42:  getstatic       #145; //Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit;
   45:  pop
   46:  aload_1
   47:  monitorexit
   48:  aload_0
   49:  getfield        #139; //Field PI:D
   52:  dreturn
   53:  aload_1
   54:  monitorexit
   55:  athrow
  Exception table:
   from   to  target type
    14    48    53   any
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you look carefully at the bytecode, the implementation of PI is checking a bitmask field (!) to determine if the first bit is flipped (!) to know whether or not the value is held in the local field PI, and if not, calculate it and store it there. This means that Java developers will just need to call PI() over and over again, rather than have to know that the instance is actually a Lazy[T] on which they need to call Value or Force (such as one would from C# in the F# case). Frankly, I don’t know at this point which approach I prefer, but I’m slightly leaning towards the Scala version for now. (If only Java supported properties, then the syntax “MyMath.PI” would look like a constant, act lazily, and everything would be great.)&lt;/p&gt;
&lt;p&gt;(It strikes me that the F# developer looking to write something C#-accessible need only tuck the Lazy&lt;T&gt; instance behind a property accessor and the problem goes away, by the way; it would just be nicer to not have to do anything special on either side, to have my laziness and Force() it, too. Pipe dream, perhaps.)&lt;/p&gt;
&lt;p&gt;In retrospect, I could wish that Scala weren&apos;t &lt;em&gt;quite&lt;/em&gt; so subtle in its treatment of &amp;quot;def&amp;quot; vs &amp;quot;val&amp;quot;, but now that I&apos;m aware of it, it&apos;ll (hopefully) not bite me quite so subtly in the sensitive spots of my anatomy again.&lt;/p&gt;
&lt;p&gt;And any experience in which you learn something is a good one, right?&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>From the Mailbag: Polyglot Programmer vs Polyactivist Language</title>
      <link>http://blogs.newardassociates.com/blog/2009/from-the-mailbag-polyglot-programmer-vs-polyactivist-language.html</link>
      <pubDate>Tue, 24 Mar 2009 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2009/from-the-mailbag-polyglot-programmer-vs-polyactivist-language.html</guid>
      	<description>
	&lt;p&gt;This crossed my Inbox:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I read your article entitled: The Polyglot Programmer. How about the thought that rather than becoming a polyglot-software engineer; pick a polyglot-language. For example, C# is borrowing techniques from functional and dynamic languages. Let the compiler designer worry about mixing features and software engineers worry about keep up with the mixture. Is this a good approach? *[From Phil, at &lt;a href=&quot;http://greensoftwareengineer.spaces.live.com/&quot;&gt;http://greensoftwareengineer.spaces.live.com/&lt;/a&gt;]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!--more--&gt;
&lt;p&gt;Phil, it’s an interesting thought you’ve raised—which is the better/easier approach to take, that of incorporating the language features we want into a single language, rather than needing to learn all those different languages (and their own unique syntaxes) in order to take advantage of those features we want?
&lt;p&gt;After all, we’re starting to see this taking place within a certain number of languages already, particularly C#; first, in 3.0, they introduced a number of features in support of LINQ that make C# a useful starting point for working with a functional language. Extension methods, for example, allow us to add a number of different methods to the collection classes that provide some functional capabilities (Select&amp;lt;&amp;gt;, GroupBy&amp;lt;&amp;gt;, and so on), as Matt Podwysocki demonstrates, generics contribute the type-safety that most functional languages embrace, anonymous methods and delegates provide better functions-as-first-class-constructs (including lambdas), and anonymous types make it vastly easier to return and pass tuples. And now, in 4.0, we’re getting the “dynamic” keyword, which will add support for invoking methods and properties dynamically, in the grand tradition of most dynamic languages (like Python and Ruby), and 3.0’s local variable type inference allows us to write &lt;code&gt;var x = ...&lt;/code&gt;, which feels pretty dynamic (even if it’s not, under the hood).&lt;/p&gt;
&lt;p&gt;Unfortunately, I think for the most part, the answer’s going to be, “Yes, it would be nice, if it weren’t for the fact that there are very few languages that won’t collapse underneath their own weight if they did so.”&lt;/p&gt;
&lt;p&gt;Consider, for example, the C# language. Already, with the C# 3.0 definition, the language specification weighs in at close to a thousand pages. The additional features in 4.0 could easily push it over a thousand and possibly, with all the places where “dynamic” behavior will need to be factored into the existing specification, could push that well into the 1200 to 1300 page range. What’s the upper limit on a language’s complexity to maintain and enhance, much less for its programmers to comprehend?&lt;/p&gt;
&lt;p&gt;(By comparison, the C++ specification, as I can best remember, didn’t weigh in at more than a thousand pages, but given that the current working draft is under password protection, and I can’t find the prior spec as a freely-available download, I can’t see if memory is correct or not.)&lt;/p&gt;
&lt;p&gt;Or, consider the various edge cases that came up around the introduction of nullable types in C# 2.0. What started out as a fairly simple suggestion—“let’s let &lt;code&gt;T?&lt;/code&gt; represent the idea that this instance of &lt;code&gt;T&lt;/code&gt; could be nullable, and at runtime it’ll be a &lt;code&gt;Nullable&amp;lt;T&amp;gt;&lt;/code&gt; instance behind the scenes”—turned into a pretty ugly morass of edge cases at the language level that resulted in some serious bug-fixing right up until the final ship date.&lt;/p&gt;
&lt;p&gt;Thing is, languages that aren’t written deliberately to allow their own modification and evolution tend to fail over time. C++ was one such example, and I think both Java and C# will stand as successor examples before long.&lt;/p&gt;
&lt;p&gt;Right now, in C# 3.0, type inference is limited entirely to local variables because the language isn’t syntactically set up to leave out type names wherever possible—the “var” token is a type placeholder, largely because the parser has to have a type first. (This is the same purpose the “dynamic” keyword seems to be playing for 4.0, though I can’t say so for certain.) In F# and Scala, this syntax is deliberately written Pascal-style, with the name first, optionally followed by a colon and the type, because the parser can see the colon and realize the type is already specified, or see no colon and realize the type should be inferred. That syntax is used consistently throughout the F# and Scala languages, and that means it’s pretty easy, lexically speaking, for the languages to recognize when type inference should kick in.&lt;/p&gt;
&lt;p&gt;What’s more, both F# and Scala don’t really support the O-O notion of method overloading, because again, it gets confusing when trying to kick in type inference—something about too many possibilities confusing the type-inferencer. (I’m not entirely positive of this point, by the way, it’s based on some conversations I’ve had with language designers over the last few years. I could be wrong, and would love to see a language that supports both.) Instead, they force developers to be more explicit about parameters being passed—F# won’t even do implicit widening conversions, in fact, such as automatically widening ints to longs.&lt;/p&gt;
&lt;p&gt;But both F# and Scala have a &lt;em&gt;very&lt;/em&gt; interesting facility to allow definitions of methods/functions using very flexible syntactic rules, such that they look like operators or keywords built into the language; F# defines its pipeline operator ( &lt;code&gt;|&amp;gt;&lt;/code&gt; ) in its library definitions, for example. Scala defines numerous “keywords”, like synchronized or transient, as classes in the Scala package extending “StaticAnnotation”—in other words, their syntax and behavior is defined as an annotation, rather than as a built-in part of the language. Ditto for Scala’s XML support.&lt;/p&gt;
&lt;p&gt;Lisp, of course, was one of the first (if not &lt;em&gt;the&lt;/em&gt; first) language to do this, and it’s my understanding that this has been one of the principal reasons it has survived all these years as a language—because it’s an abstraction built on top of an abstraction built on top of an abstraction, &lt;em&gt;et al&lt;/em&gt;, it makes it easier to change those underlying abstractions when the context changes.&lt;/p&gt;
&lt;p&gt;This doesn’t mean those “polyactivist” languages like C# are bad things, it just means that there’s a danger that they’ll eventually collapse from too many moving parts all trying to talk to each other at the same time. As an exercise, open the C# 3.0 spec, and start checking off all the sections that will need to be touched by the introduction of the “dynamic” keyword as a new type.&lt;/p&gt;
&lt;p&gt;Or, to put it analagously, yes, for a lot of work, a single multifunction tool can be useful, but for a lot of other work, you want tools that are specialized to the task at hand. Let’s not minimize the usefulness of that multifunction tool, but let’s not try to use a Swiss Army knife where a jeweler’s screwdriver is really needed.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2009 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2009/2009-tech-predictions.html</link>
      <pubDate>Wed, 31 Dec 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2009/2009-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;It&apos;s once again that time of year, and in keeping with my tradition, I&apos;ll revisit the 2008 predictions to see how close I came before I start waxing prophetic on the coming year. (I&apos;m thinking that maybe the next year--2010&apos;s edition--I should actually take a shot at predicting the next decade, but I&apos;m not sure if I&apos;d remember to go back and revisit it in 2020 to see how I did. Anybody want to set a calendar reminder for Dec 31 2019 and remind me, complete with URL? ;-) )&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Without further preamble, here&apos;s what I said for 2008:&lt;/p&gt; 
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;General&lt;/em&gt;: The buzz around building custom languages will only continue to build. More and more tools are emerging to support the creation of custom programming languages, like Microsoft&apos;s Phoenix, Scala&apos;s parser combinators, the Microsoft DLR, SOOT, Javassist, JParsec/NParsec, and so on. Suddenly, the whole &quot;write your own lexer and parser and AST from scratch&quot; idea seems about as outmoded as the idea of building your own String class. Granted, there are cases where a from-hand scanner/lexer/parser/AST/etc is the Right Thing To Do, but there are times when building your own String class is the Right Thing To Do, too. Between the rich ecosystem of dynamic languages that could be ported to the JVM/CLR, and the interesting strides being made on both platforms (JVM and CLR) to make them more &quot;dynamic-friendly&quot; (such as being able to reify classes or access the call stack directly), the probability that your company will find a need that is best answered by building a custom language are only going to rise. &lt;strong&gt;NOW: &lt;/strong&gt;The buzz has definitely continued to build, but buzz can only take us so far. There&apos;s been some scattershot use of custom languages in a few scattershot situations, but it&apos;s certainly not &quot;taken the world by storm&quot; in any meaningful way yet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;General&lt;/em&gt;: The hype surrounding &quot;domain-specific languages&quot; will peak in 2008, and start to generate a backlash. Let&apos;s be honest: when somebody looks you straight in the eye and suggests that &quot;scattered, smothered and covered&quot; is a domain-specific language, the term has lost all meaning. A lexicon unique to an industry is not a domain-specific language; it&apos;s a lexicon. Period. If you can incorporate said lexicon into your software, thus making it accessible to non-technical professionals, that&apos;s a good thing. But simply using the lexicon doesn&apos;t make it a domain-specific language. Or, alternatively, if you like, every single API designed for a particular purpose is itself a domain-specific language. This means that Spring configuration files are a DSL. Deployment descriptors are a DSL. The Java language is a DSL (since the domain is that of programmers familiar with the Java language). See how nonsensical this can get? Until somebody comes up with a workable definition of the term &quot;domain&quot; in &quot;domain-specific language&quot;, it&apos;s a nonsensical term. The idea is a powerful one, mind you--creating something that&apos;s more &quot;in tune&quot; with what users understand and can use easily is a technique that&apos;s been proven for decades now. Anybody who&apos;s ever watched an accountant rip an entirely new set of predictions for the new fiscal outlook based entirely on a few seed numbers and a deeply-nested set of Excel macros knows this already. Whether you call them domain-specific languages or &quot;little languages&quot; or &quot;user-centric languages&quot; or &quot;macro language&quot; is really up to you. &lt;strong&gt;NOW:&lt;/strong&gt; The backlash hasn&apos;t begun, but only because the DSL buzz hasn&apos;t materialized in much way yet--see previous note. It generally takes a year or two of deployments (and hard-earned experience) before a backlash begins, and we haven&apos;t hit that &quot;deployments&quot; stage yet in anything yet resembling &quot;critical mass&quot; yet. But the DSL/custom language buzz continues to grow, and the more the buzz grows, the more the backlash is likey.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;General&lt;/em&gt;: Functional languages will begin to make their presence felt. Between Microsoft&apos;s productization plans for F# and the growing community of Scala programmers, not to mention the inherently functional concepts buried inside of LINQ and the concurrency-friendly capabilities of side-effect-free programming, the world is going to find itself working its way into functional thinking either directly or indirectly. And when programmers start to see the inherent capabilities inside of Scala (such as Actors) and/or F# (such as asynchronous workflows), they&apos;re going to embrace the strange new world of functional/object hybrid and never look back. &lt;strong&gt;NOW:&lt;/strong&gt; Several books on F# and Scala (and even one or two on Haskell!) were published in 2008, and several more (including one of my own) are on the way. The functional buzz is building, and lots of disparate groups are each evaluating it (functional programming) independently.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;General&lt;/em&gt;: MacOS is going to start posting some serious market share numbers, leading lots of analysts to predict that Microsoft Windows has peaked and is due to collapse sometime within the remainder of the decade. Mac&apos;s not only a wonderful OS, but it&apos;s some of the best hardware to run Vista on. That will lead not a few customers to buy Mac hardware, wipe the machine, and install Vista, as many of the uber-geeks in the Windows world are already doing. This will in turn lead Gartner (always on the lookout for an established trend they can &quot;predict&quot; on) to suggest that Mac is going to end up with 115% market share by 2012 (.8 probability), then sell you this wisdom for a mere price of $1.5 million (per copy). &lt;strong&gt;NOW:&lt;/strong&gt; Can&apos;t speak to the Gartner report--I didn&apos;t have $1.5 million handy--but certainly the MacOS is growing in popularity. More on that later.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;em&gt;General&lt;/em&gt;: Ted will be hired by Gartner... if only to keep him from smacking them around so much. .0001 probability, with probability going up exponentially as my salary offer goes up exponentially. (Hey, I&apos;ve got kids headed for college in a few years.) &lt;strong&gt;NOW:&lt;/strong&gt; Well, Gartner appears to have lost my email address and phone number, but I&apos;m sure they were planning to make me that offer.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;General&lt;/em&gt;: MacOS is going to start creaking in a few places. The Mac OS is a wonderful OS, but it&apos;s got its own creaky parts, and the more users that come to Mac OS, the more that software packages are going to exploit some of those creaky parts, leading to some instability in the Mac OS. It won&apos;t be widespread, but for those who are interested in finding it, they&apos;re there. Assuming current trends (of customers adopting Mac OS) hold, the Mac OS 10.6 upgrade is going to be a very interesting process, indeed. &lt;strong&gt;NOW:&lt;/strong&gt; Shhh. Don&apos;t tell anybody, but I&apos;ve been seeing it starting to happen. Don&apos;t get me wrong, Apple still does a pretty good job with the OS, but the law of numbers has started to create some bad upgrade scenarios for some people.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;General&lt;/em&gt;: Somebody is going to realize that iTunes is the world&apos;s biggest monopoly on music, and Apple will be forced to defend itself in the court of law, the court of public opinion, or both. Let&apos;s be frank: if this were Microsoft, offering music that can only be played on Microsoft music players, the world would be through the roof. All UI goodness to one side, the iPod represents just as much of a monopoly in the music player business as Internet Explorer did in the operating system business, and if the world doesn&apos;t start taking Apple to task over this, then &quot;justice&quot; is a word that only applies when losers in an industry want to drag down the market leader (which I firmly believe to be the case--nobody likes more than to pile on the successful guy). &lt;strong&gt;NOW:&lt;/strong&gt; Nothing this year.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;General&lt;/em&gt;: Somebody is going to realize that the iPhone&apos;s &quot;nothing we didn&apos;t write will survive the next upgrade process&quot; policy is nothing short of draconian. As my father, who gets it right every once in a while, says, &quot;If I put a third-party stereo in my car, the dealer doesn&apos;t get to rip it out and replace it with one of their own (or nothing at all!) the next time I take it in for an oil change&quot;. Fact is, if I buy the phone, I own the phone, and I own what&apos;s on it. Unfortunately, this takes us squarely into the realm of DRM and IP ownership, and we all know how clear-cut that is... But once the general public starts to understand some of these issues--and I think the iPhone and iTunes may just be the vehicle that will teach them--look out, folks, because the backlash will be huge. As in, &quot;Move over, Mr. Gates, you&apos;re about to be joined in infamy by your other buddy Steve....&quot; &lt;strong&gt;NOW:&lt;/strong&gt; Apple released iPhone 2.0, and with it, the iPhone SDK, so at least Apple has opened the dashboard to third-party stereos. But the deployment model (AppStore) is still a bit draconian, and Apple still jealously holds the reins over which apps can be deployed there and which ones can&apos;t, so maybe they haven&apos;t learned their lesson yet, after all....&lt;/li&gt; &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;Java&lt;/em&gt;: The OpenJDK in Mercurial will slowly start to see some external contributions. The whole point of Mercurial is to allow for deeper control over which changes you incorporate into your build tree, so once people figure out how to build the JDK and how to hack on it, the local modifications will start to seep across the Internet.... &lt;strong&gt;NOW:&lt;/strong&gt; OpenJDK has started to collect contributions from external (to Sun) sources, but still in relatively small doses, it seems. None of the local modifications I envisioned creeping across the &apos;Net have begun, that I can see, so maybe it&apos;s still waiting to happen. Or maybe the OpenJDK is too complicated to really allow for that kind of customization, and it never will.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;em&gt;Java&lt;/em&gt;: SpringSource will soon be seen as a vendor like BEA or IBM or Sun. Perhaps with a bit better reputation to begin, but a vendor all the same. &lt;strong&gt;NOW:&lt;/strong&gt; SpringSource&apos;s acquisition of G2One (the company behind Groovy just as SpringSource backs Spring) only reinforced this image, but it seems it&apos;s still something that some fail to realize or acknowledge due to Spring&apos;s open-source (?) nature. (I&apos;m not a Spring expert by any means, but apparently Spring 3 was pulled back inside the SpringSource borders, leading some people to wonder what SpringSource is up to, and whether or not Spring will continue to be open source after all.)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;em&gt;.NET&lt;/em&gt;: Interest in OpenJDK will bootstrap similar interest in Rotor/SSCLI. After all, they&apos;re both VMs, with lots of interesting ideas and information about how the managed platforms work. &lt;strong&gt;NOW:&lt;/strong&gt; Nope, hasn&apos;t really happened yet, that I can see. Not even the 2nd edition of the SSCLI book (by Joel Pobar and yours truly, yes that was a plug) seemed to foster the kind of attention or interest that I&apos;d expected, or at least, not on the scale I&apos;d thought might happen.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;THEN: &lt;/strong&gt;&lt;em&gt;C++/Native&lt;/em&gt;: If you&apos;ve not heard of LLVM before this, you will. It&apos;s a compiler and bytecode toolchain aimed at the native platforms, complete with JIT and GC. &lt;strong&gt;NOW:&lt;/strong&gt; Apple sank a lot of investment into LLVM, including hosting an LLVM conference at the corporate headquarters.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;em&gt;Java&lt;/em&gt;: Somebody will create Yet Another Rails-Killer Web Framework. &apos;Nuff said. &lt;strong&gt;NOW:&lt;/strong&gt; You know what? I honestly can&apos;t say whether this happened or not; I was completely not paying attention.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;em&gt;Native&lt;/em&gt;: Developers looking for a native programming language will discover D, and be happy. Considering D is from the same mind that was the core behind the Zortech C++ compiler suite, and that D has great native platform integration (building DLLs, calling into DLLs easily, and so on), not to mention automatic memory management (except for those areas where you want manual memory management), it&apos;s definitely worth looking into. &lt;a href=&quot;http://www.digitalmars.com&quot;&gt;www.digitalmars.com&lt;/a&gt; &lt;strong&gt;NOW:&lt;/strong&gt; D had its own get-together as well, and appears to still be going strong, among the group of developers who still work on native apps (and aren&apos;t simply maintaining legacy C/C++ apps).&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Now, for the 2009 predictions. The last set was a little verbose, so let me see if I can trim the list down a little and keep it short and sweet:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;em&gt;General:&lt;/em&gt; &quot;Cloud&quot; will become the next &quot;ESB&quot; or &quot;SOA&quot;, in that it will be something that everybody will talk about, but few will understand and even fewer will do anything with. (Considering the widespread disparity in the definition of the term, this seems like a no-brainer.)&lt;/li&gt; &lt;li&gt;&lt;em&gt;Java&lt;/em&gt;: Interest in Scala will continue to rise, as will the number of detractors who point out that Scala is too hard to learn.&lt;/li&gt; &lt;li&gt;&lt;em&gt;.NET&lt;/em&gt;: Interest in F# will continue to rise, as will the number of detractors who point out that F# is too hard to learn. (Hey, the two really are cousins, and the fortunes of one will serve as a pretty good indication of the fortunes of the other, and both really seem to be on the same arc right now.)&lt;/li&gt; &lt;li&gt;&lt;em&gt;General:&lt;/em&gt; Interest in all kinds of functional languages will continue to rise, and more than one person will take a hint from Bob &quot;crazybob&quot; Lee and liken functional programming to AOP, for good and for ill. People who took classes on Haskell in college will find themselves reaching for their old college textbooks again.&lt;/li&gt; &lt;li&gt;&lt;em&gt;General:&lt;/em&gt; The iPhone is going to be hailed as &quot;the enterprise development platform of the future&quot;, and companies will be rolling out apps to it. Look for Quicken iPhone edition, PowerPoint and/or Keynote iPhone edition, along with connectors to hook the iPhone up to a presentation device, and (I&apos;ll bet) a World of Warcraft iPhone client (legit or otherwise). iPhone is the new hotness in the mobile space, and people will flock to it madly.&lt;/li&gt; &lt;li&gt;&lt;em&gt;.NET&lt;/em&gt;: Another Oslo CTP will come out, and it will bear only a superficial resemblance to the one that came out in October at PDC. Betting on Oslo right now is a fools&apos; bet, not because of any inherent weakness in the technology, but just because it&apos;s way too early in the cycle to be thinking about for anything vaguely resembling production code.&lt;/li&gt; &lt;li&gt;&lt;em&gt;.NET&lt;/em&gt;: The IronPython and IronRuby teams will find some serious versioning issues as they try to manage the DLR versioning story between themselves and the CLR as a whole. An initial hack will result, which will be codified into a standard practice when .NET 4.0 ships. Then the next release of IPy or IRb will have to try and slip around its restrictions in 2010/2011. By 2012, IPy and IRb will have to be shipping as part of Visual Studio just to put the releases back into lockstep with one another (and the rest of the .NET universe).&lt;/li&gt; &lt;li&gt;&lt;em&gt;Java&lt;/em&gt;: The death of JSR-277 will spark an uprising among the two leading groups hoping to foist it off on the Java community--OSGi and Maven--while the rest of the Java world will breathe a huge sigh of relief and look to see what &quot;modularity&quot; means in Java 7. Some of the alpha geeks in Java will start using--if not building--JDK 7 builds just to get a heads-up on its impact, and be quietly surprised and, I dare say, perhaps even pleased.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Java&lt;/em&gt;: The invokedynamic JSR will leapfrog in importance to the top of the list.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Windows&lt;/em&gt;: Another Windows 7 CTP will come out, and it will spawn huge media interest that will eventually be remembered as Microsoft promises, that will eventually be remembered as Microsoft guarantees, that will eventually be remembered as Microsoft FUD and &quot;promising much, delivering little&quot;. Microsoft ain&apos;t always at fault for the inflated expectations people have--sometimes, yes, perhaps even a lot of times, but not always.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Mac OS&lt;/em&gt;: Apple will begin to legally threaten the clone market again, except this time somebody&apos;s going to get the DOJ involved. (Yes, this is the iPhone/iTunes prediction from last year, carrying over. I still expect this to happen.)&lt;/li&gt; &lt;li&gt;&lt;em&gt;Languages&lt;/em&gt;: Alpha-geek developers will start creating their own languages (even if they&apos;re obscure or bizarre ones like Shakespeare or Ook#) just to have that listed on their resume as the DSL/custom language buzz continues to build.&lt;/li&gt; &lt;li&gt;&lt;em&gt;XML Services&lt;/em&gt;: Roy Fielding will officially disown most of the &quot;REST&quot;ful authors and software packages available. Nobody will care--or worse, somebody looking to make a name for themselves will proclaim that Roy &quot;doesn&apos;t really understand REST&quot;. And they&apos;ll be right--Roy doesn&apos;t understand what &lt;em&gt;they&lt;/em&gt; consider to be REST, and the fact that he created the term will be of no importance anymore. Being &quot;REST&quot;ful will equate to &quot;I did it myself!&quot;, complete with expectations of a gold star and a lollipop.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Parrot&lt;/em&gt;: The Parrot guys will make at least one more minor point release. Nobody will notice or care, except for a few doggedly stubborn Perl hackers. They will find themselves having nightmares of previous lives carrying around OS/2 books and Amiga paraphernalia. Perl 6 will celebrate it&apos;s seventh... or is it eighth?... anniversary of being announced, and nobody will notice.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Agile&lt;/em&gt;: The debate around &quot;Scrum Certification&quot; will rise to a fever pitch as short-sighted money-tight companies start looking for reasons to cut costs and either buy into agile at a superficial level and watch it fail, or start looking to cut the agilists from their company in order to replace them with cheaper labor.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Flash&lt;/em&gt;: Adobe will continue to make Flex and AIR look more like C# and the CLR even as Microsoft tries to make Silverlight look more like Flash and AIR. Web designers will now get to experience the same fun that back-end web developers have enjoyed for near-on a decade, as shops begin to artificially partition themselves up as either &quot;Flash&quot; shops or &quot;Silverlight&quot; shops.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Personal&lt;/em&gt;: Gartner will still come knocking, looking to hire me for outrageous sums of money to do nothing but blog and wax prophetic.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Well, so much for brief or short. See you all again next year....&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Myth of Discovery</title>
      <link>http://blogs.newardassociates.com/blog/2008/the-myth-of-discovery.html</link>
      <pubDate>Wed, 10 Dec 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/the-myth-of-discovery.html</guid>
      	<description>
	&lt;p&gt;It amazes me how insular and inward-facing the software industry is.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;And how the &amp;quot;agile&amp;quot; movement is reaping the benefits of a very simple characteristic.&lt;/p&gt;
&lt;p&gt;For example, consider Jeff Palermo&apos;s essay on &lt;a href=&quot;http://jeffreypalermo.com/blog/the-myth-of-self-organizing-teams/&quot;&gt;&quot;The Myth of Self-Organizing Teams&quot;&lt;/a&gt;. Now, nothing against Jeff, or his post, &lt;em&gt;per se&lt;/em&gt;, but it amazes me how our industry believes that they are somehow inventing new concepts, such as, in this case the &quot;self-organizing team&quot;. Team dynamics have been a subject of study for decades, and anyone with a background in psychology, business, or sales has probably already been through much of the material on it. The best teams are those that find their own sense of identity, that grow from within, but still accept some leadership from the outside--the classic example here being the championship sports team. Most often, that sense of identity is born of a string of successes, which is why teams without a winning tradition have such a hard time creating the &lt;em&gt;esprit de corps&lt;/em&gt; that so often defines the difference between success and failure. &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;(Editor&apos;s note: Here&apos;s a free lesson to all of you out there who want to help your team grow its own sense of identity: give them a chance to win a few successes, and they&apos;ll start coming together pretty quickly. It&apos;s not always that easy, but it works more often than not.)&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;How many software development managers--much less technical leads or project managers--have actually gone and looked through the management aisle at the local bookstore?&lt;/p&gt; &lt;p&gt;Tom and Mary Poppendieck have been spending years now talking about &quot;lean&quot; software development, which itself (at a casual glance) seems to be a refinement of the concepts Toyota and other Japanese manufacturers were pursuing close to two decades ago. &quot;Total quality management&quot; was a concept introduced in those days, the idea that anyone on the production line was empowered to stop the line if they found something that wasn&apos;t right. (My father was one of those &quot;lean&quot; manufacturing advocates back in the 80&apos;s, in fact, and has some great stories he can tell to its successes, and failures.)&lt;/p&gt; &lt;p&gt;How many software development managers or project leads give their developers the chance to say, &quot;No, it&apos;s not right yet, we can&apos;t ship&quot;, and back them on it? Wouldn&apos;t you, as a developer, feel far more involved in the project if you knew you had that power--and that responsibility?&lt;/p&gt; &lt;p&gt;Or consider the &quot;agile&quot; notion of customer involvement, the classic XP &quot;On-Site Customer&quot; principle. Sales people have known for years, even decades (if not centuries), that if you involve the customer in the process, they are much more likely to feel an ownership stake sooner than if they just take what&apos;s on the lot or the shelf. Skilled salespeople have done the &quot;let&apos;s walk through what you &lt;em&gt;might&lt;/em&gt; buy, if you were buying, of course&quot; trick countless numbers of times, and ended up with a sale where the customer didn&apos;t even intend to buy.&lt;/p&gt; &lt;p&gt;How many software development managers or project leads have read a book on basic salesmanship? And yet, isn&apos;t that notion of extracting what the customer wants endemic to both software development and basic sales (of anything)?&lt;/p&gt; &lt;p&gt;What is it about the software industry that just collectively refuses to accept that there might be lots of interesting research on topics that aren&apos;t technical yet still something that we can use? Why do we feel so compelled to trumpet our own &quot;innovations&quot; to ourselves, when in fact, they&apos;ve been long-known in dozens of other contexts? When will we wake up and realize that we can learn a lot more if we cross-train in other areas... like, for example, getting your MBA?&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>REST != HTTP</title>
      <link>http://blogs.newardassociates.com/blog/2008/rest--http.html</link>
      <pubDate>Fri, 7 Nov 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/rest--http.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven&quot;&gt;Roy Fielding has weighed in&lt;/a&gt; on the recent &quot;buzzwordiness&quot; (hey, if Colbert can make up &quot;truthiness&quot;, then I can make up &quot;buzzwordiness&quot;) of calling everything a &quot;REST API&quot;, a tactic that has become more &lt;em&gt;en vogue&lt;/em&gt; of late as vendors discover that the general programming population is finding the WSDL-based XML services stack too complex to navigate successfully for all but the simplest of projects. Contrary to what many RESTafarians may be hoping, Roy doesn&apos;t gather all these wayward children to his breast and praise their anti-vendor/anti-corporate/anti-proprietary efforts, but instead, blasts them pretty seriously for mangling his term:&lt;/p&gt;
&lt;!--more--&gt;
&lt;blockquote&gt; &lt;p&gt;I am getting frustrated by the number of people calling any HTTP-based interface a REST API. Today’s example is the &lt;a href=&quot;http://wikis.glassfish.org/socialsite/Wiki.jsp?page=FinalizeRESTAPI&quot;&gt;SocialSite REST API&lt;/a&gt;. That is RPC. It screams RPC. There is so much coupling on display that it should be given an X rating.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Ouch. &quot;So much coupling on display that it should be given an X rating.&quot; I have to remember that phrase--that&apos;s a keeper. And I&apos;m shocked that Roy even knows what an X rating is; he&apos;s such a mellow guy with such an innocent-looking face, I would&apos;ve bet money he&apos;d never run into one before. &lt;em&gt;(Yes, people, that&apos;s a joke.)&lt;/em&gt; &lt;blockquote&gt; &lt;p&gt;What needs to be done to make the REST architectural style clear on the notion that hypertext is a constraint? In other words, if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API. Period. Is there some broken manual somewhere that needs to be fixed?&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Go Roy!&lt;/p&gt; &lt;p&gt;For those of you who&apos;ve &lt;em&gt;not&lt;/em&gt; read Roy&apos;s thesis, and are thinking that this is some kind of betrayal or trick, let&apos;s first of all point out that at no point is Roy saying that your nifty HTTP-based API is not &lt;em&gt;useful&lt;/em&gt; or &lt;em&gt;simple&lt;/em&gt;. He&apos;s simply saying that it isn&apos;t &lt;em&gt;RESTful&lt;/em&gt;. That&apos;s a key differentiation. REST has a specific set of goals and constraints it was trying to meet, and as such prescribes a particular kind of architectural style to fit within those constraints. (Yes, REST is essentially an architectural pattern: a solution to a problem within a certain context that yields certain consequences.)&lt;/p&gt; &lt;p&gt;Assuming you haven&apos;t tuned me out completely already, allow me to elucidate. In Chapter 5 of &lt;a href=&quot;http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm&quot;&gt;Roy&apos;s thesis&lt;/a&gt;, Roy begins to build up the style that will ultimately be considered REST. I&apos;m not going to quote each and every step here--that&apos;s what the hyperlink above is for--but simply call out certain parts. For example, in section 5.1.3, &quot;Stateless&quot;, he suggests that this architectural style should be stateless in nature, and explains why; the emphasis/italics are mine:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;We next add a constraint to the client-server interaction: communication must be stateless in nature, as in the client-stateless-server (CSS) style of Section 3.4.3 (Figure 5-3), such that &lt;em&gt;each request from client to server must contain all of the information necessary to understand the request&lt;/em&gt;, and cannot take advantage of any stored context on the server. &lt;em&gt;Session state is therefore kept entirely on the client&lt;/em&gt;.  &lt;p&gt;This constraint induces the properties of visibility, reliability, and scalability. Visibility is improved because a monitoring system does not have to look beyond a single request datum in order to determine the full nature of the request. Reliability is improved because it eases the task of recovering from partial failures [133]. Scalability is improved because not having to store state between requests allows the server component to quickly free resources, and further simplifies implementation because the server doesn&apos;t have to manage resource usage across requests.  &lt;p&gt;Like most architectural choices, the stateless constraint reflects a design trade-off. The disadvantage is that it may decrease network performance by increasing the repetitive data (per-interaction overhead) sent in a series of requests, since that data cannot be left on the server in a shared context. In addition, placing the application state on the client-side reduces the server&apos;s control over consistent application behavior, since the application becomes dependent on the correct implementation of semantics across multiple client versions.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;In the HTTP case, the state is contained entirely in the document itself, the hypertext. This has a couple of implications for those of us building &quot;distributed applications&quot;, such as the very real consideration that there&apos;s a &lt;em&gt;lot&lt;/em&gt; of state we don&apos;t necessarily want to be sending back to the client, such as voluminous information (the user&apos;s e-commerce shopping cart contents) or sensitive information (the user&apos;s credentials or single-signon authentication/authorization token). This is a bitter pill to swallow for the application development world, because much of the applications we develop have some pretty hefty notions of server-based state management that we want or need to preserve, either for legacy support reasons, for legitimate concerns (network bandwidth or security), or just for ease-of-understanding. Fielding isn&apos;t apologetic about it, though--look at the third paragraph above. &quot;[T]he stateless constraint reflects a design trade-off.&quot;&lt;/p&gt; &lt;p&gt;In other words, if you don&apos;t like it, fine, don&apos;t follow it, but understand that if you&apos;re not leaving all the application state on the client, you&apos;re not doing REST.&lt;/p&gt; &lt;p&gt;By the way, note that technically, HTTP is not tied to HTML, since the document sent back and forth could easily be a PDF document, too, particularly since PDF supports hyperlinks to other PDF documents. Nowhere in the thesis do we see the idea that it &lt;em&gt;has&lt;/em&gt; to be HTML flying back and forth.&lt;/p&gt; &lt;p&gt;Roy&apos;s thesis continues on in the same vein; in section 5.1.4 he describes how &quot;client-cache-stateless-server&quot; provides some additional reliability and performance, but only if the data in the cache is consistent and not stale, which was fine for static documents, but not for dynamic content such as image maps. Extensions were necessary in order to accomodate the new ideas.&lt;/p&gt; &lt;p&gt;In section 5.1.5 (&quot;Uniform Interface&quot;) we get to another stinging rebuke of REST as a generalized distributed application scheme; again, the emphasis is mine:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;The central feature that distinguishes the REST architectural style from other network-based styles is its emphasis on a uniform interface between components (Figure 5-6). By applying the software engineering principle of generality to the component interface, the overall system architecture is simplified and the visibility of interactions is improved. Implementations are decoupled from the services they provide, which encourages independent evolvability. The trade-off, though, is that a uniform interface degrades efficiency, since information is transferred in a standardized form rather than one which is specific to an application&apos;s needs. The REST interface is designed to be efficient for large-grain hypermedia data transfer, optimizing for the common case of the Web, but resulting in an interface that is not optimal for other forms of architectural interaction.  &lt;p&gt;In order to obtain a uniform interface, multiple architectural constraints are needed to guide the behavior of components. &lt;em&gt;REST is defined by four interface constraints&lt;/em&gt;: identification of resources; manipulation of resources through representations; self-descriptive messages; and, &lt;em&gt;hypermedia as the engine of application state&lt;/em&gt;. These constraints will be discussed in Section 5.2.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;In other words, in order to be doing something that Fielding considers RESTful, you have to be using hypermedia (that is to say, hypertext documents of some form) as the core of your application state. It might seem like this implies that you have to be building a Web application in order to be considered building something RESTful, so therefore all Web apps are RESTful by nature, but pay close attention to the wording: hypermedia must be the &lt;em&gt;core&lt;/em&gt; of your application state. The way most Web apps are built today, HTML is clearly not the core of the state, but merely a way to render it. This is the accidental consequence of treating Web applications and desktop client applications as just pale reflections of one another.&lt;/p&gt; &lt;p&gt;The next section, 5.1.6 (&quot;Layered System&quot;) again builds on the notion of stateless-server architecture to provide additional flexibility and power:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;In order to further improve behavior for Internet-scale requirements, we add layered system constraints (Figure 5-7). As described in Section 3.4.2, the layered system style allows an architecture to be composed of hierarchical layers by constraining component behavior such that each component cannot &quot;see&quot; beyond the immediate layer with which they are interacting. By restricting knowledge of the system to a single layer, we place a bound on the overall system complexity and promote substrate independence. Layers can be used to encapsulate legacy services and to protect new services from legacy clients, simplifying components by moving infrequently used functionality to a shared intermediary. Intermediaries can also be used to improve system scalability by enabling load balancing of services across multiple networks and processors.  &lt;p&gt;The primary disadvantage of layered systems is that they add overhead and latency to the processing of data, reducing user-perceived performance [32].&lt;em&gt; For a network-based system that supports cache constraints, this can be offset by the benefits of shared caching at intermediaries.&lt;/em&gt; Placing shared caches at the boundaries of an organizational domain can result in significant performance benefits [136]. Such layers also allow security policies to be enforced on data crossing the organizational boundary, as is required by firewalls [79].  &lt;p&gt;The combination of layered system and uniform interface constraints induces architectural properties similar to those of the uniform pipe-and-filter style (Section 3.2.2). Although REST interaction is two-way, the large-grain data flows of hypermedia interaction can each be processed like a data-flow network, with filter components selectively applied to the data stream in order to transform the content as it passes [26]. &lt;em&gt;Within REST, intermediary components can actively transform the content of messages because the messages are self-descriptive and their semantics are visible to intermediaries.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The potential of layered systems (itself not something that people building RESTful approaches seem to think much about) is only realized if the entirety of the state being transferred is self-descriptive and visible to the intermediaries--in other words, intermediaries can only be helpful and/or non-performance-inhibitive if they have free reign to make decisions based on the state they see being transferred. If something isn&apos;t present in the state being transferred, usually because there is server-side state being maintained, then they have to be concerned about silently changing the semantics of what is happening in the interaction, and intermediaries--and layers as a whole--become a liability. (Which is probably why so few systems seem to do it.)&lt;/p&gt; &lt;p&gt;And if the notion of visible, transported state is not yet made clear in his dissertation, Fielding dissects the discussion even further in section 5.2.1, &quot;Data Elements&quot;. It&apos;s too long to reprint here in its entirety, and frankly, reading the whole thing is necessary to see the point of hypermedia and its place in the whole system. (The same could be said of the entire chapter, in fact.) But it&apos;s pretty clear, once you read the dissertation, that hypermedia/hypertext is a core, critical piece to the whole REST construction. Clients are expected, in a RESTful system, to have &lt;em&gt;no&lt;/em&gt; preconceived notions of structure or relationship between resources, and discover all of that through the state of the hypertext documents that are sent back to them. In the HTML case, that discovery occurs inside the human brain; in the SOA/services case, that discovery is much harder to define and describe. RDF and Semantic Web ideas may be of some help here, but JSON can&apos;t, and simple XML can&apos;t, unless the client has some preconceived notion of what the XML structure looks like, which violates Fielding&apos;s rules:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience (i.e., expected to be understood by any client that might use the API). From that point on, all application state transitions must be driven by client selection of server-provided choices that are present in the received representations or implied by the user’s manipulation of those representations. The transitions may be determined (or limited by) the client’s knowledge of media types and resource communication mechanisms, both of which may be improved on-the-fly (e.g., code-on-demand). [Failure here implies that out-of-band information is driving interaction instead of hypertext.]&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;An interesting &quot;fuzzy gray area&quot; here is whether or not the client&apos;s knowledge of a variant or schematic structure of XML could be considered to be a &quot;standardized media type&quot;, but I&apos;m willing to bet that Fielding will argue against it on the grounds that your application&apos;s XML schema is not &quot;standardized&quot; (unless, of course, it is, through a national/international/industry standardization effort).&lt;/p&gt; &lt;p&gt;But in case you&apos;d missed it, let me summarize the past twenty or so paragraphs: &lt;em&gt;hypermedia is a core requirement to being RESTful.&lt;/em&gt; If you ain&apos;t slinging all of your application state back and forth in hypertext, you ain&apos;t REST. Period. Fielding said it, he defined it, and that settles it.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Before the hate mail comes a-flyin&apos;, let me reiterate one vitally important point: &lt;em&gt;if you&apos;re not doing REST, it doesn&apos;t mean that your API sucks.&lt;/em&gt; Fielding may have his definition of what REST is, and the idealist in me wants to remain true to his definitions of it (after all, if we can&apos;t agree on a common set of definitions, a common lexicon, then we can&apos;t really make much progress as an industry), but...&lt;/p&gt; &lt;p&gt;... the pragmatist in me keeps saying, &quot;so what&quot;?&lt;/p&gt; &lt;p&gt;Look, at the end of the day, if your system wants to misuse HTTP, abuse HTML, and carnally violate the principles of loose coupling and resource representation that underlie REST, who cares? Do you get special bonus points from the Apache Foundation if you use HTTP in the way Fielding intended? Will Microsoft and Oracle and Sun and IBM offer you discounts on your next software purchases if you create a REST-faithful system? Will the partisan politics in Washington, or the tribal conflicts in the Middle East, or even the widely-misnamed &quot;REST-vs-SOAP&quot; debates come to an end if you only figure out a way to make hypermedia the core engine of your application state?&lt;/p&gt; &lt;p&gt;Yeah, I didn&apos;t think so, either.&lt;/p&gt; &lt;p&gt;Point is, REST is &lt;em&gt;just&lt;/em&gt; an architectural style. It is nothing more than another entry alongside such things as client-server, &lt;em&gt;n&lt;/em&gt;-tier, distributed objects, service-oriented, and embedded systems. REST is just a tool for thinking about how to build an application, and it&apos;s high time we kick it off the pedastal on which we&apos;ve placed it and let it come back down to earth with the rest of us mortals. HTTP is useful, but not sufficient, so solve our problems. REST is as well.&lt;/p&gt; &lt;p&gt;And at the end of the day, when we put one tool from our tool belt &quot;above all others&quot;, we end up building some truly horrendous crap.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Apparently I&apos;m #25...</title>
      <link>http://blogs.newardassociates.com/blog/2008/apparently-im-25-on-the-top-100-blogs-for-development-managers.html</link>
      <pubDate>Mon, 15 Sep 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/apparently-im-25-on-the-top-100-blogs-for-development-managers.html</guid>
      	<description>
	&lt;p&gt;... on the Top 100 Blogs for Development Managers.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;The full list is &lt;a href=&quot;http://www.noop.nl/2008/09/top-100-blogs-for-development-managers-q3-2008.html&quot;&gt;here&lt;/a&gt;. It&apos;s a pretty prestigious group--and I&apos;m totally floored that I&apos;m there next to some pretty big names.&lt;/p&gt; &lt;p&gt;In homage to Ms. Sally Fields, of so many years ago... &quot;You like me, you really like me&quot;. Having somebody come up to me at a conference and tell me how much they like my blog is second on my list of &quot;fun things to happen to me at a conference&quot;, right behind having somebody come up to me at a conference and tell me how much they like my blog, except for that one entry, where I said something &lt;em&gt;totally&lt;/em&gt; ridiculous (and here&apos;s why) ....&lt;/p&gt; &lt;p&gt;What I find most fascinating about the list was the means by which it was constructed--the various calculations behind page rank, technorati rating, and so on. Very cool stuff.&lt;/p&gt; &lt;p&gt;Perhaps it&apos;s trite to say it, but it&apos;s still true: readers are what make writing blogs worthwhile. Thanks to all of you.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Never-Ending Debate: Specialist vs Generalist</title>
      <link>http://blogs.newardassociates.com/blog/2008/the-never-ending-debate-of-specialist-v-generalist.html</link>
      <pubDate>Thu, 14 Aug 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/the-never-ending-debate-of-specialist-v-generalist.html</guid>
      	<description>
	&lt;p&gt;Another DZone newsletter crosses my Inbox, and again I feel compelled to comment. Not so much in the uber-aggressive style of my previous attempt, since I find myself more on the fence on this one, but because I think it&apos;s a worthwhile debate and worth calling out.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;The article in question is &quot;5 Reasons Why You Don&apos;t Want A Jack-of-all-Trades Developer&quot;, by Rebecca Murphey. In it, she talks about the all-too-common want-ad description that appears on job sites and mailing lists:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;I&apos;ve spent the last couple of weeks trolling Craigslist and have been shocked at the number of ads I&apos;ve found that seem to be looking for an entire engineering team rolled up into a single person. Descriptions like this aren&apos;t at all uncommon:  &lt;blockquote&gt; &lt;p&gt;Candidates must have 5 years experience defining and developing data driven web sites and have solid experience with ASP.NET, HTML, XML, JavaScript, CSS, Flash, SQL, and optimizing graphics for web use. The candidate must also have project management skills and be able to balance multiple, dynamic, and sometimes conflicting priorities. This position is an integral part of executing our web strategy and must have excellent interpersonal and communication skills.&lt;/p&gt;&lt;/blockquote&gt;&lt;/blockquote&gt; &lt;p&gt;Her disdain for this practice is the focus of the rest of the article:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Now I don&apos;t know about you, but if I were building a house, I wouldn&apos;t want an architect doing the work of a carpenter, or the foundation guy doing the work of an electrician. But ads like the one above are suggesting that a single person can actually do all of these things, and the simple fact is that these are fundamentally different skills. The foundation guy may build a solid base, but put him in charge of wiring the house and the whole thing could, well, burn down. When it comes to staffing a web project or product, the principle isn&apos;t all that different -- nor is the consequence.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I&apos;ll admit, when I got to this point in the article, I was fully ready to start the argument right here and now--developers &lt;em&gt;have&lt;/em&gt; to have a well-rounded collection of skills, since anecdotal evidence suggests that trying to go the route of programming specialization (along the lines of medical specialization) isn&apos;t going to work out, particularly given the shortage of programmers in the industry right now to begin with. But she goes on to make an interesting point:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;The thing is, the more you know, the more you find out you don&apos;t know. A year ago I&apos;d have told you I could write PHP/MySQL applications, and do the front-end too; now that I&apos;ve seen what it means to be truly skilled at the back-end side of things, I realize the most accurate thing I can say is that I understand PHP applications and how they relate to my front-end development efforts. To say that I can write them myself is to diminish the good work that truly skilled PHP/MySQL developers are doing, just as I get a little bent when a back-end developer thinks they can do my job.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;She really caught me eye (and interest) with that first statement, because it echoes something Bjarne Stroustrup told me almost 15 years ago, in an email reply sent back to me (in response to my rather audacious cold-contact email inquiry about the costs and benefits of writing a book): &quot;The more you know, the more you know you don&apos;t know&quot;. What I think also caught my eye--and, I admit it, earned respect--was her admission that she maybe isn&apos;t as good at something as she thought she was before. This kind of reflective admission is a good thing (and missing far too much from our industry, IMHO), because it leads not only to better job placements for us as well as the companies that want to hire us, but also because the more honest we can be about our own skills, the more we can focus efforts on learning what needs to be learned in order to grow.&lt;/p&gt; &lt;p&gt;She then turns to her list of 5 reasons, phrased more as a list of suggestions to companies seeking to hire programming talent; my comments are in italics:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;So to all of those companies who are writing ads seeking one magical person to fill all of their needs, I offer a few caveats before you post your next Craigslist ad:  &lt;p&gt;1. If you&apos;re seeking a single person with all of these skills, make sure you have the technical expertise to determine whether a person&apos;s skills match their resume. Outsource a tech interview if you need to. Any developer can tell horror stories about inept predecessors, but when a front-end developer like myself can read PHP and think it&apos;s appalling, that tells me someone didn&apos;t do a very good job of vetting and got stuck with a programmer who couldn&apos;t deliver on his stated skills.  &lt;p&gt;&lt;em&gt;(T: I cannot stress this enough--the technical interview process practiced at most companies is a complete sham and travesty, and usually only succeeds in making sure the company doesn&apos;t hire a serial killer, would-be terrorist, or financially destitute freeway-underpass resident. I seriously think most companies should outsource the technical interview process entirely.)&lt;/em&gt;  &lt;p&gt;2. A single source for all of these skills is a single point of failure on multiple fronts. Think long and hard about what it will mean to your project if the person you hire falls short in some aspect(s), and about the mistakes that will have to be cleaned up when you get around to hiring specialized people. I have spent countless days cleaning up after back-end developers who didn&apos;t understand the nuances and power of CSS, or the difference between a div, a paragraph, a list item, and a span. Really.  &lt;p&gt;&lt;em&gt;(T: I&apos;m not as much concerned about the single point of failure argument here, to be honest. Developers will always have &quot;edges&quot; to what they know, and companies will constantly push developers to that edge for various reasons, most of which seem to be financial--&quot;Why pay two people to do what one person can do?&quot; is a really compelling argument to the CFO, particularly when measured against an unquantifiable, namely the quality of the project.)&lt;/em&gt;  &lt;p&gt;3. Writing efficient SQL is different from efficiently producing web-optimized graphics. Administering a server is different from troubleshooting cross-browser issues. Trust me. All are integral to the performance and growth of your site, and so you&apos;re right to want them all -- just not from the same person. Expecting quality results in every area from the same person goes back to the foundation guy doing the wiring. You&apos;re playing with fire.  &lt;p&gt;&lt;em&gt;(T: True, but let&apos;s be honest about something here. It&apos;s not so much that the company wants to play with fire, or that the company has a manual entitled &quot;Running a Dilbert Company&quot; that says somewhere inside it, &quot;Thou shouldst never hire more than one person to run the IT department&quot;, but that the company is dealing with limited budgets and headcount. If you only have room for one head under the budget, you want the maximum for that one head. And please don&apos;t tell me how wrong that practice of headcount really is--you&apos;re preaching to the choir on that one. The people you want to preach to are the Jack Welches of the world, who apparently aren&apos;t listening to us very much.)&lt;/em&gt;  &lt;p&gt;4. Asking for a laundry list of skills may end up deterring the candidates who will be best able to fill your actual need. Be precise in your ad: about the position&apos;s title and description, about the level of skill you&apos;re expecting in the various areas, about what&apos;s nice to have and what&apos;s imperative. If you&apos;re looking to fill more than one position, write more than one ad; if you don&apos;t know exactly what you want, try harder to figure it out before you click the publish button.  &lt;p&gt;&lt;em&gt;(T: Asking people to think before publishing? Heresy! Truthfully, I don&apos;t think it&apos;s a question of not knowing what they want, it&apos;s more trying to find what they want. I&apos;ve seen how some of these same job ads get generated, and it&apos;s usually because a programmer on the team has left, and they had some degree of skill in all of those areas. What the company wants, then, is somebody who can step into exactly what that individual was doing before they handed in their resignation, but ads like, &quot;Candidate should look at Joe Smith&apos;s resume on Dice.com (http://...) and have exactly that same skill set. Being named Joe Smith a desirable &apos;plus&apos;, since then we won&apos;t have to have the sysadmins create a new login handle for you.&quot; won&apos;t attract much attention. Frankly, what I&apos;ve found most companies want is to just not lose the programmer in the first place.)&lt;/em&gt;  &lt;p&gt;5. If you really do think you want one person to do the task of an entire engineering team, prepare yourself to get someone who is OK at a bunch of things and not particularly good at any of them. Again: the more you know, the more you find out you don&apos;t know. I regularly team with a talented back-end developer who knows better than to try to do my job, and I know better than to try to do his. Anyone who represents themselves as being a master of front-to-back web development may very well have no idea just how much they don&apos;t know, and could end up imperiling your product or project -- front to back -- as a result.  &lt;p&gt;&lt;em&gt;(T: Or be prepared to pay a lot of money for somebody who is an expert at all of those things, or be prepared to spend a lot of time and money growing somebody into that role. Sometimes the exact right thing to do is have one person do it all, but usually it&apos;s cheaper to have a small team work together.)&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;(On a side note, I find it amusing that she seems to consider PHP a back-end skill, but I don&apos;t want to sound harsh doing so--that&apos;s just a matter of perspective, I suppose. (I can just imagine the guffaws from the mainframe guys when I talk about EJB, message-queue and Spring systems being &quot;back-end&quot;, too.) To me, the whole &quot;web&quot; thing is front-end stuff, whether you&apos;re the one generating the HTML from your PHP or servlet/JSP or ASP.NET server-side engine, or you&apos;re the one generating the CSS and graphics images that are sent back to the browser by said server-side engine. If a user sees something I did, it&apos;s probably because something bad happened and they&apos;re looking at a stack trace on the screen.)&lt;/p&gt; &lt;p&gt;The thing I find interesting is that HR hiring practices and job-writing skills haven&apos;t gotten any better in the near-to-two-decades I&apos;ve been in this industry. I can still remember a fresh-faced wet-behind-the-ears Stroustrup-2nd-Edition-toting job candidate named Neward looking at job placement listings and finding much the same kind of laundry list of skills, including those with the impossible number of years of experience. (In 1995, I saw an ad looking for somebody who had &quot;10 years of C++ experience&quot;, and wondering, &quot;Gosh, I guess they&apos;re looking to hire Stroustrup or Lippmann&quot;, since those two are the only people who could possibly have filled that requirement at the time. This was right before reading the ad that was looking for 5 years of Java experience, or the ad below it looking for 15 years of Delphi....)&lt;/p&gt; &lt;p&gt;Given that it doesn&apos;t seem likely that HR departments are going to &quot;get a clue&quot; any time soon, it leaves us with an interesting question: if you&apos;re a developer, and you&apos;re looking at these laundry lists of requirements, how do you respond?&lt;/p&gt; &lt;p&gt;Here&apos;s my own list of things for programmers/developers to consider over the next five to ten years:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;em&gt;These &quot;laundry list&quot; ads are not going away any time soon.&lt;/em&gt; We can rant and rail about the stupidity of HR departments and hiring managers all we want, but the basic fact is, this is the way things are going to work for the forseeable future, it seems. Changing this would require a &quot;sea change&quot; across the industry, and sea change doesn&apos;t happen overnight, or even within the span of a few years. So, to me, the right question to ask isn&apos;t, &quot;How do I change the industry to make it easier for me to find a job I can do?&quot;, but &quot;How do I change what I do when looking for a job to better respond to what the industry is doing?&quot;  &lt;li&gt;&lt;em&gt;Exclusively focusing on a single area of technology is the Kiss of Death.&lt;/em&gt; If all you know is PHP, then your days are numbered. I mean no disrespect to the PHP developers of the world--in fact, were it not too ambiguous to say it, I would rephrase that as &quot;If all you know is &lt;em&gt;X&lt;/em&gt;, your days are numbered.&quot; There is no one technical skill that will be as much in demand in ten years as it is now. Technologies age. Industry evolves. Innovations come along that completely change the game and leave our predictions of a few years ago in the dust. Bill Gates (he of the &quot;640K comment&quot;) has said, and I think he&apos;s spot on with this, &quot;We routinely overestimate where we will be in five years, and vastly underestimate where we will be in ten.&quot; If you put all your eggs in the PHP basket, then when PHP gets phased out in favor of &lt;em&gt;(insert new &quot;hotness&quot; here)&lt;/em&gt;, you&apos;re screwed. Unless, of course, you want to wait until you&apos;re the last man standing, which seems to have paid off well for the few COBOL developers still alive.... but not so much for the Algol, Simula, or RPG folks....  &lt;li&gt;&lt;em&gt;Assuming that you can stop learning is the Kiss of Death.&lt;/em&gt; Look, if you want to stop learning at some point and coast on what you know, be prepared to switch industries. This one, for the forseeable future, is one that&apos;s predicated on radical innovation and constant change. This means we have to accept that everything is in a constant state of flux--you can either rant and rave against it, or roll with it. This doesn&apos;t mean that you don&apos;t have to look back, though--anybody who&apos;s been in this industry for more than 10 years has seen how we keep reinventing the wheel, particularly now that the relationship between Ruby and Smalltalk has been put up on the big stage, so to speak. Do yourself a favor: learn stuff that&apos;s already &quot;done&quot;, too, because it turns out there&apos;s a lot of lessons we can learn from those who came before us. &quot;Those who cannot remember the past are condemned to repeat it&quot; (George Santanyana). Case in point: if you&apos;re trying to get into XML services, spend some time learning CORBA and DCOM, and compare how they do things against WSDL and SOAP. What&apos;s similar? What&apos;s different? Do some Googling and see if you can find comparison articles between the two, and what XML services were supposed to &quot;fix&quot; from the previous two. You don&apos;t have to write a ton of CORBA or DCOM code to see those differences (though writing at least a little CORBA/DCOM code will probably help.) &lt;li&gt;&lt;em&gt;Find a collection of people smarter than you.&lt;/em&gt; Chad Fowler calls this &quot;Being the worst player in any band you&apos;re in&quot; (&lt;em&gt;My Job Went to India (and All I Got Was This Lousy Book)&lt;/em&gt;, Pragmatic Press&lt;em&gt;)&lt;/em&gt;. The more you surround yourself with smart people, the more of these kinds of things (tools, languages, etc) you will pick up merely by osmosis, and find yourself more attractive to those kind of &quot;laundry list&quot; job reqs. If nothing else, it speaks well to you as an employee/consultant if you can say, &quot;I don&apos;t know the answer to that question, but I know people who do, and I can get them to help me&quot;. &lt;li&gt;&lt;em&gt;Learn to be at least self-sufficient in related, complementary technologies.&lt;/em&gt; We see laundry list ads in &quot;clusters&quot;. Case in point: if the company is looking for somebody to work on their website, they&apos;re going to rattle off a list of five or so things they want he/she to know--HTML, CSS, XML, JavaScript and sometimes Flash (or maybe now Silverlight), in addition to whatever server-side technology they&apos;re using (ASP.NET, servlets, PHP, whatever). This is a pretty reasonable request, depending on the depth of each that they want you to know. Here&apos;s the thing: the company does &lt;em&gt;not&lt;/em&gt; want the guy who says he knows ASP.NET (and nothing but ASP.NET), when asked to make a small HTML or CSS change, to turn to them and say, &quot;I&apos;m sorry, that&apos;s not in my job description. I only know ASP.NET. You&apos;ll have to get your HTML guy to make that change.&quot; You should at least be comfortable with the basic syntax of all of the above (again, with possible exception for Flash, which is the odd man out in that job ad that started this piece), so that you can at least make sure the site isn&apos;t going to break when you push your changes live. In the case of the ad above, learn the things that &quot;surround&quot; website development: HTML, CSS, JavaScript, Flash, Java applets, HTTP (!!), TCP/IP, server operating systems, IIS or Apache or Tomcat or some other server engine (including the necessary admin skills to get them installed and up and running), XML (since it&apos;s so often used for configuration), and so on. These are all &quot;complementary&quot; skills to being an ASP.NET developer (or a servlet/JSP developer). If you&apos;re a C# or Java programmer, learn different programming languages, a la F# (.NET) or Scala (Java), IronRuby (.NET) or JRuby (Java), and so on. If you&apos;re a Ruby developer, learn either a JVM language or a CLR language, so you can &quot;plug in&quot; more easily to the large corporate enterprise when that call comes.  &lt;li&gt;&lt;em&gt;Learn to &quot;read&quot; the ad at a higher level.&lt;/em&gt; It&apos;s often possible to &quot;read between the lines&quot; and get an idea of what they&apos;re looking for, even before talking to anybody at the company about the job. For example, I read the ad that started this piece, and the internal dialogue that went on went something like this:  &lt;blockquote&gt;Candidates must have 5 years experience &lt;em&gt;(No entry-level developers wanted, they want somebody who can get stuff done without having their hand held through the process) &lt;/em&gt;defining and developing data driven &lt;em&gt;(they want somebody who&apos;s comfortable with SQL and databases) &lt;/em&gt;web sites &lt;em&gt;(wait for it, the &quot;web cluster&quot; list is coming) &lt;/em&gt;and have solid experience with ASP.NET &lt;em&gt;(OK, they&apos;re at least marginally a Microsoft shop, that means they probably also want some Windows Server and IIS experience)&lt;/em&gt;, HTML, XML, JavaScript, CSS &lt;em&gt;(the &quot;web cluster&quot;, knew that was coming)&lt;/em&gt;, Flash &lt;em&gt;(OK, I wonder if this is because they&apos;re building rich internet/intranet apps already, or just flirting with the idea?)&lt;/em&gt;, SQL &lt;em&gt;(knew that was coming)&lt;/em&gt;, and optimizing graphics for web use &lt;em&gt;(OK, this is another wrinkle--this smells of &quot;we don&apos;t want our graphics-heavy website to suck&quot;)&lt;/em&gt;. The candidate must also have project management skills &lt;em&gt;(in other words, &quot;You&apos;re on your own, sucka!&quot;--you&apos;re not part of a project team) &lt;/em&gt;and be able to balance multiple, dynamic, and sometimes conflicting priorities &lt;em&gt;(in other words, &quot;You&apos;re own your own trying to balance between the CTO&apos;s demands and the CEO&apos;s demands, sucka!&quot;, since you&apos;re not part of a project team; this also probably means you&apos;re not moving into an existing project, but doing more maintenance work on an existing site)&lt;/em&gt;. This position is an integral part of executing our web strategy &lt;em&gt;(in other words, this project has public visibility and you can&apos;t let stupid errors show up on the website and make us all look bad) &lt;/em&gt;and must have excellent interpersonal and communication skills &lt;em&gt;(what job &lt;/em&gt;doesn&apos;t&lt;em&gt; need excellent interpersonal and communication skills?)&lt;/em&gt;.&lt;/blockquote&gt;See what I mean? They want an ASP.NET dev. My guess is that they&apos;re thinking a lot about Silverlight, since Silverlight&apos;s closest competitor is Flash, and so theoretically an ASP.NET-and-Flash dev would know how to use Silverlight well. Thus, I&apos;m guessing that the HTML, CSS, and JavaScript don&apos;t need to be &quot;Adept&quot; level, nor even &quot;Master&quot; level, but &quot;Journeyman&quot; is probably necessary, and maybe you could get away with &quot;Apprentice&quot; at those levels, if you&apos;re working as part of a team. The SQL part will probably have to be &quot;Journeyman&quot; level, the XML could probably be just &quot;Apprentice&quot;, since I&apos;m guessing it&apos;s only necessary for the web.config files to control the ASP.NET configuration, and the &quot;optimizing web graphics&quot;, push-come-to-shove, could probably be forgiven if you&apos;ve had some experience at doing some performance tuning of a website.  &lt;li&gt;&lt;em&gt;Be insightful.&lt;/em&gt; I know, every interview book ever written says you should &quot;ask questions&quot;, but what they&apos;re really getting at is &quot;Demonstrate that you&apos;ve thought about this company and this position&quot;. Demonstrating insight about the position and the company and technology as a whole is a good way to prove that you&apos;re a neck above the other candidates, and will help keep the job once you&apos;ve got it. &lt;li&gt;&lt;em&gt;Be honest about what you know.&lt;/em&gt; Let&apos;s be honest--we&apos;ve all met developers who claimed they were &quot;experts&quot; in a particular tool or technology, and then painfully demonstrated how far from &quot;expert&quot; status they really were. Be honest about yourself: claim your skills on a simple four-point scale. &quot;Apprentice&quot; means &quot;I read a book on it&quot; or &quot;I&apos;ve looked at it&quot;, but &quot;there&apos;s no way I could do it on my own without some serious help, and ideally with a Master looking over my shoulder&quot;. &quot;Journeyman&quot; means &quot;I&apos;m competent at it, I know the tools/technology&quot;; or, put another way, &quot;I can do 80% of what anybody can ask me to do, and I know how to find the other 20% when those situations arise&quot;. &quot;Master&quot; means &quot;I not only claim that I can do what you ask me to do with it, I can optimize systems built with it, I can make it do things others wouldn&apos;t attempt, and I can help others learn it better&quot;. Masters are routinely paired with Apprentices as mentors or coaches, and should expect to have this as a major part of their responsibilities. (Ideally, anybody claiming &quot;architect&quot; in their title should be a Master at one or two of the core tools/technologies used in their system; or, put another way, architects should be &lt;em&gt;very&lt;/em&gt; dubious about architecting with something they can&apos;t reasonably claim at least Journeyman status in.) &quot;Adept&quot;, shortly put, means you are not only fully capable of pulling off anything a Master can do, but you routinely take the tool/technology way beyond what anybody else thinks possible, or you know the depth of the system so well that you can fix bugs just by thinking about them. With your eyes closed. While drinking a glass of water. Seriously, Adept status is not something to claim lightly--not only had you better know the guys who created the thing personally, but you should have offered up suggestions on how to make it better and had one or more of them accepted. &lt;li&gt;&lt;em&gt;Demonstrate that you have relevant skills beyond what they asked for.&lt;/em&gt; Look at the ad in question: they want an ASP.NET dev, so any familiarity with IIS, Windows Server, SQL Server, MSMQ, COM/DCOM/COM+, WCF/Web services, SharePoint, the CLR, IronPython, or IronRuby should be listed prominently on your resume, and brought up at least twice during your interview. These are (again) complementary technologies, and even if the company doesn&apos;t have a need for those things right now, it&apos;s probably because Joe didn&apos;t know any of those, and so they couldn&apos;t use them without sending Joe to a training class. If you bring it up during the interview, it can also show some insight on your part: &quot;So, any questions for us?&quot; &quot;Yes, are you guys using Windows Server 2008, or 2003, for your back end?&quot; &quot;Um, we&apos;re using 2003, why do you ask?&quot; &quot;Oh, well, when I was working as an ASP.NET dev for my previous company, we moved up to 2008 because it had the Froobinger Enhancement, which let us...., and I was just curious if you guys had a similar need.&quot; Or something like that. Again, be entirely honest about what you know--if you helped the server upgrade by just putting the CDs into the drive and punching the power button, then say as much.  &lt;li&gt;&lt;em&gt;Demonstrate that you can talk to project stakeholders and users.&lt;/em&gt; Communication is huge. The era of the one-developer team is long since over--you have to be able to meet with project champions, users, other developers, and so on. If you can&apos;t do that without somebody being offended at your lack of tact and subtlety (or your lack of personal hygiene), then don&apos;t expect to get hired too often. &lt;li&gt;&lt;em&gt;Demonstrate that you understand the company, its business model, and what would help it move forward.&lt;/em&gt; Developers who actually understand business are surprisingly and unfortunately rare. Be one of the rare ones, and you&apos;ll find companies highly reluctant to let you go.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Is this an exhaustive list? Hardly. Is this list guaranteed to keep you employed forever? Nope. But this seems to be working for a lot of the people I run into at conferences and client consulting gigs, so I humbly submit it for your consideration.&lt;/p&gt; &lt;p&gt;But in no way do I consider this conversation completely over, either--feel free to post your own suggestions, or tell me why I&apos;m full of crap on any (or all) of these. :-)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Java Object.hashCode implementation</title>
      <link>http://blogs.newardassociates.com/blog/2008/objecthashcode-implementation.html</link>
      <pubDate>Thu, 7 Aug 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/objecthashcode-implementation.html</guid>
      	<description>
	&lt;p&gt;The implementation of Object.equals is, it turns out, just &quot;return this == obj&quot;, but the implementation of Object.hashCode is far more complicated.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Taken straight from the latest hg-pulled OpenJDK sources, Object.hashCode is a native method registered from Object.c that calls into a Hotspot-exported function, JVM_IHashCode(), from hotspot\src\share\vm\prims\jvm.cpp:&lt;/p&gt; &lt;div id=&quot;codeSnippetWrapper&quot; style=&quot;border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &apos;Courier New&apos;, courier, monospace; background-color: #f4f4f4&quot;&gt;&lt;pre id=&quot;codeSnippet&quot; style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &apos;Courier New&apos;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;JVM_ENTRY(jint, JVM_IHashCode(JNIEnv* env, jobject handle))&lt;br&gt;  JVMWrapper(&lt;span style=&quot;color: #006080&quot;&gt;&quot;JVM_IHashCode&quot;&lt;/span&gt;);&lt;br&gt;  &lt;span style=&quot;color: #008000&quot;&gt;// as implemented in the classic virtual machine; return 0 if object is NULL&lt;/span&gt;&lt;br&gt;  &lt;span style=&quot;color: #0000ff&quot;&gt;return&lt;/span&gt; handle == NULL ? 0 : ObjectSynchronizer::FastHashCode (THREAD, JNIHandles::resolve_non_null(handle)) ;&lt;br&gt;JVM_END&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;
&lt;p&gt;which in turn calls ObjectSynchronizer::FastHashCode, defined in hotspot\src\share\vm\runtime\synchronizer.cpp as:&lt;/p&gt;
&lt;div id=&quot;codeSnippetWrapper&quot; style=&quot;border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &apos;Courier New&apos;, courier, monospace; background-color: #f4f4f4&quot;&gt;&lt;pre id=&quot;codeSnippet&quot; style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &apos;Courier New&apos;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;intptr_t ObjectSynchronizer::FastHashCode (Thread * Self, oop obj) {&lt;br&gt;  &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (UseBiasedLocking) {&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// NOTE: many places throughout the JVM do not expect a safepoint&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// to be taken here, in particular most operations on perm gen&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// objects. However, we only ever bias Java instances and all of&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// the call sites of identity_hash that might revoke biases have&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// been checked to make sure they can handle a safepoint. The&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// added check of the bias pattern is to avoid useless calls to&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// thread-local storage.&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (obj-&amp;gt;mark()-&amp;gt;has_bias_pattern()) {&lt;br&gt;      &lt;span style=&quot;color: #008000&quot;&gt;// Box and unbox the raw reference just in case we cause a STW safepoint.&lt;/span&gt;&lt;br&gt;      Handle hobj (Self, obj) ;&lt;br&gt;      &lt;span style=&quot;color: #008000&quot;&gt;// Relaxing assertion for bug 6320749.&lt;/span&gt;&lt;br&gt;      assert (Universe::verify_in_progress() ||&lt;br&gt;              !SafepointSynchronize::is_at_safepoint(),&lt;br&gt;             &lt;span style=&quot;color: #006080&quot;&gt;&quot;biases should not be seen by VM thread here&quot;&lt;/span&gt;);&lt;br&gt;      BiasedLocking::revoke_and_rebias(hobj, false, JavaThread::current());&lt;br&gt;      obj = hobj() ;&lt;br&gt;      assert(!obj-&amp;gt;mark()-&amp;gt;has_bias_pattern(), &lt;span style=&quot;color: #006080&quot;&gt;&quot;biases should be revoked by now&quot;&lt;/span&gt;);&lt;br&gt;    }&lt;br&gt;  }&lt;br&gt;&lt;br&gt;  &lt;span style=&quot;color: #008000&quot;&gt;// hashCode() is a heap mutator ...&lt;/span&gt;&lt;br&gt;  &lt;span style=&quot;color: #008000&quot;&gt;// Relaxing assertion for bug 6320749.&lt;/span&gt;&lt;br&gt;  assert (Universe::verify_in_progress() ||&lt;br&gt;          !SafepointSynchronize::is_at_safepoint(), &lt;span style=&quot;color: #006080&quot;&gt;&quot;invariant&quot;&lt;/span&gt;) ;&lt;br&gt;  assert (Universe::verify_in_progress() ||&lt;br&gt;          Self-&amp;gt;is_Java_thread() , &lt;span style=&quot;color: #006080&quot;&gt;&quot;invariant&quot;&lt;/span&gt;) ;&lt;br&gt;  assert (Universe::verify_in_progress() ||&lt;br&gt;         ((JavaThread *)Self)-&amp;gt;thread_state() != _thread_blocked, &lt;span style=&quot;color: #006080&quot;&gt;&quot;invariant&quot;&lt;/span&gt;) ;&lt;br&gt;&lt;br&gt;  ObjectMonitor* monitor = NULL;&lt;br&gt;  markOop temp, test;&lt;br&gt;  intptr_t hash;&lt;br&gt;  markOop mark = ReadStableMark (obj);&lt;br&gt;&lt;br&gt;  &lt;span style=&quot;color: #008000&quot;&gt;// object should remain ineligible for biased locking&lt;/span&gt;&lt;br&gt;  assert (!mark-&amp;gt;has_bias_pattern(), &lt;span style=&quot;color: #006080&quot;&gt;&quot;invariant&quot;&lt;/span&gt;) ;&lt;br&gt;&lt;br&gt;  &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (mark-&amp;gt;is_neutral()) {&lt;br&gt;    hash = mark-&amp;gt;hash();              &lt;span style=&quot;color: #008000&quot;&gt;// this is a normal header&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (hash) {                       &lt;span style=&quot;color: #008000&quot;&gt;// if it has hash, just return it&lt;/span&gt;&lt;br&gt;      &lt;span style=&quot;color: #0000ff&quot;&gt;return&lt;/span&gt; hash;&lt;br&gt;    }&lt;br&gt;    hash = get_next_hash(Self, obj);  &lt;span style=&quot;color: #008000&quot;&gt;// allocate a new hash code&lt;/span&gt;&lt;br&gt;    temp = mark-&amp;gt;copy_set_hash(hash); &lt;span style=&quot;color: #008000&quot;&gt;// merge the hash code into header&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// use (machine word version) atomic operation to install the hash&lt;/span&gt;&lt;br&gt;    test = (markOop) Atomic::cmpxchg_ptr(temp, obj-&amp;gt;mark_addr(), mark);&lt;br&gt;    &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (test == mark) {&lt;br&gt;      &lt;span style=&quot;color: #0000ff&quot;&gt;return&lt;/span&gt; hash;&lt;br&gt;    }&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// If atomic operation failed, we must inflate the header&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// into heavy weight monitor. We could add more code here&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// for fast path, but it does not worth the complexity.&lt;/span&gt;&lt;br&gt;  } &lt;span style=&quot;color: #0000ff&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (mark-&amp;gt;has_monitor()) {&lt;br&gt;    monitor = mark-&amp;gt;monitor();&lt;br&gt;    temp = monitor-&amp;gt;header();&lt;br&gt;    assert (temp-&amp;gt;is_neutral(), &lt;span style=&quot;color: #006080&quot;&gt;&quot;invariant&quot;&lt;/span&gt;) ;&lt;br&gt;    hash = temp-&amp;gt;hash();&lt;br&gt;    &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (hash) {&lt;br&gt;      &lt;span style=&quot;color: #0000ff&quot;&gt;return&lt;/span&gt; hash;&lt;br&gt;    }&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// Skip to the following code to reduce code size&lt;/span&gt;&lt;br&gt;  } &lt;span style=&quot;color: #0000ff&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (Self-&amp;gt;is_lock_owned((address)mark-&amp;gt;locker())) {&lt;br&gt;    temp = mark-&amp;gt;displaced_mark_helper(); &lt;span style=&quot;color: #008000&quot;&gt;// this is a lightweight monitor owned&lt;/span&gt;&lt;br&gt;    assert (temp-&amp;gt;is_neutral(), &lt;span style=&quot;color: #006080&quot;&gt;&quot;invariant&quot;&lt;/span&gt;) ;&lt;br&gt;    hash = temp-&amp;gt;hash();              &lt;span style=&quot;color: #008000&quot;&gt;// by current thread, check if the displaced&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (hash) {                       &lt;span style=&quot;color: #008000&quot;&gt;// header contains hash code&lt;/span&gt;&lt;br&gt;      &lt;span style=&quot;color: #0000ff&quot;&gt;return&lt;/span&gt; hash;&lt;br&gt;    }&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// WARNING:&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;//   The displaced header is strictly immutable.&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// It can NOT be changed in ANY cases. So we have&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// to inflate the header into heavyweight monitor&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// even the current thread owns the lock. The reason&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// is the BasicLock (stack slot) will be asynchronously&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// read by other threads during the inflate() function.&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// Any change to stack may not propagate to other threads&lt;/span&gt;&lt;br&gt;    &lt;span style=&quot;color: #008000&quot;&gt;// correctly.&lt;/span&gt;&lt;br&gt;  }&lt;br&gt;&lt;br&gt;  &lt;span style=&quot;color: #008000&quot;&gt;// Inflate the monitor to set hash code&lt;/span&gt;&lt;br&gt;  monitor = ObjectSynchronizer::inflate(Self, obj);&lt;br&gt;  &lt;span style=&quot;color: #008000&quot;&gt;// Load displaced header and check it has hash code&lt;/span&gt;&lt;br&gt;  mark = monitor-&amp;gt;header();&lt;br&gt;  assert (mark-&amp;gt;is_neutral(), &lt;span style=&quot;color: #006080&quot;&gt;&quot;invariant&quot;&lt;/span&gt;) ;&lt;br&gt;  hash = mark-&amp;gt;hash();&lt;br&gt;  &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (hash == 0) {&lt;br&gt;    hash = get_next_hash(Self, obj);&lt;br&gt;    temp = mark-&amp;gt;copy_set_hash(hash); &lt;span style=&quot;color: #008000&quot;&gt;// merge hash code into header&lt;/span&gt;&lt;br&gt;    assert (temp-&amp;gt;is_neutral(), &lt;span style=&quot;color: #006080&quot;&gt;&quot;invariant&quot;&lt;/span&gt;) ;&lt;br&gt;    test = (markOop) Atomic::cmpxchg_ptr(temp, monitor, mark);&lt;br&gt;    &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (test != mark) {&lt;br&gt;      &lt;span style=&quot;color: #008000&quot;&gt;// The only update to the header in the monitor (outside GC)&lt;/span&gt;&lt;br&gt;      &lt;span style=&quot;color: #008000&quot;&gt;// is install the hash code. If someone add new usage of&lt;/span&gt;&lt;br&gt;      &lt;span style=&quot;color: #008000&quot;&gt;// displaced header, please update this code&lt;/span&gt;&lt;br&gt;      hash = test-&amp;gt;hash();&lt;br&gt;      assert (test-&amp;gt;is_neutral(), &lt;span style=&quot;color: #006080&quot;&gt;&quot;invariant&quot;&lt;/span&gt;) ;&lt;br&gt;      assert (hash != 0, &lt;span style=&quot;color: #006080&quot;&gt;&quot;Trivial unexpected object/monitor header usage.&quot;&lt;/span&gt;);&lt;br&gt;    }&lt;br&gt;  }&lt;br&gt;  &lt;span style=&quot;color: #008000&quot;&gt;// We finally get the hash&lt;/span&gt;&lt;br&gt;  &lt;span style=&quot;color: #0000ff&quot;&gt;return&lt;/span&gt; hash;&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;
&lt;p&gt;Hope this answers all the debates. :-)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Editor&apos;s note: Yes, I know it&apos;s a long quotation of code completely out of context; my goal here is simply to suggest that the hashCode() implementation is &lt;/em&gt;not&lt;em&gt; just a integerification of the object&apos;s address in memory, as was suggested in other discussions. For whatever it&apos;s worth, the get_next_hash() implementation that&apos;s referenced in the FastHashCode() method looks like:&lt;/em&gt;&lt;/p&gt;
&lt;div id=&quot;codeSnippetWrapper&quot; style=&quot;border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &apos;Courier New&apos;, courier, monospace; background-color: #f4f4f4&quot;&gt;&lt;pre id=&quot;codeSnippet&quot; style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &apos;Courier New&apos;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #008000&quot;&gt;// hashCode() generation :&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #008000&quot;&gt;//&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #008000&quot;&gt;// Possibilities:&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #008000&quot;&gt;// * MD5Digest of {obj,stwRandom}&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #008000&quot;&gt;// * CRC32 of {obj,stwRandom} or any linear-feedback shift register function.&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #008000&quot;&gt;// * A DES- or AES-style SBox[] mechanism&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #008000&quot;&gt;// * One of the Phi-based schemes, such as:&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #008000&quot;&gt;//   2654435761 = 2^32 * Phi (golden ratio)&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #008000&quot;&gt;//   HashCodeValue = ((uintptr_t(obj) &amp;gt;&amp;gt; 3) * 2654435761) ^ GVars.stwRandom ;&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #008000&quot;&gt;// * A variation of Marsaglia&apos;s shift-xor RNG scheme.&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #008000&quot;&gt;// * (obj ^ stwRandom) is appealing, but can result&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #008000&quot;&gt;//   in undesirable regularity in the hashCode values of adjacent objects&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #008000&quot;&gt;//   (objects allocated back-to-back, in particular).  This could potentially&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #008000&quot;&gt;//   result in hashtable collisions and reduced hashtable efficiency.&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #008000&quot;&gt;//   There are simple ways to &quot;diffuse&quot; the middle address bits over the&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #008000&quot;&gt;//   generated hashCode values:&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #008000&quot;&gt;//&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;inline&lt;/span&gt; intptr_t get_next_hash(Thread * Self, oop obj) {&lt;br&gt;  intptr_t value = 0 ;&lt;br&gt;  &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (hashCode == 0) {&lt;br&gt;     &lt;span style=&quot;color: #008000&quot;&gt;// This form uses an unguarded global Park-Miller RNG,&lt;/span&gt;&lt;br&gt;     &lt;span style=&quot;color: #008000&quot;&gt;// so it&apos;s possible for two threads to race and generate the same RNG.&lt;/span&gt;&lt;br&gt;     &lt;span style=&quot;color: #008000&quot;&gt;// On MP system we&apos;ll have lots of RW access to a global, so the&lt;/span&gt;&lt;br&gt;     &lt;span style=&quot;color: #008000&quot;&gt;// mechanism induces lots of coherency traffic.&lt;/span&gt;&lt;br&gt;     value = os::random() ;&lt;br&gt;  } &lt;span style=&quot;color: #0000ff&quot;&gt;else&lt;/span&gt;&lt;br&gt;  &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (hashCode == 1) {&lt;br&gt;     &lt;span style=&quot;color: #008000&quot;&gt;// This variation has the property of being stable (idempotent)&lt;/span&gt;&lt;br&gt;     &lt;span style=&quot;color: #008000&quot;&gt;// between STW operations.  This can be useful in some of the 1-0&lt;/span&gt;&lt;br&gt;     &lt;span style=&quot;color: #008000&quot;&gt;// synchronization schemes.&lt;/span&gt;&lt;br&gt;     intptr_t addrBits = intptr_t(obj) &amp;gt;&amp;gt; 3 ;&lt;br&gt;     value = addrBits ^ (addrBits &amp;gt;&amp;gt; 5) ^ GVars.stwRandom ;&lt;br&gt;  } &lt;span style=&quot;color: #0000ff&quot;&gt;else&lt;/span&gt;&lt;br&gt;  &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (hashCode == 2) {&lt;br&gt;     value = 1 ;            &lt;span style=&quot;color: #008000&quot;&gt;// for sensitivity testing&lt;/span&gt;&lt;br&gt;  } &lt;span style=&quot;color: #0000ff&quot;&gt;else&lt;/span&gt;&lt;br&gt;  &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (hashCode == 3) {&lt;br&gt;     value = ++GVars.hcSequence ;&lt;br&gt;  } &lt;span style=&quot;color: #0000ff&quot;&gt;else&lt;/span&gt;&lt;br&gt;  &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (hashCode == 4) {&lt;br&gt;     value = intptr_t(obj) ;&lt;br&gt;  } &lt;span style=&quot;color: #0000ff&quot;&gt;else&lt;/span&gt; {&lt;br&gt;     &lt;span style=&quot;color: #008000&quot;&gt;// Marsaglia&apos;s xor-shift scheme with thread-specific state&lt;/span&gt;&lt;br&gt;     &lt;span style=&quot;color: #008000&quot;&gt;// This is probably the best overall implementation -- we&apos;ll&lt;/span&gt;&lt;br&gt;     &lt;span style=&quot;color: #008000&quot;&gt;// likely make this the default in future releases.&lt;/span&gt;&lt;br&gt;     &lt;span style=&quot;color: #0000ff&quot;&gt;unsigned&lt;/span&gt; t = Self-&amp;gt;_hashStateX ;&lt;br&gt;     t ^= (t &amp;lt;&amp;lt; 11) ;&lt;br&gt;     Self-&amp;gt;_hashStateX = Self-&amp;gt;_hashStateY ;&lt;br&gt;     Self-&amp;gt;_hashStateY = Self-&amp;gt;_hashStateZ ;&lt;br&gt;     Self-&amp;gt;_hashStateZ = Self-&amp;gt;_hashStateW ;&lt;br&gt;     &lt;span style=&quot;color: #0000ff&quot;&gt;unsigned&lt;/span&gt; v = Self-&amp;gt;_hashStateW ;&lt;br&gt;     v = (v ^ (v &amp;gt;&amp;gt; 19)) ^ (t ^ (t &amp;gt;&amp;gt; 8)) ;&lt;br&gt;     Self-&amp;gt;_hashStateW = v ;&lt;br&gt;     value = v ;&lt;br&gt;  }&lt;br&gt;&lt;br&gt;  value &amp;amp;= markOopDesc::hash_mask;&lt;br&gt;  &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (value == 0) value = 0xBAD ;&lt;br&gt;  assert (value != markOopDesc::no_hash, &lt;span style=&quot;color: #006080&quot;&gt;&quot;invariant&quot;&lt;/span&gt;) ;&lt;br&gt;  TEVENT (hashCode: GENERATE) ;&lt;br&gt;  &lt;span style=&quot;color: #0000ff&quot;&gt;return&lt;/span&gt; value;&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Thus (hopefully) putting the idea that it might be allocating a hash based on the object&apos;s identity completely to rest.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;For the record, this is all from the OpenJDK source base--naturally, it&apos;s possible that earlier VM implementations did something entirely different.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>More Thoughts on Architects and Architecture</title>
      <link>http://blogs.newardassociates.com/blog/2008/more-thoughts-on-architects-and-architecture.html</link>
      <pubDate>Tue, 29 Jul 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/more-thoughts-on-architects-and-architecture.html</guid>
      	<description>
	&lt;p&gt;Speaking of things crossing my Inbox, Shane Paterson sent me this email:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Hi Ted,&lt;/p&gt; &lt;p&gt;How’s things in the USA?&lt;/p&gt; &lt;p&gt;I just wrote the following little &lt;a href=&quot;http://www.javaworks.co.nz/blojsom/blog/default/2008/&quot;&gt;blog entry&lt;/a&gt; I wanted to share with you, which I thought you may find interesting.&lt;/p&gt;&lt;/blockquote&gt;
&lt;!--more--&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;I used to work with a Naval Architect a few years back. On day we were discussing where the name &quot;Naval Architect&quot; came from. He explained that &quot;Naval Architecture&quot; is really &quot;Naval Engineering&quot; or &quot;Ship Engineering&quot;. The word Engineering came into use AFTER the industrial revolution, however ship design existed hundreds of years before. At that time, people needed a name for ship designers, so they reasoned that Architects designed buildings, therefore ship designers must be a kind of Architect too - hence the name &quot;Naval Architect&quot;.&lt;/p&gt;
&lt;p&gt;Clearly IT didn&apos;t exist before the industrial revolution, and IT Architects don&apos;t design buildings, so the question begs to be asked &quot;How did we end up with the word Architecture being used for a role in IT&quot;. It seems to me to be a rather vague and grandiose name for a role which is probably better described by the use of the word &quot;Engineer&quot;. &lt;/p&gt;
&lt;p&gt;Perhaps instead of the names &quot;Solution Architect&quot; and &quot;Enterprise Architect&quot; we should actually be using the names &quot;IT Solution Engineer&quot;, &quot;IT Enterprise Engineer&quot;? &lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;I&apos;ve heard this idea put forward before, and I have to say, I&apos;m not overly fond of it, because I believe that what we do as architects is fundamentally different from what a civil engineer does when he engages in the architect&apos;s role.&lt;/p&gt;
&lt;p&gt;When a civil architect--be it Frank Lloyd Wright or the folks who designed the I-35 bridge in Minnesota--sits down to draw up the plans for a given project, they do so under a fairly strict set of laws and codes governing the process. Not only must the civic restrictions about safety and appearance be honored and respected, but also the basic physical laws of the universe--weight loads, stress, wind shear and harmonics (which the engineers of the first infamous Tacoma Narrows bridge discovered, to everlasting infamy). Ignoring these has disastrous consequences, and a discipline of mathematical calculation joins in with legal regulation to ensure that those laws are obeyed. Only then can the architect engage in the artistry that Lloyd Wright made so much a part of his craft.&lt;/p&gt;
&lt;p&gt;Software architecture, though, is a different matter. Not only do we mostly enjoy complete freedom from legal regulation (Sarbannes-Oxley compliance being perhaps the most notable exception, and even then it routinely fails to apply at the small- to medium-sized project levels), we can also ignore most of the laws of physics (the speed of digital signal across a cable or through the air being perhaps our most notable barrier at the moment). &quot;Access data in Tokyo from a web server in Beijing and send the rendered results to a browser in San Francisco? Sure, yeah, no problem, so long as there&apos;s a TCP/IP connection, I don&apos;t see why not....&quot; There&apos;s just so much less by way of physical restrictions in software than there is in civil (or any other kind) of engineering, it seems.&lt;/p&gt;
&lt;p&gt;And that sort of hits the central point squarely on the head--there&apos;s a lot we don&apos;t know about building software yet. We keep concocting these tortured metaphors and imperfect analogies to other practices, industries and disciplines in an attempt to figure out how best to build software, and they keep leading us astray in various ways. When&apos;s the last time you heard an accountant say, &quot;Well, what I do is kinda like what the clerk in a retail store does--handle money--so therefore I should take ideas on how to do my job better from retail store clerks&quot;? Sure, maybe the basic premise is true at some levels, but clearly the difference is in the details. And analogies and metaphors have this dangerous habit--they cause us to lose sight of those limitations, in the pursuit of keeping the analogy pure. Remember when everybody was getting purist about objects, such that an automobile repair shop&apos;s accounting system had to model &quot;Car&quot; as an object having an &quot;Engine&quot; object and four &quot;Tire&quot; objects and so on, not because these were things that needed to be repaired and tracked somehow, but because cars in real life have an engine and four tires and other things? (Stroustrup even touches on this at one point, talking about an avionics system which ran into design difficulties trying to decide if &quot;Cloud&quot; objects were owned by the &quot;Sky&quot; object, or something along those lines.) All analogies break down somewhere.&lt;/p&gt;
&lt;p&gt;Now, to go back to architects and architecture. At the risk of offering up yet &lt;em&gt;another&lt;/em&gt; of those tortured metaphors, let me proffer my own architect analogy: an architect is not like a construction architect, but more like the conductor of a band or symphony. Yes, the band could play without him, but at the end of the day, the band plays &lt;em&gt;better&lt;/em&gt; with one guy coordinating the whole thing. The larger the band, the more necessary a conductor becomes. Sometimes the conductor is the same thing as the composer (and perhaps that&apos;s the most accurate analogous way to view this), in which case it&apos;s his &quot;vision&quot; of how the music in his head should come out in real life, and his job is to lead the performers into contributing towards that vision. Each performer has their own skills, freedom to interpret, and so on, but within the larger vision of the work.&lt;/p&gt;
&lt;p&gt;Is it a perfect analogy? Heavens, no. It falls apart, just as every other analogy does, if you stress it too hard. But it captures the essence of art and rigor that I think seeing it as &quot;architecture&quot; along the lines of civil engineering just can&apos;t. At least, not easily.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Of Zealotry, Idiocy, and Etiquette...</title>
      <link>http://blogs.newardassociates.com/blog/2008/of-zealotry-idiocy-and-etiquette.html</link>
      <pubDate>Tue, 15 Jul 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/of-zealotry-idiocy-and-etiquette.html</guid>
      	<description>
	&lt;p&gt;I&apos;m not sure what it is about our industry that promotes the flame war, but for some reason exchanges like &lt;a href=&quot;http://james-iry.blogspot.com/2008/07/is-scala-for-academics-and-egomaniacs.html&quot;&gt;this one&lt;/a&gt;, unheard of in any other industry I&apos;ve ever touched (even tangentially), are far too common, too easy to get into, and entirely too counterproductive.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;I&apos;m not going to weigh in on one side or the other here; frankly, I have a hard time following the debate and figuring out who&apos;s exactly arguing for what. I can see, however, that the entire debate follows some traditional patterns of the flame war:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;em&gt;Citing yourself as the final authority.&lt;/em&gt; At no point during the debate does anybody reach for their copy of &lt;em&gt;Effective Java&lt;/em&gt;, a widely-accepted source of Java guidance, for a potential resolution to the discussion. Instead, the various players simply say, &quot;Fact A is true&quot; or &quot;Fact A is false&quot;, with zero supporting information, citations, or demonstrations either way. (A few people cite the Javadoc, but there is enough ambiguity there to merit further citation.)&lt;/li&gt; &lt;li&gt;&lt;em&gt;Refusal to accept the possibility of an alternative viewpoint.&lt;/em&gt; At no point, near as I can tell, did any of the participants bother to say, &quot;You know, you could be right, but I remain unconvinced. Can you give me more information to support your point of view?&quot; The entire time, everybody is arguing from &quot;fact&quot;, and nobody even considers the possibility that different JVMs can have different implementations, despite the fact that the Javadoc being quoted says as much.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Degeneration into personal attacks.&lt;/em&gt; I don&apos;t care who started it, I don&apos;t care who called who the worse name. Fact is, reasonable people can reasonably disagree, and nobody in that transcript seemed overly reasonable to me.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Nobody ever really gets around to answering the question because they&apos;re too busy arguing their position or point.&lt;/em&gt; Poor &quot;doub&quot;, the initiator of the question, tries valiantly to circle the conversation back on topic, but the various players are too busy whipping out their instruments of manhood onto the table so everybody can see how much bigger it is than the other guys&apos;. When &quot;doub&quot; points out that writing some sample code &quot;gave me a very loose but still usefull information about my object, and took less time than the conversation about my question :-)&quot;, or in other words, &quot;Hey, guys, I kinda already got my answer, can we move on now?&quot;, the conversation continues as if the comment never occurred--the question has turned into a &quot;biggest-geek&quot; argument by this point. &quot;doub&quot; even asks, at 10:12:12, &quot;do i get bad karma points for being the initiator of a conflict?&quot;, and the image I get in my head is that of the poor kid, hiding in his bedroom while his parents yell and scream downstairs, feeling awful because the fight started over his backpack lying in the hallway where Mom told him to put it and Dad thought he left it instead of putting it away. (&quot;doub&quot;, if you read this, no, you get no bad karma points, at least not in my universe.)&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;The interesting thing, though, is that this conversation has &lt;em&gt;nothing&lt;/em&gt; to do with Scala. &quot;dysinger&quot; twitters:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&quot;It&apos;s no wonder scala sucks at gaining any momentum with that kind of academic egomaniac cliques going on in the community.&quot; (&lt;a title=&quot;http://twitter.com/dysinger/statuses/859189384&quot; href=&quot;http://twitter.com/dysinger/statuses/859189384&quot;&gt;http://twitter.com/dysinger/statuses/859189384&lt;/a&gt;)&lt;/li&gt; &lt;li&gt;&quot;@DRMacIver if you often get called an academic programmer, it&apos;s probably because you _are_ one. Scala + zero tolerance + ego = academic.&quot; (&lt;a title=&quot;http://twitter.com/dysinger/statuses/859201109&quot; href=&quot;http://twitter.com/dysinger/statuses/859201109&quot;&gt;http://twitter.com/dysinger/statuses/859201109&lt;/a&gt;)&lt;/li&gt; &lt;li&gt;&quot;@DRMaclver starts with this &quot;Or, in other words, you&apos;re full of shit. Kindly shut up about this now.&quot; to my chat. That set me off. Idiot.&quot; (&lt;a title=&quot;http://twitter.com/dysinger/statuses/859204285&quot; href=&quot;http://twitter.com/dysinger/statuses/859204285&quot;&gt;http://twitter.com/dysinger/statuses/859204285&lt;/a&gt;)&lt;/li&gt; &lt;li&gt;&quot;ok - I am better now. I was seeing red for a minute there.... R.I.P. Scala You were barely a twinkle in somebody&apos;s eye and now your dead.&quot; (&lt;a title=&quot;http://twitter.com/dysinger/statuses/859214117&quot; href=&quot;http://twitter.com/dysinger/statuses/859214117&quot;&gt;http://twitter.com/dysinger/statuses/859214117&lt;/a&gt;)&lt;/li&gt; &lt;li&gt;&quot;Felt better when I wrote some scala code to prove to #scala that they have a tard for a channel op -&amp;gt; http://is.gd/Ulx&quot; (&lt;a title=&quot;http://twitter.com/dysinger/statuses/859457360&quot; href=&quot;http://twitter.com/dysinger/statuses/859457360&quot;&gt;http://twitter.com/dysinger/statuses/859457360&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Frankly, &quot;dysinger&quot;, it&apos;s kinda hard to have much sympathy for somebody when they blame the language or tool for a conversation that&apos;s had around it; this would be like blaming Python, the language, for the community around it (which some people do, I understand). I can understand the frustration, on both sides, since everybody was essentially arguing past one another, but why is that Scala&apos;s fault, pray tell?&lt;/p&gt;
&lt;p&gt;And frankly, I find the dig at the academics to be a tad disingenuous. Yes, academics have a reputation--duly earned in &lt;em&gt;some&lt;/em&gt; cases--of being removed from reality and the slings and arrows of a life spent developing software for production environments, but name for me a language in the popular mainstream that doesn&apos;t owe a huge debt to the preliminary work laid down by academics before it. In &lt;em&gt;every&lt;/em&gt; other industry, academics are revered and honored--it&apos;s only in this industry they are used as an example of degradation and insult. Way to bite the hand that makes your life easier, folks....&lt;/p&gt;
&lt;p&gt;At the end of the day, these kind of debates do nothing but harm the innocent, &quot;doub&quot;, in this case. &quot;dysinger&quot;, &quot;DrMacIver&quot;, &quot;JamesIry&quot;, all of you, right or wrong, didn&apos;t exactly cover yourselves in glory, nor did you really convince anybody of anything. Instead, you shouted at each other really loudly, made lots of noise, got angry over nothing in particular, and really failed to achieve much of anything. Regardless of your intentions, now Scala, Java, the JVM and the entire ecosystem have seen their reputation tarnished just a touch more than it was when you started. Great job.&lt;/p&gt; &lt;p&gt;Here&apos;s a tip for all of you: Try &lt;em&gt;listening&lt;/em&gt;.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The power of Office as a front-end</title>
      <link>http://blogs.newardassociates.com/blog/2008/the-power-of-office-as-a-front-end.html</link>
      <pubDate>Wed, 2 Jul 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/the-power-of-office-as-a-front-end.html</guid>
      	<description>
	&lt;p&gt;I recently had the pleasure of meeting Bruce Wilson, a principal with iLink, and we had a pleasant conversation about enterprise applications and trends and such. Last week, in the middle of my trip to &lt;a href=&quot;http://javasymposium.techtarget.com/europe/index.html&quot;&gt;Prague&lt;/a&gt; and &lt;a href=&quot;http://jazoon.com/&quot;&gt;Zurich&lt;/a&gt;, he sent me a link to a blog entry he&apos;d written on &lt;a href=&quot;http://bruminations.wordpress.com/2008/06/17/enterprise-meet-mashups-user-experience-20-via-soa-and-obas/&quot;&gt;using Office as a front-end&lt;/a&gt;, and it sort of underscored some ideas I&apos;ve had around Office in general. &lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;The interesting thing is, most of the ideas he talks about here could just as easily be implemented on top of a Java back-end, or a Ruby back-end, as a .NET back-end. Office is a tool that many end-users &quot;get&quot; right away (whether you agree with Microsoft&apos;s user interface metaphors or not, or even &lt;em&gt;like&lt;/em&gt; the fact that Office is one of the most widely-installed software packages on the planet), and it has a lot of support infrastructure built in. &quot;Mashup&quot; doesn&apos;t have to mean YouTube on your website; in fact, I dislike the term &quot;mashup&quot; entirely, since it sounds like something done in the heat of the moment without any planning or thought (which is the antithesis of anything that goes--or should go--into the enterprise). Can we use the term &quot;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb288452.aspx&quot;&gt;cardinality&lt;/a&gt;&quot; instead? Please?&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Thinking in Language</title>
      <link>http://blogs.newardassociates.com/blog/2008/thinking-in-language.html</link>
      <pubDate>Thu, 8 May 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/thinking-in-language.html</guid>
      	<description>
	&lt;p&gt;A couple of folks have taken me to task over some of the things I said... or didn&apos;t say... in my last blog piece. So, in no particular order, let&apos;s discuss.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;A few commented on how I left out commentary on language X, Y or Z. That wasn&apos;t an accidental slip or surge of forgetfulness, but I didn&apos;t want to rattle off a laundry list of every language I&apos;ve run across or am exploring, since that list would be much, much longer and arguably of little to no additional benefit. Having said that, though, a more comprehensive list (and more comprehensive explanation and thought process) is probably deserved, so expect to see that from me before long, maybe in the next week or two.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://steve.vinoski.net/blog/2008/05/01/erlang-its-about-reliability/&quot;&gt;Steve Vinoski wrote&lt;/a&gt;:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;In a &lt;a href=&quot;http://blogs.tedneward.com/2008/04/29/Groovy+Or+JRuby.aspx&quot;&gt;recent post, Ted Neward&lt;/a&gt; gives a brief description of a variety of programming languages. It’s a useful post; I’ve known Ted for awhile now, and he’s quite knowledgeable about such things. Still, I have to comment on what he says about Erlang....&amp;nbsp; I might have said it like this:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;&lt;strong&gt;Erlang&lt;/strong&gt;. Joe Armstrong’s baby was built to solve a specific set of problems at Ericsson, and from it we can learn a phenomenal amount about building highly reliable systems that can also support massive concurrency. The fact that it runs on its own interpreter, good; otherwise, the reliability wouldn’t be there and it would be just another curious but useless concurrency-oriented language experiment.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Far too many blog posts and articles that touch on Erlang completely miss the point that reliability is an extremely important aspect of the language. &lt;p&gt;To achieve reliability, you have to accept the fact that failure &lt;em&gt;will&lt;/em&gt; occur, Once you accept that, then other things fall into place: you need to be able to restart things quickly, and to do that, processes need to be cheap. If something fails, you don’t want it taking everything else with it, so you need to at least minimize, if not eliminate, sharing, which leads you to message passing. You also need monitoring capabilities that can detect failed processes and restart them (BTW in the same posting Ted seems to claim that Erlang has no monitoring capabilities, which baffles me). &lt;p&gt;Massive concurrency capabilities become far easier with an architecture that provides lightweight processes that share nothing, but that doesn’t mean that once you design it, the rest is just a simple matter of programming. Rather, actually &lt;em&gt;implementing&lt;/em&gt; all this in a way that delivers what’s needed and performs more than adequately for production-quality systems is an incredibly enormous challenge, one that the Erlang development team has quite admirably met, and that’s an understatement if there ever was one. &lt;p&gt;They come for the concurrency but they stay for the reliability. Do any other “Erlang-like” languages have real, live, production systems in the field that have been running non-stop for years? (That’s not a rhetorical question; if you know of any such languages, please let me know.) Next time you see yet another posting about Erlang and concurrency, especially those of the form “Erlang-like concurrency in language X!” just ask the author: where’s the reliability?&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;As he says, Steve and I have known each other for a while now, so I&apos;m fairly comfortable in saying, Mr. Vinoski, you conflate two ideas together in your assessment of Erlang, and teasing those two things apart reveals a great deal about Erlang, reliability, and the greater world at large.&lt;/p&gt; &lt;p&gt;Erlang&apos;s reliability model--that is, the spawn-a-thousand-processes model--is not unique to Erlang. In fact, it&apos;s been the model for Unix programs and servers, most notably the Apache web server, for decades. When building a robust system under Unix, a master-slave model, in which a master process spawns (and monitors) &lt;em&gt;n&lt;/em&gt; number of child processes to do the actual work, offers that same kind of reliability and robustness. If one of these processes fail (due to corrupted memory access, operating system fault, or what-have-you), the process can simply die and be replaced by a new child process. Under the Windows model, which stresses threads rather than processes, corrupted memory access tearing down the process brings down the entire system; this is partly why .NET chose to create the AppDomain model, which looks and feels remarkably like the lightweight process model. (It still can&apos;t stop a random rogue pointer access from tearing down the entire process, but if we assume that future servers will be written all in managed code, it offers the same kind of reliability that the process model does so long as your kernel drivers don&apos;t crash.)&lt;/p&gt; &lt;p&gt;There is no reason a VM (JVM, CLR, Parrot, etc) could not do this. In fact, here&apos;s the kicker: it would be &lt;em&gt;easier&lt;/em&gt; for a VM environment to do this, because VM&apos;s, by their nature, seek to abstract away the details of the underlying platform that muddy up the picture. It would be relatively simple to take an Actors-based Java application, such as that currently being built in Scala, and move it away from a threads-based model and over to a process-based model (with the JVM constuction/teardown being handled entirely by underlying infrastructure) with little to no impact on the programming model.&lt;/p&gt; &lt;p&gt;As to Steve&apos;s comment that the Erlang interpreter isn&apos;t monitorable, I never said that--I said that Erlang was not monitorable using current IT operations monitoring tools. The JVM and CLR both have gone to great lengths to build infrastructure hooks that make it easy to keep an eye not only on what&apos;s going on at the process level (&quot;Is it up? Is it down?&quot;) but also what&apos;s going on inside the system (&quot;How many requests have we processed in the last hour? How many of those were successful? How many database connections have been created?&quot; and so on). Nothing says that Erlang--or any other system--can&apos;t do that, but it requires the Erlang developer build that infrastructure him-or-herself, which usually means it&apos;s either not going to get done, making life harder for the IT support staff, or else it gets done to a minimalist level, making life harder for the IT support staff.&lt;/p&gt; &lt;p&gt;So given that an execution engine could easily adopt the model that gives Erlang its reliability, and that using Erlang means a lot more work to get the monitorability and manageability (which is a necessary side-effect requirement of accepting that failure happens), hopefully my reasons for saying that Erlang (or Ruby&apos;s or any other native-implemented language) is a non-starter for me becomes more clear.&lt;/p&gt; &lt;p&gt;Meanwhile, &lt;a href=&quot;http://patricklogan.blogspot.com/2008/05/huh-fact-that-it-runs-on-its-own.html&quot;&gt;Patrick Logan offers up some sharp words&lt;/a&gt; about my preference for VMs:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;What is this &lt;a href=&quot;http://blogs.tedneward.com/2008/04/29/Groovy+Or+JRuby.aspx&quot;&gt;obsession with some virtual machine being the one&lt;/a&gt;, true byte code? The Java Virtual Machine, the CLR, Parrot, whatever. Give it up.  &lt;p&gt;I agree &lt;a href=&quot;http://steve.vinoski.net/blog/2008/05/01/erlang-its-about-reliability/&quot;&gt;with Steve Vinoski&lt;/a&gt;...  &lt;blockquote&gt;&lt;em&gt;The fact that it runs on its own interpreter, good; otherwise, the reliability wouldn’t be there. &lt;/em&gt;&lt;/blockquote&gt;We need to get over our thinking about &quot;One VM to bring them all and in the darkness bind them&quot;. Instead we should be focused on improving interprocess communication among various languages. This can be done with HTTP and XMPP. And we should expecially be focused on reliability, deployment, starting and stopping locally or remotely, etc. XMPP&apos;s &quot;presence&quot; provides Erlang-process-like linking of a sort as well.  &lt;p&gt;With Erlang&apos;s JInterface for Java then a Java process can look like an Erlang process (distributed or remote). Two or more Java processes can use JInterface to communicate and &quot;link&quot; reliably and Erlang virtual machines and libraries, save this one single .jar, do not have to be anywhere in sight.  &lt;p&gt;To obsess about a single VM is to remain stuck at about 1980 and UCSD Pascal&apos;s p-code. It just should not matter today, and certainly not tomorrow. The forest is now much more important than any given tree.  &lt;p&gt;Pay attention to &lt;a href=&quot;http://www.infoq.com/interviews/project-zero-cuomo&quot;&gt;the new JVM from IBM&lt;/a&gt; in support of their lightweight, fast-start, single-purpose process philosophy embodied in Project Zero. It&apos;s not intended to be a big honkin&apos; run everything forever virtual machine. It will support JVM languages and the more the merrier in the sense that such a JVM will enable lightweight pieces to be stiched together dynamically. However the intention is to perform some interprocess communication and then get out of the way. Exactly the right approach for any virtual machine.  &lt;p&gt;Jini clearly is *the* most important thing about Java, ever. But it&apos;s lost. Gone. Buh-bye. Pity.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&quot;We need to get over our thinking about &quot;One VM to bring them all and in the darkness bind them&quot;. &quot; &lt;em&gt;Huh?&lt;/em&gt; How did we go from &quot;I like virtual machine/execution environments because of the support they give my code for free&quot; to &quot;One VM to bring them all and in the darkness bind them&quot;? I truly fail to see the logical connection there. My love for both the JVM &lt;em&gt;and&lt;/em&gt; the CLR has hopefully made itself clear, but maybe Patrick&apos;s only subscribed to the Java/J2EE category bits of my RSS feed. Fact is, I&apos;m coming to like any virtual machine/execution environment that offers a layer of abstraction over the details of the underlying platform itself, because developers do not want to deal with those details. They want to be able to get at them when it becomes necessary, granted, but the actual details should remain hidden (as best they can, anyway) until that time.&lt;/p&gt; &lt;p&gt;&quot;Instead we should be focused on improving interprocess communication among various languages. This can be done with HTTP and XMPP.&quot;&amp;nbsp; I&apos;m sorry, but I&apos;m getting very very tired of this &quot;HTTP is the best way to communicate&quot; meme that surrounds the Internet. Yes, HTTP was successful. Nobody is arguing with this. So is FTP. So is SMTP and POP3. So, for that matter, is XMPP. &lt;em&gt;Each serves a useful purpose, solving a particular problem.&lt;/em&gt; Let&apos;s not try to force everything down a single pipe, shall we? I would hate to be so focused on the tree of HTTP that we lose sight of the forest of communication protocols.&lt;/p&gt; &lt;p&gt;&quot;And we should expecially &lt;em&gt;[sic]&lt;/em&gt; be focused on reliability, deployment, starting and stopping locally or remotely, etc. XMPP&apos;s &quot;presence&quot; provides Erlang-process-like linking of a sort as well.&quot; &lt;em&gt;Yes!&lt;/em&gt; XMPP&apos;s &quot;presence&quot; aspect is a powerful one, and heavily underutilized. &quot;Presence&quot;, however, is really just a specific form of &quot;discovery&quot;, and quite frankly our enterprise systems need to explore more &quot;discovery&quot;-based approaches, particularly for resource acquisition and monitoring. I&apos;ve talked about this for years.&lt;/p&gt; &lt;p&gt;&quot;To obsess about a single VM is to remain stuck at about 1980 and UCSD Pascal&apos;s p-code.&quot; Great one-liner... with no supporting logic, granted, but I&apos;m sure it drew a cheer from the faithful.&lt;/p&gt; &lt;p&gt;&quot;It just should not matter today, and certainly not tomorrow.&quot; For what reason? Based on what concepts? Look, as much as we want to try and abstract ourselves away from everything, at some point rubber must meet road, and the semantic details of the platform you&apos;re using--virtual or otherwise--make a huge difference about how you build systems. For example, Erlang&apos;s many-child-processes model works well on Unix, but not as well on Windows, owing to the heavier startup costs of creating a process under Windows. For applications that will involve spinning up thousands of processes, Windows is probably not a good platform to use.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;Disclaimer: This &quot;it&apos;s heavier to spin up processes on Windows than Unix&quot; belief is one I&apos;ve not verified personally; I&apos;m trusting what I&apos;ve heard from other sources I know and trust. Under later Windows releases, this may have changed, but my understanding is that it is still much much faster to spin up a thread on Windows than a separate process, and that it is only marginally faster to spin up a thread on Unix than a process, because many Unixes use the process model to &quot;fake&quot; threads, the so-called LightWeightProcess model.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&quot;The forest is now much more important than any given tree.&quot; &lt;em&gt;Yes!&lt;/em&gt; And that means you have to keep an eye on the forest as a whole, which underscores the need for monitoring and managing capabilities in your programs. Do you want to build this by hand?&lt;/p&gt; &lt;p&gt;&quot;Pay attention to &lt;a href=&quot;http://www.infoq.com/interviews/project-zero-cuomo&quot;&gt;the new JVM from IBM&lt;/a&gt; in support of their lightweight, fast-start, single-purpose process philosophy embodied in Project Zero. It&apos;s not intended to be a big honkin&apos; run everything forever virtual machine. It will support JVM languages and the more the merrier in the sense that such a JVM will enable lightweight pieces to be stiched together dynamically. However the intention is to perform some interprocess communication and then get out of the way. Exactly the right approach for any virtual machine.&quot; &lt;em&gt;Yes!&lt;/em&gt; You make my point for me--the point of the virtual machine/execution environment is to reduce the noise a developer must face, and if IBM&apos;s new VM gains us additional reliability by silently moving work and data between processes, great! But the only way you take advantage of this is by &lt;em&gt;writing to the JVM&lt;/em&gt;. (Or CLR, or Parrot, or whatever.) If you don&apos;t, and instead choose to write to something that doesn&apos;t abstract away from the OS, you have to write all of this supporting infrastructure code yourself. That sounds like fun, right? Not to mention highly business-ROI-focused?&lt;/p&gt; &lt;p&gt;&quot;Jini clearly is *the* most important thing about Java, ever. But it&apos;s lost. Gone. Buh-bye. Pity.&quot; Jini was cool. I liked Jini. Jini got nowhere because Sun all but abandoned it in its zeal to push the client-server EJB model of life. &lt;em&gt;sigh&lt;/em&gt; I wish they had sought to incorporate more of the discovery elements of Jini into the J2EE stack (see the previous paragraph). But they didn&apos;t, and as a result, Jini is all but dead.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;Disclaimer: I know, I know, Jini isn&apos;t really dead. The bits are still there, you can still download them and run them, and there is a rabidly zealous community of supporters out there, but as a tool in widespread use and a good bet for an IT department, it&apos;s a non-starter. Oh, and if you&apos;re one of those rabidly zealous supporters, don&apos;t bother emailing me to tell me how wrong I am, I won&apos;t respond. Don&apos;t forget that FoxPro and OS/2 still have a rabidly zealous community of supporters out there, too.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Frankly, a comment on Patrick&apos;s blog entry really captures my point precisely, so (hopefully with permission) I will repeat it here:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;The only argument you made that I can find against sharing VMs is that people should be focusing on other things. But the main reason for sharing VMs is to allow people to focus on other things, instead of focusing on creating yet another VM.&lt;/p&gt; &lt;p&gt;You write as if you think creating an entirely new VM from scratch would be easier than targeting a common VM. Is that really what you think?&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Couldn&apos;t have said it better... though that never stops me from trying. ;-)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Do you fall prey to technical folk etymology?</title>
      <link>http://blogs.newardassociates.com/blog/2008/do-you-fall-prey-to-technical-folk-etymology.html</link>
      <pubDate>Wed, 16 Apr 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/do-you-fall-prey-to-technical-folk-etymology.html</guid>
      	<description>
	&lt;!--more--&gt;
&lt;p&gt;From &lt;a href=&quot;http://en.wikipedia.org/wiki/Folk_etymology&quot;&gt;Wikipedia&lt;/a&gt; (itself a source of conceptual folk etymology, but that&apos;s another rant):&lt;/p&gt; &lt;ul&gt; &lt;ul&gt; &lt;li&gt;A commonly held misunderstanding of the origin of a particular word, a false etymology&lt;/li&gt; &lt;li&gt;&quot;The popular perversion of the form of words in order to render it apparently significant&quot;; &quot;the process by which a word or phrase, usually one of seemingly opaque formation, is arbitrarily reshaped so as to yield a form which is considered to be more transparent&quot;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt; &lt;p&gt;What do I mean by &quot;technical folk etymology&quot;? &lt;/p&gt; &lt;ol&gt; &lt;li&gt;If you&apos;re a Java developer, consider the term &lt;em&gt;EJB&lt;/em&gt;. No, I mean, seriously think about it for a moment. What images are conjured before your eyes when you do so? Horrendous APIs, hideous deployment requirements, complete untestability, and something that takes forty-five minutes to start?&lt;/li&gt; &lt;li&gt;If you&apos;re a Ruby developer, consider the phrase &lt;em&gt;static typing&lt;/em&gt;. Same sort of reaction?&lt;/li&gt; &lt;li&gt;If you&apos;re a .NET developer, try on &lt;em&gt;COM&lt;/em&gt; or &lt;em&gt;COM+&lt;/em&gt; or even &lt;em&gt;ATL&lt;/em&gt;. Mystifying collections of code repeated by rote, cut-and-pasted from that very first project you built by hand from &lt;em&gt;Inside OLE 2&lt;/em&gt;, and once you got it to work, served as your basic template for every other COM/MTS/COM+ entity you ever built?&lt;/li&gt; &lt;li&gt;Or, if you&apos;re any of these, how about &lt;em&gt;Visual Basic&lt;/em&gt;?&lt;/li&gt; &lt;li&gt;Or maybe &lt;em&gt;Web services&lt;/em&gt;, specifically all those WS-* specifications?&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;As the MVP Summit Product Team dinners wound down here in Redmond tonight, I found myself at a table with (not surprisingly) Neal Ford and Venkat Subramaniam, two of my close friends from the NFJS tour, and who should join us but first Amanda Silver (lately of the Office team, but with her heart still firmly rooted in her Visual Basic dev days), then Don Box (lately of the Oslo team) and Chris Sells (also lately of the Oslo team), and a rousing discussion around the concept of DSLs--domain specific languages--arose, largely because Don wanted to sound out Venkat and Neal on the subject.&lt;/p&gt; &lt;p&gt;Listening to the conversation (Don was mostly interested in Neal and Venkat&apos;s opinions, so I just relaxed and listened for the most part), I realized that the discussion was entirely rooted in this concept of &lt;em&gt;context&lt;/em&gt;, that ephemeral structure surrounding a concept that gives it shape and color and taste and the other aesthetic qualities that lead us to &quot;like&quot; or &quot;dislike&quot; or &quot;accept&quot; or &quot;reject&quot; certain concepts. Don held the position--either for arguments&apos; sake or because he believes it, I&apos;m not sure which--that domain-specific languages lose context too easily once stored on the file system, in ways that data does not. His test was to suggest &quot;What if a random piece of text drops into my email, how do I know what consumes this text?&quot; The answer, of course, is that you don&apos;t, unless you somehow have a context by which to understand a piece of text, in many cases based solely on nothing more than filesystem extension, or MIME type, or the &quot;#!/bin/...&quot; line that precedes many shell scripts, and so on.&lt;/p&gt; &lt;p&gt;Interestingly enough, as I drove home after the dinner, I realized that the conversation echoed an exchange Neal and Venkat and I were having in the car on the way over, about how Microsoft (I think) is making a &lt;em&gt;huge&lt;/em&gt; mistake by looking to make C# more dynamic in nature[1]. My position was (and is) that Microsoft needs to differentiate the two key languages they offer--C# and Visual Basic--and an obvious way to do so would be to designate VB as the official &quot;dynamic language&quot; for the CLR, and C# as the official &quot;static language&quot; for the CLR, and encourage developers to use C# to build infrastructure (libraries and business types and so on) and VB to build &quot;top of the stack&quot; kinds of code (WinForms, ASP.NET, and so on).&lt;/p&gt; &lt;p&gt;Neal put me squarely back on my heels with this (paraphrased) comment: Microsoft will never do this, because Visual Basic will &lt;em&gt;never&lt;/em&gt; be able to shed the image it has gained, that of being the programming language for idiots[2].&lt;/p&gt; &lt;p&gt;Wow.&lt;/p&gt; &lt;p&gt;Sad thing is, he&apos;s right. Go back to the terms I suggested you think about at the top of this blog post. If you&apos;re like most Java developers, you heard the term &quot;EJB&quot; and immediately got a note of distaste in your mouth. You know that if you suggest EJB on your next Java project, you will be ridiculed and shamed and made to stand in the corner with the Dunce Cap on, &lt;em&gt;even if it makes complete sense from a technical perspective&lt;/em&gt;. Companies are choosing instead to build their own transactional-oriented client/server middleware infrastructure, just to avoid the &quot;shame&quot; of using EJB. Because, as we all know, you just can&apos;t test EJB.&lt;/p&gt; &lt;p&gt;Which, by the way, is a fallacy, and always has been. Oh, I know, you meant you can&apos;t &lt;em&gt;unit&lt;/em&gt;-test EJB, but that&apos;s a fallacy too. It&apos;s &lt;a href=&quot;http://openejb.apache.org/&quot;&gt;always been testable&lt;/a&gt;, to the same degree that any servlet application has been testable, it&apos;s just that nobody wanted to take the time to figure out how to test it effectively, particularly not once Rod Johnson had unleashed Spring upon the world and Made Everything Better(TM) (or, at least, XML configurable, which is better... right?).&lt;/p&gt; &lt;p&gt;Static typing suffers the same kind of negative prejudice today. Suggest that C++ has a place in the world, and you will be kicked to the curb by any Right-Thinking Technical Leader. Suggest that C++ has a place on your next project, and you&apos;re likely to get sternly reprimanded, possibly even cut loose from the project. Suggest &lt;em&gt;anything&lt;/em&gt; that doesn&apos;t fit with the Way We Build Software Today, and you&apos;re swimming upstream, either with management or with your fellow developers.&lt;/p&gt; &lt;p&gt;All because they fall prey to technical folk etymology. They bend the context around the phrases in question to mean something entirely different than what the words actually mean, and as a result, the words take on an aura of snarling, bitter distaste, or, worse, angelic euphoric enlightenment.&lt;/p&gt; &lt;p&gt;Domain-specific languages are the new phrase of the moment, and its emotional context is being built as we speak. Functional languages will be there sometime next year or the year after. For both, the euphoria is growing, and for each, in some period of &lt;em&gt;n&lt;/em&gt; (three, maybe four) years will be crashing just as hard as they were built up, just as Ruby&apos;s and Visual Basic&apos;s and COM&apos;s and EJB&apos;s and WS-*&apos;s and other technologies have done before it. It&apos;s as predictable as the flow of alcohol at an MVP Summit, or the consumption of either caffeine at an all-night code frenzy.&lt;/p&gt; &lt;p&gt;Other industries have varying relationships with this notion of context: the medical field seems to be almost as susceptible to it as we are, particularly the area of weight management and holistic health (remember the water diet? the South Beach diet? the no-sodium diet? the low-cholesterol diet?), whereas traditional engineering disciplines, such as electrical and construction disciplines, seem far less vulnerable to &quot;the hip new thing of the day&quot;. I&apos;m not sure why this is, quite honestly, except that software and medicine share the similar characteristics of a rapid influx of new information on a regular, even daily, basis.&lt;/p&gt; &lt;p&gt;People often call me a contrarian, a technical fuddy-duddy who refuses to embrace anything new or anything &quot;bleeding-edge&quot;. In many respects, I welcome and accept that label, but frankly, I bristle at the implicit &quot;you just don&apos;t want to learn anything new&quot; accusation, because it&apos;s a gross misunderstanding and hideous misinterpretation of what I&apos;m &lt;em&gt;really&lt;/em&gt; trying to do: Distance myself from the emotional context surrounding a technology, and examine it through the lens of dispassionate observation.&lt;/p&gt; &lt;p&gt;In short, I actively seek to defeat technical folk etymology, if only in the small area I personally can affect.&lt;/p&gt; &lt;p&gt;Do you?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[1] &lt;em&gt;That particular discussion will have to wait for a different blog post on a different day.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;[2] &lt;em&gt;I should point out, before the hate mail comes flooding in, that this isn&apos;t Neal&apos;s own opinion, nor mine--witness my post on &quot;Mort means productivity&quot;. What he--and I--refer to here is the reputation Visual Basic has garnered, not the fact surrounding it. And if you care to argue that point, then you&apos;re not paying attention to the relative average salary numbers between C# and Visual Basic developers. The laws of economics do not lie.&lt;/em&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Is &quot;Performance&quot; Subjective or Objective?</title>
      <link>http://blogs.newardassociates.com/blog/2008/is-performance-subjective-or-objective-in-nature.html</link>
      <pubDate>Thu, 10 Apr 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/is-performance-subjective-or-objective-in-nature.html</guid>
      	<description>
	&lt;p&gt;As a fellow Scala writer, I&apos;ve been following &lt;a href=&quot;http://www.codecommit.com/blog/&quot;&gt;Daniel Spiewak&apos;s blog&lt;/a&gt; with no small amount of interest, as he discovers little tidbits inside the Scala language (like the Option type). Then I ran across &lt;a href=&quot;http://www.codecommit.com/blog/java/groovys-performance-is-not-subjective&quot;&gt;this entry&lt;/a&gt;, about benchmarks and comparing the performance of Java, Groovy and Scala:&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;&lt;em&gt;(Editor&apos;s note: This post is likely to open a huge can of whoop-*ss on this blog, so unless you want to get caught up in the huge bar fight that&apos;s about to break out, you&apos;re advised to take your whiskey or beer and head outside for a smoke until the cops come.)&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt; &lt;p&gt;I’ve seen these results dozens of times (looking back at the post), but they never cease to startle me. How could Groovy be that much slower than everything else? Granted it is very much a dynamic language, compared to Java and Scala which are peers in static-land. But still, this is a ray tracer we’re talking about! There’s no meta-programming involved to muddle the scene, so a halfway-decent optimizer should be able to at least squeeze that gradient down to maybe 5x as slow, rather than a factor of &lt;strong&gt;830&lt;/strong&gt;.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;That&apos;s a huge discrepancy, and like Daniel, I&apos;m not sure where the perf hit comes from, particularly when we consider that JRuby, another language with equally powerful metaobject protocol (MOP) capabilities, is turning in performance times that are equal to those we see with the original Ruby interpreter (according to Daniel&apos;s blog entry, though I note that the comparison of JRuby to Java isn&apos;t given). And if the disbelievers in the crowd are starting to tune this out based on the fact that &quot;Ah, it must be an edge case, after all, there&apos;s always one benchmark that any language will fail compared to another one; maybe Groovy&apos;s just not cut out to do ray-tracing. Yeah, that must be it. Besides, how often do I really do ray-tracing when I&apos;m writing code at work?&quot;, take heed, for Daniel notes this and starts to cite other evidence that seem to establish a disturbing pattern:&lt;/p&gt;
&lt;blockquote&gt; &lt;p&gt;If this were an isolated incident, I would probably just blow it off as bad benchmarking, or perhaps an odd corner case that trips badness in the Groovy runtime. Then a week later, I read &lt;a href=&quot;http://www.jroller.com/rants/entry/why_is_groovy_so_slow&quot;&gt;this post&lt;/a&gt; by Pete Knego &lt;em&gt;(which shows Groovy&apos;s performance as equally disappointing, on the order of 7.6x to 56x worse than equivalent Java code --TKN).&lt;/em&gt;&lt;/p&gt; &lt;p&gt;All of this is old news, so the question is: Why am I bringing this up now? Well, I recently saw &lt;a href=&quot;http://groovy.dzone.com/news/groovy-vs-java-performance-jav&quot;&gt;a post&lt;/a&gt; on Groovy Zone by none-other-than Rick Ross, talking about this very subject. Rick’s post was in response to two posts (&lt;a href=&quot;http://tiago.org/cc/2008/03/21/groovy-performance-speed/&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;http://tiago.org/cc/2008/03/23/revisiting-groovy-performance-issues/&quot;&gt;here&lt;/a&gt;), discussing ways to improve Groovy code performance by obfuscating code.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Uh, oh. I don&apos;t know about y&apos;all, but anytime somebody is suggesting &lt;em&gt;improving&lt;/em&gt; performance by &lt;em&gt;obfuscating&lt;/em&gt; code, I&apos;m nervous--almost by definition, code obfuscation makes code run more &lt;em&gt;slowly&lt;/em&gt;, not more quickly, because now the bytecode is pulled out of familiar patterns recognizable by the JITter and therefore more aggressively turned into optimized native code. I&apos;m not saying Rick is wrong, but if his experiments are leading him to understand that obfuscated code is somehow running faster than non-obfuscated code, then something deeply strange is afoot.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;(Editor&apos;s note: Better hurry and head outside folks, the Groovyists in the corner are starting to grumble amongst themselves, working up the courage to toss that first beer in the piano player&apos;s face.)&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Daniel&apos;s not done here, though, and goes on:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Final result? &lt;blockquote&gt; &lt;p&gt;This text is being written as I was changing and trying things, I gained 20s from&lt;br&gt;minor changes of which I lost track. &lt;img alt=&quot;:-)&quot; src=&quot;http://www.codecommit.com/blog/wp-includes/images/smilies/icon_smile.gif&quot;&gt; I am currently at 1m30s (down from the&lt;br&gt;original 4m and comparing with Java’s 4s).&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I’m sorry, this is acceptable performance? This is someone who’s spent time trying to optimize Groovy, and &lt;em&gt;by his own admission,&lt;/em&gt; Groovy is &lt;strong&gt;23x&lt;/strong&gt; slower than the equivalent Java code. Certainly this is a far cry from the 830x slower in the ray tracer benchmark, but in this case it’s simple string manipulation, rather than a mathematically intensive test.  &lt;p&gt;Coming back to Rick’s entry, he looks at the conclusion and has this to say about it: &lt;blockquote&gt; &lt;p&gt;&lt;b&gt;Language performance is highly overrated&lt;/b&gt; &lt;p&gt;Much is often made of the theoretical “performance” of a language based on benchmarks and arcane tests. There have even been cases where vendors have built cheats into their products specifically so they would score well on benchmarks. In the end, runtime execution speed is not as important a factor as a lot of people would think it is if they only read about performance comparisons. Other factors such as maintainability, interoperability, developer productivity and tool and library support are all very significant, too.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Wait a minute, that sounds a lot like something else I’ve read recently! Maybe something like &lt;a href=&quot;http://www.nabble.com/Re%3A-Is-Groovy-the-slowest-dynamic-language--p16143470.html&quot;&gt;this&lt;/a&gt;: &lt;blockquote&gt; &lt;p&gt;Is picking out the few performance weaknesses the right way to judge the&lt;br&gt;overall speed of Groovy?  &lt;p&gt;To me the Groovy performance is absolutely sufficient because of the&lt;br&gt;easy integration with Java. If something’s too slow, I do it in Java. &lt;br&gt;And Java compared to Python is in most cases much faster.  &lt;p&gt;I appreciate the efforts of the Groovy team to improve the performance, &lt;br&gt;but if they wouldn’t, this would be no real problem to me. Groovy is the&lt;br&gt;grooviest language with a development team always having the simplicity &lt;br&gt;and elegance of the language usage in mind - and that counts to me. &lt;img alt=&quot;:-)&quot; src=&quot;http://www.codecommit.com/blog/wp-includes/images/smilies/icon_smile.gif&quot;&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;This is almost a mantra for the Groovy proponents: performance is irrelevant. What’s worse, is that the few times where they’ve been pinned down on a particular performance issue that’s &lt;em&gt;obviously&lt;/em&gt; a problem, the response seems to be along the lines of: this test doesn’t really show anything, since micro-benchmarks are useless.  &lt;p&gt;I’m sorry, but that’s a cop-out. Face up to it, Groovy’s performance is &lt;em&gt;terrible.&lt;/em&gt; Anyone who claims otherwise is simply not looking at the evidence. Oh, and if you’re going to claim that this is just a function of shoe-horning a dynamic language onto the JVM, check out a &lt;a href=&quot;http://shootout.alioth.debian.org/gp4sandbox/benchmark.php?test=all&amp;amp;lang=jruby&amp;amp;lang2=groovy&quot;&gt;direct comparison&lt;/a&gt; between JRuby and and Groovy. Groovy comes out ahead in only four of the tests. &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Uh, oh.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;(Editor&apos;s note: Head for the doors, folks--those guys in the corner wearing the black leather jackets sporting the &quot;Grails Rulez&quot; logos on the back have started to head for the center of the room, and they&apos;re looking drunk, mean, and angry.)&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Here comes the &lt;em&gt;coup de grace&lt;/em&gt;&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;What really bothers me about the Groovy performance debates is that most “Groovyists” seem to believe that performance is in the eye of the beholder. The thought is that it’s all just a subjective issue and so should be discounted almost completely from the language selection process. People who say this have obviously forgotten what it means to try to write a scalable non-trivial application which performs decently under load. When you start getting hundreds of thousands of hits an hour, you’ll be willing to sell your soul for every last millisecond.&lt;/p&gt; &lt;p&gt;The only answer I can think of is that the Groovy core team just &lt;strong&gt;doesn’t value performance.&lt;/strong&gt; Why else would they consistently bury their heads in the sand, ignoring the issues even when the evidence is right in front of them? It’s as if they have repeated their own “performance is irrelevant” mantra so many times that they are actually starting to believe it. It’s unfortunate, because Groovy really is an interesting effort. I may not see any value for my needs, but I can understand how a lot of people would. It fills a nice syntactic niche that other languages (such as Ruby) just miss. But all of its benefits are for naught if it can’t deliver when it counts.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;That did it.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;(Editor&apos;s note: Shiiiiiiiit! I didn&apos;t say nothing, HE did, why&apos;re you swinging that beer stein at *WHACK*)&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;^^^^^^^^^^^^^^^^^^^^^&lt;/p&gt; &lt;p&gt;OK, now that we&apos;ve gotten &lt;em&gt;that&lt;/em&gt; out of our system, let&apos;s sit back and examine this issue more carefully, shall we?&lt;/p&gt; &lt;p&gt;The fact is, Groovy is slower than it should be. The Groovy guys can mumble about how performance isn&apos;t that important and that developer productivity is what really matters and similar kinds of rationale, but at the end of the day, the basic fact remains that Groovy is, by measurement of several different tests, at least an order of magnitude slower than compiled Java code.&lt;/p&gt; &lt;p&gt;Or is it? Funny thing is, looking at some of these tests, they don&apos;t say whether the Groovy code was compiled first, or run through the Groovy interpreter. Theoretically this shouldn&apos;t matter, since the Groovy architecture essentially compiles the classes generated once read, it might make a difference in practice.&lt;/p&gt; &lt;p&gt;Although Daniel&apos;s post doesn&apos;t mention it, I went back and double-checked. Peter Knego&apos;s benchmark says that &quot;Groovy code was inside a Groovy script, compiled with groovyc.&quot;, which leads me to believe that it was compiled code rather than run through the Groovy shell interpreter, but it would be nice if the actual code and batch/command scripts that ran the benchmarks would be available. (He also notes that each time, the benchmark was &quot;warmed up&quot; by running the bechmark five or six times in a loop, presumably to allow the JIT to work its magic, but most notably, doesn&apos;t point out which JVM was used, -client or -server.) Meanwhile, Derek Young&apos;s ray-tracing example explicitly uses the Groovy interpreter, but defends that decision in comments: &quot;The only reason I didn’t use &lt;code&gt;groovyc&lt;/code&gt; was because the difference was so great, and the compilation overhead at the beginning of the run only takes a couple seconds. I decided it wasn’t worth waiting another two and a half hours to time the compiled output. Running with &lt;code&gt;groovy&lt;/code&gt; first compiles the code just like &lt;code&gt;groovyc&lt;/code&gt; does, then executes that code. It doesn&apos;t interpret the source code or run any differently.&quot;&lt;/p&gt; &lt;p&gt;So, apparently, it doesn&apos;t make much difference. That&apos;s not a good development for the Groovy language.&lt;/p&gt; &lt;p&gt;But let&apos;s put the hard numbers out of the way for a moment, and concentrate on the much bigger question: does the core Groovy team just not value performance? And, as a corollary to this, does the performance of a language really matter in a day and age when CPUs are still doubling in size and number of cores? Rick&apos;s (and others&apos;, including myself) positions on this seem fairly clear, that we long ago passed the threshold where programmer time became more expensive than CPU time, and therefore we should optimize based on programmer productivity, not CPU efficiency, and that&apos;s important to recognize: a language should enable the programmer to express the core idea without a great deal of &quot;noise&quot; or additional work, what Stu Halloway has coined as &quot;ceremony&quot;, and certainly Groovy takes the Java programmer a step closer towards that place of lower ceremony.&lt;/p&gt; &lt;p&gt;But...&lt;/p&gt; &lt;p&gt;But I can&apos;t help it, folks. Ted&apos;s First Law of Computer Science states that &quot;Dogma is the Root of All Evil&quot;, and holding scripting languages up as the last language you&apos;ll ever have to use is dogma, plain and simple. Ted&apos;s Second Law of Computer Science states, &quot;Context matters&quot;, and in this case, the context includes the performance cost of using a language or tool. Taking a performance hit that weighs in at the orders of magnitude mark is just too big to ignore--the ray-tracing example, at its close-to-four-orders-of-magnitude hit, almost suggests that it would have been just as expensive to offload all those calculations through a distributed RPC call to another machine, rather than calculate it locally in Groovy, and when it becomes faster to go off-CPU to do a calculation than to do it locally, something is wrong.&lt;/p&gt; &lt;p&gt;And Daniel&apos;s point is good to hear clearly through the noise: &quot;&lt;strong&gt;&lt;em&gt;When you start getting hundreds of thousands of hits an hour, you’ll be willing to sell your soul for every last millisecond.&lt;/em&gt;&lt;/strong&gt;&quot; Forget getting hundreds or thousands of hits an hour--the real test will be when the system gets hundreds or thousands of hits &lt;em&gt;per second&lt;/em&gt;, that&apos;s when developers will be scrambling to find ways to eke out those last bits of performance from the system, even if it means selling their last Mountain Dew (which for some is pretty much synonymous to &quot;soul&quot;) to whatever entity can give it to them.&lt;/p&gt; &lt;p&gt;So what exactly is my point with this particular entry, besides stirring the pot up a little? In order:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;&lt;em&gt;Measure for yourself.&lt;/em&gt;&lt;/strong&gt; As with all things performance and scalability related, abstract benchmarks aren&apos;t a good measure of how well it works for you and your system. Build a prototype, measure, and then compare that against your performance and scalability goals. You &lt;em&gt;did&lt;/em&gt; establish performance and scalability goals as part of your project&apos;s runup, right? (If you didn&apos;t, then you probably assume your users don&apos;t care about performance, and I suspect you&apos;ll be rudely surprised on the veracity of that statement before long...)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;&lt;em&gt;Benchmarks are tricky things&lt;/em&gt;&lt;/strong&gt;. Programmers could learn something from politicians, and that is the imprecise nature of poll results. Thanks to the nature of statistical analysis and the sample size and source used to produce the poll, polls are always cited with a &quot;plus or minus 3 percent&quot; (or 5 percent, or 10 percent) to indicate the imprecision assumed in the poll. Benchmarks, both across languages and across other products, should be assumed to have similar kinds of imprecision. As people have already noted, benchmarks very quickly get &quot;gamed&quot; in order to produce results that are unfairly biased one way or another if they&apos;re not explicitly written and administered to be fair and equal to all sides involved. This isn&apos;t to say that benchmarks aren&apos;t useful, they&apos;re just not useful to a point more precise than rounding to the nearest 10% figure.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;&lt;em&gt;Groovy IS slower than it could or should be.&lt;/em&gt;&lt;/strong&gt; As much as I like the people involved in the Groovy space, and as much as I like the language itself, I can&apos;t help but be very very worried that Groovy&apos;s performance numbers aren&apos;t anywhere close to where they should be. Yes, productivity will get you a long way in the technology-adoption market, but once people have adopted your language or tool, if your system proves to be unresponsive and performance-challenged, the doors letting people &lt;em&gt;in&lt;/em&gt; will get blocked by the people trying to get &lt;em&gt;out&lt;/em&gt;, and that&apos;s not good for Groovy.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;&lt;em&gt;Groovy&apos;s performance may not be a reason not to use Groovy&lt;/em&gt;&lt;/strong&gt;. Let&apos;s be honest, again: &lt;em&gt;productivity matters&lt;/em&gt;. This is Mort&apos;s principal goal, remember, and there&apos;s nothing wrong with it. Groovy fits into that most natural of places, a scripting language gluing together pieces written in a system language. Perl and Python serve the same purpose for native/C/C++ code, PowerShell does the same (I believe) for .NET code, and it&apos;s high time we see the value in doing that for Java code.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;&lt;em&gt;I believe that the core Groovy team holds performance as a value.&lt;/em&gt;&lt;/strong&gt; I know Graeme and Guillaume, and I believe they believe in the value of performance. I believe that Groovy will get faster over time, as they discover new and better ways to compile Groovy code into bytecode. That doesn&apos;t mean users of Groovy should walk into this exercise with their eyes shut, mind you, but take the whole of this discussion into context as you figure out where Groovy can be used to make your life, as a developer, more productive and powerful. Certain parts of your system are perf-sensitive, and certain parts aren&apos;t. Identify which of those parts are which, and apply Groovy (and other tools) judiciously.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;&lt;em&gt;These discussions are always good, so long as they&apos;re held without rancor.&lt;/em&gt;&lt;/strong&gt; Groovy doesn&apos;t suck. It has warts, but so does everything. Hushing them up or pooh-poohing them just leads to arguments--I encourage the Groovy team to take the criticism of Groovy&apos;s performance the way I intend it in this blog entry: a challenge to be faced and overcome, and not as an indictment of any and all Groovy code everywhere. Because, and I will say this outright, if Groovy&apos;s backers seriously mean Groovy as &quot;a better Java 7&quot;, then they have a large gap to fill.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;Oh, and if some of you wouldn&apos;t mind sticking around to clean up the mess...? Getting beer off the ceiling can be tricky.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Channel 9 Interview with Yours Truly</title>
      <link>http://blogs.newardassociates.com/blog/2008/channel-9-interview-with-yours-truly-is-live.html</link>
      <pubDate>Wed, 9 Apr 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/channel-9-interview-with-yours-truly-is-live.html</guid>
      	<description>
	&lt;p&gt;Over on Channel 9, &lt;a href=&quot;http://channel9.msdn.com/ShowPost.aspx?PostID=394826&quot;&gt;the video interview recorded with me during Lang.NET&lt;/a&gt; has gone live. Have a look, tell me what you think.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The reason for conferences</title>
      <link>http://blogs.newardassociates.com/blog/2008/the-reason-for-conferences.html</link>
      <pubDate>Sat, 15 Mar 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/the-reason-for-conferences.html</guid>
      	<description>
	&lt;p&gt;People have sometimes asked me if it&apos;s really worth it to go to a conference these days, given that so much material is appearing online via blogs, webcasts, online publications and Google. I think the answer is an unqualified &quot;yes&quot; (what else would you expect from a guy who spends a significant part of his life speaking at conferences?), but not necessarily for the reasons you might think.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;A long time ago, Billy Hollis said something very profound to me: &quot;Newbies go to conferences for the technical sessions. Seasoned veterans go to conferences for the people.&quot; At the time, I thought this was Billy&apos;s way of saying that the sessions really weren&apos;t &quot;all that&quot; at most conferences (JavaOne and TechEd come to mind, for example--whatever scheduling gods that think project managers on a particular project make good technical speakers on that subject really needs to be taken out back and shot), and that you&apos;re far better off spending the time networking to improve your social network. Now I think it&apos;s for a different reason. By way of explanation, allow me to recount a brief travel anecdote.&lt;/p&gt; &lt;p&gt;I spend a lot of time on airplanes, as you might expect. Periodically, while staring out the window (trying to rearrange words in my head in order to make them sound coherent for the current email, blog entry, book chapter or article), I will see another commercial aircraft traveling in the same air traffic control lane going the other way. Every time I see it, I&apos;m simply floored at how fast they appear to be going--they usually don&apos;t stay within my visibility for more than a few seconds. &quot;Whoosh&quot; is the first thought that goes through my easily-amused consciousness, and then, &quot;Damn, they&apos;re really &lt;em&gt;moving&lt;/em&gt;.&quot; Then I realize, &quot;Wow--somebody on that plane over there is probably looking at this plane I&apos;m on, and thinking the exact same thing.&quot;&lt;/p&gt; &lt;p&gt;This is why you go to conferences.&lt;/p&gt; &lt;p&gt;In the agile communities, they talk about velocity, the amount of work a team can get done in a particular iteration. But I think teams need to have a sense of their velocity &lt;em&gt;relative to the rest of the industry&lt;/em&gt;, too. It helps put things into perspective. All too often, I find teams that look at me in meetings and conference calls and say, &quot;Surely the rest of the industry isn&apos;t this bad, right?&quot; or &quot;Surely, somebody else has found a solution to this problem by now, right?&quot; or &quot;Please, dear God, &lt;em&gt;tell&lt;/em&gt; me this kind of WTF-style of project management is unique to my company&quot;. While I am certainly happy to answer those questions, the fact of the matter is, at the end of the day they&apos;re still left taking my word for it, and let&apos;s be blunt: my answer can really only cover those companies and/or project teams I&apos;ve had direct contact with. I can certainly tell you what I&apos;ve heard from others (usually at conferences), but even that&apos;s now getting into secondhand information, which to you will be third-hand. (And that, of course, assumes I&apos;m getting it from the source in the first place.)&lt;/p&gt; &lt;p&gt;This isn&apos;t just about project management styles--agile or waterfall or WHISCEY (Why the Hell Isn&apos;t Somebody Coding Everything Yet) or what-have-you--but also about technical trends. Is Ruby taking off? Is Scala becoming more mainstream? Is JRuby worth exploring? Is C++ making a comeback? What are peoples&apos; experiences with Spring 2.5? Has Grails reached a solid level of performance and/or stability? Sure, I&apos;m happy to come to your company, meet with your team, talk about what I&apos;ve seen and heard and done--but sending your developers (and managers, though *ahem* preferably to conferences that aren&apos;t in Las Vegas) to a conference like No Fluff Just Stuff or JavaOne or TechEd or SD West can give them some opportunities to swap stories and gain some important insights about your team&apos;s (and company&apos;s) velocity relative to the rest of the industry.&lt;/p&gt; &lt;p&gt;All of which is to say, yes, Billy was right: it&apos;s about the people. Which means, boss, it&apos;s OK to let the developers go to the parties and maybe sleep in and miss a session or two the next morning.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Mort means productivity</title>
      <link>http://blogs.newardassociates.com/blog/2008/mort-means-productivity.html</link>
      <pubDate>Sat, 15 Mar 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/mort-means-productivity.html</guid>
      	<description>
	&lt;p&gt;Recently, a number of folks in the Java space have taken to openly ridiculing Microsoft&apos;s use of the &amp;quot;Mort&amp;quot; persona, latching on to the idea that Mort is somehow equivalent to &amp;quot;Visual Basic programmer&amp;quot;, which is itself somehow equivalent to &amp;quot;stupid idiot programmer who doesn&apos;t understand what&apos;s going on and just clicks through the wizards&amp;quot;. &lt;!--more--&gt; This would be a mischaracterization, one which I think &lt;a href=&quot;http://www.nikhilk.net/Personas.aspx&quot;&gt;Nikhilik&apos;s definition&lt;/a&gt; helps to clear up:&lt;/p&gt;
&lt;blockquote&gt; &lt;p&gt;Mort, the opportunistic developer, likes to create quick-working solutions for immediate problems and focuses on productivity and learn as needed. Elvis, the pragmatic programmer, likes to create long-lasting solutions addressing the problem domain, and learn while working on the solution. Einstein, the paranoid programmer, likes to create the most efficient solution to a given problem, and typically learn in advance before working on the solution. ....  &lt;p&gt;The description above is only rough summarization of several characteristics collected and documented by our usability folks. During the meeting a program manager on our team applied these personas in the context of server controls rather well (I think), and thought I should share it. Mort would be a developer most comfortable and satisfied if the control could be used as-is and it just worked. Elvis would like to able to customize the control to get the desired behavior through properties and code, or be willing to wire up multiple controls together. Einstein would love to be able to deeply understand the control implementation, and want to be able to extend it to give it different behavior, or go so far as to re-implement it.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Phrased this way, it&apos;s fairly easy to recognize that it&apos;s possible that these are more roles than actual categorizations for programmers as individuals--sometimes you want to know how to create the most efficient solution, and sometimes you just want the damn thing (whatever it is) to get out of your way and let you move on. &lt;/p&gt; &lt;p&gt;Don Box called this latter approach (which is a tendency on the part of &lt;em&gt;all&lt;/em&gt; developers, not just the VB guys) the &lt;em&gt;selective ignorance bit&lt;/em&gt;: none of us have the time or energy or intellectual capacity to know how &lt;em&gt;everything&lt;/em&gt; works, so for certain topics, a programmer flips the selective ignorance bit and just learns enough to make it work. For myself, a lot of the hardware stuff sees that selective ignorance bit flipped on, as well as a lot of the frou-frou UI stuff like graphics and animation and what-not. Sure, I&apos;m curious, and I&apos;d love to know how it works, but frankly, that&apos;s way down the priority list.&lt;/p&gt; &lt;p&gt;If trying to find a quick-working solution to a particular problem means labeling yourself as a Mort, then call me Mort. After all, raise your hand if you didn&apos;t watch a team of C++ guys argue for months over the most efficient way to create a reusable framework for an application that they ended up not shipping because they couldn&apos;t get the framework done in time to actually start work on the application as a whole....&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>URLs as first-class concepts in a language</title>
      <link>http://blogs.newardassociates.com/blog/2008/urls-as-first-class-concepts-in-a-language.html</link>
      <pubDate>Fri, 22 Feb 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/urls-as-first-class-concepts-in-a-language.html</guid>
      	<description>
	&lt;p&gt;While perusing the &lt;a href=&quot;http://www.erights.org/elang/intro/finding-text.html&quot;&gt;E Tutorial&lt;/a&gt;, I noticed something that was simple and powerful all at the same time: &lt;em&gt;URLs as first-class concepts in the language.&lt;/em&gt;&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Or, if you will, URLs as a factory for creating objects. Check out this snippet of E:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;? def poem := &amp;lt;http://www.erights.org/elang/intro/jabberwocky.txt&amp;gt;
# value: &amp;lt;http://www.erights.org/elang/intro/jabberwocky.txt&amp;gt;

? &amp;lt;file:c:/jabbertest&amp;gt;.mkdirs(null);
? &amp;lt;file:c:/jabbertest/jabberwocky.txt&amp;gt;.setText(poem.getText())
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice how the initialization of the &amp;quot;poem&amp;quot; variable is set to what looks like an HTTP URL? This essentially downloads the contents of that file and stores it into poem (in a form I don&apos;t precisely understand yet--I think it&apos;s an object that wraps the contents, but I could be wrong). Then the script uses file URLs to create the local directory (jabbertest) and to create a new file (jabberwocky.txt) and set the contents of that file to be the same as the contents of the stored &amp;quot;poem&amp;quot; object.&lt;/p&gt;
&lt;p&gt;That, my friends, is just slick. It also neatly avoids the whole &amp;quot;how are files and directories and stuff different from URLs&amp;quot; that tends to make doing this same bit of code in Java or C# that much more difficult.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>More language features revisited</title>
      <link>http://blogs.newardassociates.com/blog/2008/more-language-features-revisited.html</link>
      <pubDate>Fri, 22 Feb 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/more-language-features-revisited.html</guid>
      	<description>
	&lt;p&gt;Since we&apos;re examining various aspects of the canonical O-O language (the three principals being C++, Java and C#/VB.NET), let&apos;s take in a review of another recent post, this time on &lt;a href=&quot;http://geekswithblogs.net/chrisfalter/archive/2008/02/15/new-statement-considered-harmful.aspx&quot;&gt;the use of &quot;new&quot;&lt;/a&gt; in said languages.&lt;/p&gt;
&lt;!--more--&gt;
&lt;blockquote&gt; &lt;p&gt;All of us have probably written code like this:  &lt;p&gt;Foo f = new Foo();  &lt;p&gt;And what could be simpler?&amp;nbsp; As long as the logic in the constructor is simple (or better yet, the constructor is empty), it would seem that the simplest code is the best, so just use the constructor.&amp;nbsp; Certainly the MSDN documentation is rife with code that uses public constructors.&amp;nbsp; You can probably find plenty of public constructors used right here on my blog.&amp;nbsp; Why invest the effort in writing (and using) a factory class that will probably never do anything useful, other than call a public constructor?  &lt;p&gt;In his excellent &lt;a href=&quot;http://www.netobjectives.com/webinars/EmergentDesign/EmergentDesign_12_11_2007.mp3&quot;&gt;podcast&lt;/a&gt; entitled &quot;Emergent Design: The Evolutionary Nature of Software Development,&quot; Scott Bain of Net Objectives nevertheless makes a strong case against the routine use of public constructors.&amp;nbsp; The problem, notes Scott, is that the use of a public constructor ties the calling code to the implementation of Foo as a concrete class.&amp;nbsp; But suppose that you later discover that there need to be many subtypes of Foo, and Foo should therefore be an abstract class instead of a concrete class--what then?&amp;nbsp; You&apos;ve got a big problem, that&apos;s what; a lot of client code that has been making use of Foo&apos;s public constructor suddenly becomes invalid.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I just love it when people rediscover advice that they could have had much earlier, had they only been aware of the prior art in the field. I refer the curious C#/VB.NET developer to the book &lt;em&gt;Effective Java&lt;/em&gt;, by Joshua Bloch, in which Item 1 states, &quot;Consider providing static factory methods instead of constructors&quot;. Quoting from said book, we see:  &lt;blockquote&gt; &lt;p&gt;&lt;strong&gt;One advantage of static factory methods is that, unlike constructors, they have names.&lt;/strong&gt; If the parameters to a constructor do not, in and of themselves, describe the object being returned, a static factory with a well-chosen name can make a class easier to user and the resulting client code easier to read. ...  &lt;p&gt;&lt;strong&gt;A second advantage of static factory methods is that, unlike constructors, they are not required to create a new object each time they&apos;re invoked.&lt;/strong&gt; This allows immutable classes (Item 13) to use preconstructed instances or to cache instances as they&apos;re constructed and to dispense these instances repeatedly so as to avoid creating unnecessary duplicate values. ...  &lt;p&gt;&lt;strong&gt;A third advantage of static factory methods is that, unlike constructors, they can return an object of any subtype of their return type.&lt;/strong&gt; This gives you great flexibility in choosing the class of the returned object. ...  &lt;p&gt;&lt;strong&gt;The main disadvantage of static factory methods is that classes without public or protected constructors cannot be subclassed.&lt;/strong&gt; The same is true for nonpublic classes returned by public static factories.  &lt;p&gt;&lt;strong&gt;A second disadvantage of static factory methods is that they are not readily distinguishable from other static methods.&lt;/strong&gt; They do not stand out in API documentation the way that constructors do.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;C# and VB.NET developers are encouraged to read the book to discover about 30 or so other nuggets of wisdom that are directly applicable to the .NET framework. Note that Josh is in the process, this very month, of revising the book for rerelease as a second edition, taking into account the wide variety of changes that have taken place in the Java language since EJ&apos;s initial release.  &lt;p&gt;Meanwhile....  &lt;p&gt;One thing that&apos;s been nagging at me is how I think Java and C# missed the boat in respect to the various ways we&apos;d like to construct objects. The presumption was always that allocation and initialization would (a) always take place at the same time, and (b) always take place in the same manner--the underlying system would allocate the memory, the object would be laid out in this newly-minted chunk of heap, and your constructor would then initialize the contents. Neither assumption can be taken to be true, as we&apos;ve seen over the years; the object may need to come from pre-existing storage (a la the object cache), or the object may need to be a derived type (a la the covariant return Josh mentions in #3 advantage above), or in some cases you want to mint the object from an entirely different part of the process.  &lt;p&gt;C++ actually had an advantage over C# and Java here, in that you could overload operator new() for a class (which then meant you had to overload operator delete(), and oh-by-the-way don&apos;t forget to overload array new, that is, operator new[]() and its corresponding twin, array delete, operator delete[](), which was a bit of a pain) to gain better control over both allocation and initialization, to a degree. Initially we always used it to control allocation--the idea being one would create a class-specific allocator, on the grounds that knowing some of the assumptions of the class, such as its size, would allow you to write faster allocation routines for it. But one of the rarely-used features of operator new() was that it could take additional parameters, using a truly obscure syntactic corner of C++:  &lt;blockquote&gt; &lt;div style=&quot;border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &apos;Courier New&apos;, courier, monospace; background-color: #f4f4f4&quot;&gt; &lt;div style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &apos;Courier New&apos;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &apos;Courier New&apos;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #606060&quot;&gt;   1:&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;void&lt;/span&gt;* &lt;span style=&quot;color: #0000ff&quot;&gt;operator&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt;(size_t s, &lt;span style=&quot;color: #0000ff&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;string&lt;/span&gt;&amp;amp; message)&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &apos;Courier New&apos;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #606060&quot;&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &apos;Courier New&apos;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #606060&quot;&gt;   3:&lt;/span&gt;     cout &amp;lt;&amp;lt; &lt;span style=&quot;color: #006080&quot;&gt;&quot;Operator new sez &quot;&lt;/span&gt; &amp;lt;&amp;lt; message &amp;lt;&amp;lt; endl;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &apos;Courier New&apos;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #606060&quot;&gt;   4:&lt;/span&gt;         &lt;span style=&quot;color: #008000&quot;&gt;// allocate s bytes and return; Foo ctor will be invoked automagically&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &apos;Courier New&apos;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #606060&quot;&gt;   5:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &apos;Courier New&apos;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #606060&quot;&gt;   6:&lt;/span&gt; Foo* newFoo = &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; (&lt;span style=&quot;color: #006080&quot;&gt;&quot;Howdy, world!&quot;&lt;/span&gt;) Foo();&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Officially, one such overloaded operator was recognized, the &lt;em&gt;&lt;a href=&quot;http://www.glenmccl.com/tip_025.htm&quot;&gt;placement new&lt;/a&gt;&lt;/em&gt; operator, which took a void* as a parameter, indicating the exact location in which your object was to be allocated and thus laid down. This meant that C++ developers could allocate from some other part of the process (including &lt;em&gt;shudder&lt;/em&gt; a pointer they&apos;d made up out of thin air) and drop the initialized object right there. While useful in its own right, placement new opened up a whole new world of construction options to the C++ developer that we never really took advantage of, since now you could pass parameters to the construction process &lt;em&gt;without involving the constructor&lt;/em&gt;. 
&lt;p&gt;That&apos;s kind of nifty, in an obscure and slightly terrifying fashion. One thought I&apos;d always had was that it would be cool if a C++ O/R-M overloaded operator new() for database-bound objects to indicate which database connection to use during construction: 
&lt;blockquote&gt;
&lt;div style=&quot;border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &apos;Courier New&apos;, courier, monospace; background-color: #f4f4f4&quot;&gt;
&lt;div style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &apos;Courier New&apos;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &apos;Courier New&apos;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #606060&quot;&gt;   1:&lt;/span&gt; DBConnection conn;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &apos;Courier New&apos;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #606060&quot;&gt;   2:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &apos;Courier New&apos;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #606060&quot;&gt;   3:&lt;/span&gt; Person* newFoo = &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; (conn) Person(&lt;span style=&quot;color: #006080&quot;&gt;&quot;Ted&quot;&lt;/span&gt;, &lt;span style=&quot;color: #006080&quot;&gt;&quot;Neward&quot;&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;font face=&quot;Courier New&quot;&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Of course, such syntax has the immediate drawback of &lt;a href=&quot;http://www.osnews.com/images/comics/wtfm.jpg&quot;&gt;eliciting a chorus of &quot;WTF?!?&quot; at the next code review&lt;/a&gt;, but still.... 
&lt;p&gt;Meanwhile, other languages choose to view new as one of those nasty static methods Gilad dislikes so much, Ruby and Smalltalk being two of them. That is to say, construction now basically calls into a static method on a class, which has the nice effect of keeping the number of &quot;special&quot; parts of the language to a minimum (since now &quot;new&quot; is just a method, not a keyword), makes it easier to have different-yet-similar names to represent slightly different concepts (&quot;create&quot; vs &quot;new&quot; vs &quot;fetch&quot; vs &quot;allocate&quot;, and so on) sitting side by side, and helps eliminate Josh&apos;s second disadvantage above. I&apos;m not certain how exactly this could eliminate Josh&apos;s first disadvantage (that of inheritance and inaccessible constructors), but it&apos;s not entirely unimaginable that the language would have a certain amount of incestuous knowledge here to be able to reach those static method (constructors) in the same way it does currently. 
&lt;p&gt;(It actually works better if they aren&apos;t static methods at all, but instance methods on class objects, to which the language automatically defers when it sees a &quot;classname.new&quot;; that is, when it sees 
&lt;blockquote&gt;
&lt;div style=&quot;border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &apos;Courier New&apos;, courier, monospace; height: 35px; background-color: #f4f4f4&quot;&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &apos;Courier New&apos;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;Person ann = Person.&lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt;(&lt;span style=&quot;color: #006080&quot;&gt;&quot;Ann&quot;&lt;/span&gt;, &lt;span style=&quot;color: #006080&quot;&gt;&quot;Sheriff&quot;&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;the language automatically changes this to read: 
&lt;blockquote&gt;
&lt;div style=&quot;border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &apos;Courier New&apos;, courier, monospace; height: 35px; background-color: #f4f4f4&quot;&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &apos;Courier New&apos;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;Person ann = Person.&lt;span style=&quot;color: #0000ff&quot;&gt;class&lt;/span&gt;.&lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt;(&lt;span style=&quot;color: #006080&quot;&gt;&quot;Ann&quot;&lt;/span&gt;, &lt;span style=&quot;color: #006080&quot;&gt;&quot;Sheriff&quot;&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;which would be eminently doable in Java, were class objects available for modification/definition somehow. In a language built on top of the JVM or CLR, the class object would be a standalone singleton, a la &quot;object&quot; definitions in Scala.)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Fallacies Remain...</title>
      <link>http://blogs.newardassociates.com/blog/2008/the-fallacies-remain.html</link>
      <pubDate>Tue, 19 Feb 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/the-fallacies-remain.html</guid>
      	<description>
	&lt;!--more--&gt;
&lt;p&gt;Just recently, I got this bit in an email from the &lt;a href=&quot;http://reddevnews.com&quot;&gt;Redmond Developer News&lt;/a&gt; ezine:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;TWO IF BY SEA &lt;p&gt;In the course of just over a week starting on Jan. 30, a total of five undersea data cables linking Europe, Africa and the Middle East were damaged or disrupted. The first two cables to be lost link Europe with Egypt and terminate near the Port of Alexandria.  &lt;p&gt;&lt;a href=&quot;http://reddevnews.com/columns/article.aspx?editorialsid=2502&quot;&gt;http://reddevnews.com/columns/article.aspx?editorialsid=2502&lt;/a&gt; &lt;p&gt;Early speculation placed the blame on ship anchors that might have dragged across the sea floor during heavy weather. But the subsequent loss of cables in the Persian Gulf and the Mediterranean has produced a chilling numbers game. Someone, it seems, may be trying to sabotage the global network. &lt;p&gt;It&apos;s a conclusion that came up at a recent International Telecommunication Union (ITU) press conference. According to an Associated Press report, ITU head of development Sami al-Murshed isn&apos;t ready to &quot;rule out that a deliberate act of sabotage caused the damage to the undersea cables over two weeks ago.&quot; &lt;p&gt;&lt;a href=&quot;http://tinyurl.com/3bjtdg&quot;&gt;http://tinyurl.com/3bjtdg&lt;/a&gt; &lt;p&gt;You think? &lt;p&gt;In just seven or eight days, five undersea cables were disrupted.  &lt;p&gt;Five. All of them serving or connecting to the Middle East. And thus far, only one cable cut -- linking Oman and the United Arab Emirates -- has been identified as accidental, caused by a dragging ship anchor. &lt;p&gt;So what does it mean for developers? A lot, actually. Because it means that the coming wave of service-enabled applications needs to take into account the fact that the cloud is, literally, under attack. &lt;p&gt;This isn&apos;t new. For as long as the Internet has been around, concerns about attacks on the network have centered on threats posed by things like distributed denial of service (DDOS) and other network-borne attacks. Twice -- once in 2002 and again in 2007 -- DDOS attacks have targeted the 13 DNS root servers, threatening to disrupt the Internet.  &lt;p&gt;But assaults on the remote physical infrastructure of the global network are especially concerning. These cables lie hundreds or even thousands of feet beneath the surface. This wasn&apos;t a script-kiddie kicking off an ill-advised DOS attack on a server. This was almost certainly a sophisticated, well-planned, well-financed and well-thought-out effort to cut off an entire section of the world from the global Internet. &lt;p&gt;Clearly, efforts need to be made to ensure that the intercontinental cable infrastructure of the Internet is hardened. Redundant, geographically dispersed links, with plenty of excess bandwidth, are a good start. &lt;p&gt;But development planners need to do their part, as well. Web-based applications shouldn&apos;t be crafted with the expectation of limitless bandwidth. Services and apps must be crafted so that they can fail gracefully, shift to lower-bandwidth media (such as satellite) and provide priority to business-critical operations. In short, your critical cloud-reliant apps must continue to work, when almost nothing else will. &lt;p&gt;And all this, I might add, as the industry prepares to welcome the second generation of rich Internet application tools and frameworks.  &lt;p&gt;Silverlight 2.0 will debut at MIX08 next month. Adobe is upping the ante with its latest offerings. Developers will enjoy a major step up in their ability to craft enriched, Web-entangled applications and environments. &lt;p&gt;But as you make your plans and write your code, remember this one thing: The people, organization or government that most likely sliced those four or five cables in the Mediterranean and Persian Gulf -- they can do it again.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;There&apos;s a couple of things to consider here, aside from the geopolitical ramifications of a concerted attack on the global IT infrastructure (which does more to damage corporations and the economy than it does to disrupt military communications, which to my understanding are mostly satellite-based).&lt;/p&gt; &lt;p&gt;First, this attack on the global infrastructure raises a &lt;em&gt;huge&lt;/em&gt; issue with respect to outsourcing--if you lose touch with your development staff for a day, a week, a month (just how long &lt;em&gt;does&lt;/em&gt; it take to lay down new trunk cable, anyway?), what sort of chaos is this going to strike with your project schedule? In &lt;em&gt;The World is Flat&lt;/em&gt;, Friedman mentions that a couple of fast-food restaurants have outsourced the drive-thru--you drive up to the speaker, and as you place your order, you&apos;re talking to somebody half a world way who&apos;s punching it into a computer that&apos;s flashing the data back to the fast-food join in question for harvesting (it&apos;s not like they &lt;em&gt;make&lt;/em&gt; the food when you order it, just harvest it from the fields of pre-cooked burgers ripening under infrared lamps in the back) and disbursement as you pull forward the remaining fifty feet to the first window.&lt;/p&gt; &lt;p&gt;The ludicrousness of this arrangement notwithstanding, this means that the local fast-food joint is now dependent on the global IT infrastructure in the same way that your ERP system is. Aside from the obvious &quot;geek attraction&quot; to a setup like this, I find it fascinating that at no point did somebody stand up and yell out, &quot;What happened to &lt;em&gt;minimizing&lt;/em&gt; the risks?&quot; Effective project development relies heavily on the ability to touch base with the customer every so often to ensure things are progressing in the way the customer was anticipating. When the development team is one ocean and two continents away in one direction, or one ocean and a whole pile of islands away in the other direction, or even just a few states over, that vital communication link is now at the mercy of every single IT node in between them and you.&lt;/p&gt; &lt;p&gt;We can make huge strides, but at the end of the day, the huge distances involved can only be &quot;fractionalized&quot;, never eliminated.&lt;/p&gt; &lt;p&gt;Second, as Desmond points out, this has a huge impact on the design of applications that are assuming a 100% or 99.9% Internet uptime. Yes, I&apos;m looking at you, GMail and Google Calendar and the other so-called &quot;next-generation Internet applications&quot; based on technologies like AJAX. (I categorically refuse to call them &quot;Web 2.0&quot; applications--there is no such thing as &quot;Web 2.0&quot;.) As much as we keep looking to the future for an &quot;always-on&quot; networking infrastructure, the more we delude ourselves to the practical realities of life: &lt;em&gt;there is no such thing as &quot;always-on&quot; infrastructure&lt;/em&gt;. Networking or otherwise.&lt;/p&gt; &lt;p&gt;I know this personally, since last year here in Redmond, some stronger-than-normal winter storms knocked down a whole slew of power lines and left my house without electricity for a week. To &lt;em&gt;very&lt;/em&gt; quickly discover how much of modern Western life depends on &quot;always-on&quot; assumptions, go without power to the house for a week. We were fortunate--parts of Redmond and nearby neighborhoods got power back within 24 hours, so if I needed to recharge the laptop or get online to keep doing business, much less get a hot meal or just find a place where it was warm, it meant a quick trip down to the local strip mall where a restaurant with WiFi (Canyon&apos;s, for those of you that visit Redmond) kept me going. For others in Redmond, the power outage meant a brief vacation down at the Redmond Town Center Marriott, where power was available pretty much within an hour or two of its disruption.&lt;/p&gt; &lt;p&gt;The First Fallacy of Enterprise Systems states that &quot;The network is reliable&quot;. The network is only as reliable as the infrastructure around it, and not just the infrastructure that your company lays down from your workstation to the proxy or gateway or cable modem. Take a &quot;traceroute&quot; reading from your desktop machine to the server on which your application is running--if it&apos;s not physically in the building as you, then you&apos;re probably looking at 20 - 30 &quot;hops&quot; before it reaches the server. Every single one of those &quot;hops&quot; is a potential point of failure. Granted, the architecture of TCP/IP suggests that we should be able to route around any localized points of failure, but how many of those points are, in fact, to your world view, completely unroutable? If your gateway machine goes down, how does TCP/IP try to route around that? If your ISP gets hammered by a Denial-of-Service attack, how do clients reach the server?&lt;/p&gt; &lt;p&gt;If we cannot guarantee 100% uptime for electricity, something we&apos;ve had close to a century to perfect, then how can you assume similar kinds of guarantees for network availability? And before any of you point out that &quot;Hey, most of the time, it just works so why worry about it?&quot;, I humbly suggest you walk into your Network Operations Center and ask the helpful IT people to point out the Uninterruptible Power Supplies that fuel the servers there &quot;just in case&quot;. &lt;/p&gt; &lt;p&gt;When they in turn ask you to point out the &quot;just in case&quot; infrastructure around the application, what will you say?&lt;/p&gt; &lt;p&gt;Remember, the Fallacies only bite you when you ignore them:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;1) The network is reliable &lt;p&gt;2) Latency is zero &lt;p&gt;3) Bandwidth is infinite &lt;p&gt;4) The network is secure &lt;p&gt;5) Topology doesn&apos;t change &lt;p&gt;6) There is one administrator &lt;p&gt;7) Transport cost is zero &lt;p&gt;8) The network is homogeneous &lt;p&gt;9) The system is monolithic &lt;p&gt;10) The system is finished&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Every project needs, at some point, to have somebody stand up in the room and shout out, &quot;But how do we &lt;em&gt;minimize&lt;/em&gt; the risks?&quot; If this is truly a &quot;mission-critical&quot; application, then somebody needs the responsibility of cooking up &quot;What if?&quot; scenarios and answers, even if the answer is to say, &quot;There&apos;s not much we can reasonably do in that situation, so we&apos;ll just accept that the company shuts its doors in that case&quot;.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Why we need both static and dynamic in the same language</title>
      <link>http://blogs.newardassociates.com/blog/2008/why-we-need-both-static-and-dynamic-in-the-same-language.html</link>
      <pubDate>Mon, 18 Feb 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/why-we-need-both-static-and-dynamic-in-the-same-language.html</guid>
      	<description>
	&lt;p&gt;Stu &lt;a href=&quot;http://www.relevancellc.com/2008/2/12/how-should-metaclass-work&quot;&gt;demonstrates&lt;/a&gt; one of the basic problems with an all-dynamic language: &quot;I just spent an hour figuring out why some carefully-tested code went no-op after adding RSpec to a project.&quot; As much as I berate Stu at times (both in person and in blog), the fact is, I deeply respect and admire his programming skill, and if he can lose an hour to something that (I submit for your consideration) could have been caught by a static analysis tool fairly easily, then clearly that was a wasted hour of Stu&apos;s life. Worse, the problem is not yet solved, since now he has to make a hard choice about which definition to use, or else find a way to hack around the two definitions and create a third. Or perhaps something even uglier than this....&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;And this presumes that all developers using Ruby will have Stu&apos;s skill and his sense of responsibility when coming up with the solution. Asking that of all programmers across the globe is simply too much.&lt;/p&gt; &lt;p&gt;But clearly we cannot simply abandon the power of the dynamic language, either. &lt;a href=&quot;http://www.relevancellc.com/2008/2/11/why-they-fear-the-meta&quot;&gt;Quoting again from the same source&lt;/a&gt;, Stu points out the very reason why dynamic languages are so powerful: &quot;Once you start treating code as data, the elegance of your code is dependent on your skill. You cannot hide behind the limitations of your programming language anymore, because there aren&apos;t any.&quot;&lt;/p&gt; &lt;p&gt;What&apos;s a language designer left to do?&lt;/p&gt; &lt;p&gt;Choose both, of course.&lt;/p&gt; &lt;p&gt;The more I think about it, the more I think &lt;a href=&quot;http://cobra-language.com/&quot;&gt;Cobra&lt;/a&gt; (and other languages) has it right: a programming language should have &lt;em&gt;both&lt;/em&gt; static and dynamic features within it, simultaneously. This is the first &quot;modern&quot; language I&apos;ve seen come along that espouses the &quot;static when you can, dynamic when you want&quot; principle as a first-class concept. Even at that, I imagine that there&apos;s much more that could be done than what Cobra espouses. Imagine combining the power of Scala&apos;s type inferencing system with the flexibility of a Groovy or Ruby.&lt;/p&gt; &lt;p&gt;Shivers.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>What about Context</title>
      <link>http://blogs.newardassociates.com/blog/2008/what-about-context.html</link>
      <pubDate>Tue, 29 Jan 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/what-about-context.html</guid>
      	<description>
	&lt;p&gt;Reclaiming my Context pattern writeup from an ancient blog system.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Andrew Wild emails me:  &lt;blockquote&gt; &lt;p&gt;I vaguely remember one of your blog posts in which you went into a bit of an exposition of &apos;context&apos;. &lt;br&gt;Did you ever come up with anything solid or did you wind up talking yourself in self-referential circles? &lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Because that post was actually a part of the old weblog hosted at neward.net, I decided to repost it and the followup discussion to this blog in order to make it available again, although the WayBack Machine also has &lt;a href=&quot;http://web.archive.org/web/20040824184000/http://www.neward.net/ted/weblog/index.jsp?date=20040823&quot;&gt;it&lt;/a&gt; and its &lt;a href=&quot;http://web.archive.org/web/20041010214204/www.neward.net/ted/weblog/index.jsp?date=20040825&quot;&gt;followup&lt;/a&gt; tucked away.
&lt;hr /&gt;
&lt;h2&gt;Context&lt;/h2&gt;
&lt;p&gt;I&apos;m not normally one to promote myself as a &quot;pattern miner&quot;--those who &quot;discover&quot; patterns in the software systems around us--since I don&apos;t think I have that much experience yet, but one particular design approach, &quot;patlet&quot;, if you will, has been showing up with frightening regularity (such as Sandy Khaund&apos;s mention of EDRA, the format of a SOAP 1.2 message, which in itself forms a Context, and more), and yet hasn&apos;t, to my knowledge, been documented anywhere, that I thought I&apos;d take a stab at documenting it and see what comes out of it. Treat this as a alpha, at best, and be brutal in your feedback.
&lt;h3&gt;Context (Object Behavioral)&lt;/h3&gt;
&lt;p&gt;Define a wrapper object that encapsulates all aspects of an operation, including details that may not be directly related to that operation. Context allows an object or graph of objects to be handled in a single logical unit, as part of a logical unit of work.
&lt;h3&gt;Motivation&lt;/h3&gt;
&lt;p&gt;Frequently an operation, which consists fundamentally of inputs and a generated output, requires additional information by which to carry out its work. In some cases, this consists of out-of-band information, such as historical data, previous values, or quality-of-service data, which needs to travel with the operation regardless of its execution path within the system. The desire is to decouple the various participants working with the operation from having to know everything that is being &quot;carried around&quot; as part of the operation.  &lt;p&gt;In many cases, a Context will be what is passed around between the various actors in a Chain of Responsibility (223).
&lt;h3&gt;Consequences&lt;/h3&gt; &lt;p&gt;I&apos;m not sure yet.&lt;br&gt; &lt;h3&gt;Known Uses&lt;/h3&gt; &lt;p&gt;Several distributed communication toolkits make use of Context or something very similar to it. COM+, for example, uses the notion of Context as a interception barrier, allowing for a tightly-coupled graph of objects to be treated as an atomic unit, synchronizing multi-threaded calls into the context, also called an apartment. Transactions are traced as they flow through different parts of the system, such that each Context knows the transaction ID it was associated with and can allow that same transaction ID (the causality) to continue to flow through, thus avoiding self-deadlock.  &lt;p&gt;Web Services also make use of Context, using the SOAP Message format as a mechanism in which out-of-band information, such as security headers and addressing information, can be conveyed without &quot;polluting&quot; the data stored in the message itself. WS-Security, WS-Transaction, WS-Routing, among others, are all examples of specifications that simply add headers to SOAP messages, so that other &quot;processing nodes&quot; in the Web service call chain can provide the appropriate semantics.  &lt;p&gt;(I know there are others, but nothing&apos;s coming to mind at the moment.)
&lt;h3&gt;Related Patterns&lt;/h3&gt;
&lt;p&gt;Context is often the object passed along a Chain of Responsibility; each ConcreteHandler in the Chain examines the Context and potentially modifies it as necessary before handing it along to the next Handler in the Chain.
&lt;p&gt;Context is also used as a wrapper for a Command object, providing additional information beyond the Command itself. The key difference between the two is that Context provides out-of-band information that the Command object may not even know is there, for processing by others around the Command. &lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;The followup looked like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Wow--lots of you have posted comments about Context. Let&apos;s address some of them and see what comes up in the second iteration:  &lt;ul&gt; &lt;li&gt; &lt;p&gt;Michael Earls wrote:  &lt;blockquote&gt;Very timely. I&apos;m building a system right now that fits this pattern. We spent about five minutes determining what to call &quot;it&quot; (the little &quot;black box&quot; that holds the core command, entity, and metadata information). We settled on &quot;nugget&quot;. Now there&apos;s prior art I can refer to. I&apos;m using Context with WSE 2.0 and SOAP extensions for the pipeline in exactly the way you describe. Nice.&lt;/blockquote&gt;and  &lt;blockquote&gt;Another Related Pattern: Additionally, the Context may also be an container/extension/augmentation/decoration on the UnitOfWork (???).&lt;/blockquote&gt;I suspect you&apos;re right--Context can be used to hold the information surrounding a UnitOfWork, including the transaction it&apos;s bound to (if the transaction is already opened). This is somewhat similar to what the MTS implementation does, if I&apos;m not mistaken. &lt;p&gt;&lt;/p&gt; &lt;li&gt; &lt;p&gt;Kris wrote:  &lt;blockquote&gt;The HTTP pipeline in ASP.NET comes to mind, with the HttpContext being passed through for various things like session state, security, etc. One possible side effect that I can see (hopefully you can drop some thoughts on this one), is how to manage dependencies between the chain, as well as order of invocation of chain elements. The MS PAG stuff I believe talks about this somewhat with the Pipelines &amp;amp; Filters pattern, but I&apos;d love to hear your thoughts as well.&lt;/blockquote&gt;The PAG stuff (Sandy Khaund&apos;s post) was part of what triggered this post in the first place, but I want to be careful not to rely too much on Microsoft prior art (WSE, Shadowfax, HttpContext, COM/MTS/COM+) since in many cases those systems were designed by people who had worked together before and/or shared ideas. The Rule of Three says that the pattern needs to be discovered &quot;independently&quot; of any other system, although with Google around these days that&apos;s becoming harder and harder to do. :-) As to managing dependencies between the chain, I think that&apos;s out of scope to Context itself--in fact, that raises another interesting pattern relationship, in that Context can be the thing operated upon by a Blackboard [POSA1 71]. Context doesn&apos;t care who interacts with it when, IMHO. &lt;p&gt;&lt;/p&gt; &lt;li&gt; &lt;p&gt;Dan Moore wrote:  &lt;blockquote&gt;Another context &lt;i&gt;(pun intended? --TKN)&lt;/i&gt; I&apos;ve read a lot about is the transactional context used in enterprise transaction processing systems. This entity contains information about the transaction, needed by various participants.&lt;/blockquote&gt;Yep. Read on (Dan Malks&apos; post). &lt;p&gt;&lt;/p&gt; &lt;li&gt; &lt;p&gt;Dan Malks wrote:  &lt;blockquote&gt;Hi Ted, Good start with your pattern writeup :) We document &quot;Context Object&quot; in our pattern catalog in our book &quot;Core J2EE Patterns&quot; 2nd ed., Alur, Crupi, Malks. I hope you&apos;ll find some interesting content in our writeup, so please feel free to have a look and let me know what you think. Thanks, Dan Malks&lt;/blockquote&gt;Thanks, Dan. As soon as you posted I ran off and grabbed my copy of your book, and looked it up, and while I think there&apos;s definitely some overlap (boy what I wouldn&apos;t give to workshop this thing at PLOP this year), Context Object, given the protocol-independence focus that you guys gave it in Core J2EE, looks like a potential combination of Context and Chain of Responsibility. I wanted to elevate Context out of just the Chain of Responsibility usage, though, to create something that isn&apos;t &quot;part of&quot; another pattern--I&apos;ll leave it to you guys to decide whether Context makes sense in that regard. &lt;p&gt;&lt;/p&gt; &lt;li&gt; &lt;p&gt;Mark Levison wrote:  &lt;blockquote&gt;On related patterns: Context is what is passed into a Flyweight (alias Glyph&apos;s). We&apos;ve been using Context for over two years on current project.&lt;/blockquote&gt;Really? Wow; I never would have considered that, but of course it makes sense when you describe it that way. I&apos;m not really keeping track, but I think we&apos;ve reached the Rule of Three.

	</description>
    </item>
    <item>
      <title>Can Dynamic Languages Scale? Yes</title>
      <link>http://blogs.newardassociates.com/blog/2008/can-dynamic-languages-scale.html</link>
      <pubDate>Wed, 23 Jan 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/can-dynamic-languages-scale.html</guid>
      	<description>
	&lt;p&gt;The recent &lt;a href=&quot;http://blogs.cnet.com/8301-13505_1-9847739-16.html?part=rss&amp;amp;subj=news&amp;amp;tag=2547-1_3-0-20&quot;&gt;&amp;quot;failure&amp;quot; of the Chandler PIM project&lt;/a&gt; generated the question, &lt;a href=&quot;http://www.theserverside.com/news/thread.tss?thread_id=48180&quot;&gt;&amp;quot;Can Dynamic Languages Scale?&amp;quot;&lt;/a&gt; on TheServerSide, and, as is all too typical these days, it turned into a &amp;quot;You suck&amp;quot;/&amp;quot;No you suck&amp;quot; flamefest between a couple of posters to the site.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;I now make the perhaps vain attempt to address the question meaningfully.&lt;/p&gt;
&lt;h3&gt;What do you mean by &amp;quot;scale&amp;quot;?&lt;/h3&gt;
&lt;p&gt;There&apos;s an implicit problem with using the word &amp;quot;scale&amp;quot; here, in that we can think of a language scaling in one of two very orthogonal directions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Size of project, as in lines-of-code (LOC)&lt;/li&gt;
&lt;li&gt;Capacity handling, as in &amp;quot;it needs to scale to 100,000 requests per second&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Part of the problem I think that appears on the TSS thread is that the posters never really clearly delineate the differences between these two. Assembly language can scale(2), but it can&apos;t really scale(1) very well. Most people believe that C scales(2) well, but doesn&apos;t scale(1) well. C++ scores better on scale(1), and usually does well on scale(2), but you get into all that icky memory-management stuff. (Unless, of course, you&apos;re using the Boehm GC implementation, but that&apos;s another topic entirely.)
&lt;p&gt;Scale(1) is a measurement of a language&apos;s ability to extend or enhance the &lt;em&gt;complexity budget&lt;/em&gt; of a project. For those who&apos;ve not heard the term &amp;quot;complexity budget&amp;quot;, I heard it first from Mike Clark (though I can&apos;t find a citation for it via Google--if anybody&apos;s got one, holler and I&apos;ll slip it in here), he of Pragmatic Project Automation fame, and it&apos;s essentially a statement that says &amp;quot;Humans can only deal with a fixed amount of complexity in their heads. Therefore, every project has a fixed complexity budget, and the more you spend on infrastructure and tools, the less you have to spend on the actual business logic.&amp;quot; In many ways, this is a reflection of the ability of a language or tool to raise the level of abstraction--when projects began to exceed the abstraction level of assembly, for example, we moved to higher-level languages like C to help hide some of the complexity and let us spend more of the project&apos;s complexity budget on the program, and not with figuring out which register needed to have the value of the interrupt to be invoked. This same argument can be seen in the argument against EJB in favor of Spring: too much of the complexity budget was spent in getting the details of the EJB beans correct, and Spring reduced that amount and gave us more room to work with. Now, this argument is at the core of the Ruby/Rails-vs-Java/JEE debate, and implicitly it&apos;s obviously there in the middle of the room in the whole discussion over Chandler.&lt;/p&gt;
&lt;p&gt;Scale(2) is an equally important measurement, since a project that cannot handle the expected user load during peak usage times will have effectively failed just as surely as if the project had never shipped in the first place. Part of this will be reflected in not just the language used but also the tools and libraries that are part of the overall software footprint, but choice of language can obviously have a major impact here: Erlang is being tossed about as a good choice for high-scale systems because of its intrinsic Actors-based model for concurrent processing, for example.&lt;/p&gt;
&lt;p&gt;Both of these get tossed back and forth rather carelessly during this debate, usually along the following lines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Pro-Java (and pro-.NET, though they haven&apos;t gotten into this particular debate so much as the Java guys have) adherents argue that a dynamic language cannot scale(1) because of the lack of type-safety commonly found in dynamic languages. Since the compiler is not there to methodically ensure that parameters obey a certain type contract, that objects are not asked to execute methods they couldn&apos;t possibly satisfy, and so on. In essence, strongly-typed languages are theorem provers, in that they take the assertion (by the programmer) that this program is type-correct, and validate that. This means less work for the programmer, as an automated tool now runs through a series of tests that the programmer doesn&apos;t have to write by hand; as one contributor to the TSS thread &lt;a href=&quot;http://www.theserverside.com/news/thread.tss?thread_id=48180#245674&quot;&gt;put it&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;With static languages like Java, we get a select subset of code tests, with 100% code coverage, every time we compile. We get those tests for &amp;quot;free&amp;quot;. The price we pay for those &amp;quot;free&amp;quot; tests is static typing, which certainly has hidden costs.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Note that this argument frequently derails into the world of IDE support and refactoring (as its witnessed on the TSS thread), pointing out that Eclipse and IntelliJ provide powerful automated refactoring support that is widely believed to be impossible on dynamic language platforms.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pro-Java adherents also argue that dynamic languages cannot scale(2) as well as Java can, because those languages are built on top of their own runtimes, which are arguably vastly inferior to the engineering effort that goes into the garbage collection facilities found in the JVM Hotspot or CLR implementations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pro-Ruby (and pro-Python, though again they&apos;re not in the frame of this argument quite so much) adherents argue that the dynamic nature of these languages means less work during the creation and maintenance of the codebase, resulting in a far fewer lines-of-code count than one would have with a more verbose language like Java, thus implicitly improving the scale(1) of a dynamic language.&lt;br /&gt;
On the subject of IDE refactoring, scripting language proponents point out that the original refactoring browser was an implementation built for (and into) Smalltalk, one of the world&apos;s first dynamic languages.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pro-Ruby adherents also point out that there are plenty of web applications and web sites that scale(2) &amp;quot;well enough&amp;quot; on top of the MRV (Matz&apos;s Ruby VM?) interpreter that comes &amp;quot;out of the box&amp;quot; with Ruby, despite the widely-described fact that MRV Ruby Threads are what Java used to call &amp;quot;green threads&amp;quot;, where the interpreter manages thread scheduling and management entirely on its own, effectively using one native thread underneath.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Both sides tend to get caught up in &amp;quot;you don&apos;t know as much as me about this&amp;quot; kinds of arguments as well, essentially relying on the idea that the less you&apos;ve coded in a language, the less you could possibly know about that language, and the more you&apos;ve coded in a language, the more knowledgeable you must be. Both positions are fallacies: I know a great deal about D, even though I&apos;ve barely written a thousand lines of code in it, because D inherits much of its feature set and linguistic expression from both Java and C++. Am I a certified expert in it? Hardly--there are likely dozens of D idioms that I don&apos;t yet know, and certainly haven&apos;t elevated to the state of intuitive use, and those will come as I write more lines of D code. But that doesn&apos;t mean I don&apos;t already have a deep understanding of how to design D programs, since it fundamentally remains, as its genealogical roots imply, an object-oriented language. Similar rationale holds for Ruby and Python and ECMAScript, as well as for languages like Haskell, ML, Prolog, Scala, F#, and so on: the more you know about &amp;quot;neighboring&amp;quot; languages on the linguistic geography, the more you know about that language in particular. If two of you are learning Ruby, and you&apos;re a Python programmer, you already have a leg up on the guy who&apos;s never left C++. Along the other end of this continuum, the programmer who&apos;s written half a million lines of C++ code and still never uses the &amp;quot;private&amp;quot; keyword is &lt;em&gt;not&lt;/em&gt; an expert C++ programmer, no matter what his checkin metrics claim. (And believe me, I&apos;ve met way too many of these guys, in more than just the C++ domain.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A couple of thoughts come to mind on this whole mess.&lt;/p&gt;
&lt;h3&gt;Just how refactorable are you?&lt;/h3&gt;
&lt;p&gt;First of all, it&apos;s a widely debatable point as to the actual refactorability of dynamic languages. On NFJS speaker panels, Dave Thomas (he of the PickAxe book) would routinely admit that not all of the refactorings currently supported in Eclipse were possible on a dynamic language platform given that type information (such as it is in a language like Ruby) isn&apos;t present until runtime. He would also take great pains to point out that simple search-and-replace across files, something any non-trivial editor supports, will do many of the same refactorings as Eclipse or IntelliJ provides, since type is no longer an issue. Having said that, however, it&apos;s relatively easy to imagine that the IDE could be actively &amp;quot;running&amp;quot; the code as it is being typed, in much the same way that Eclipse is doing constant compiles, tracking type information throughout the editing process. This is an area I personally expect the various IDE vendors will explore in depth as they look for ways to capture the dynamic language dynamic (if you&apos;ll pardon the pun) currently taking place.&lt;/p&gt;
&lt;h3&gt;Who exactly are you for?&lt;/h3&gt;
&lt;p&gt;What sometimes gets lost in this discussion is that not all dynamic languages need be for programmers; a tremendous amount of success has been achieved by creating a core engine and surrounding it with a scripting engine that non-programmers use to exercise the engine in meaningful ways. Excel and Word do it, Quake and Unreal (along with other equally impressively-successful games) do it, UNIX shells do it, and various enterprise projects I&apos;ve worked on have done it, all successfully. A model whereby core components are written in Java/C#/C++ and are manipulated from the UI (or other &amp;quot;top-of-the-stack&amp;quot; code, such as might be found in nightly batch execution) by these less-rigorous languages is a powerful and effective architecture to keep in mind, particularly in combination with the next point....&lt;/p&gt;
&lt;h3&gt;Where do you run again?&lt;/h3&gt;
&lt;p&gt;With the release of JRuby, and the work on projects like IronRuby and Ruby.NET, it&apos;s entirely reasonable to assume that these dynamic languages can and will now run on top of modern virtual machines like the JVM and the CLR, completely negating arguments 2 and 4. While a dynamic language will usually take some kind of performance and memory hit when running on top of VMs that were designed for statically-typed languages, work on the DLR and the MLVM, as well as enhancements to the underlying platform that will be more beneficial to these dynamic language scenarios, will reduce that. Parrot may change that in time, but right now it sits at a 0.5 release and doesn&apos;t seem to be making huge inroads into reaching a 1.0 release that will be attractive to anyone outside of the &amp;quot;bleeding-edge&amp;quot; crowd.&lt;/p&gt;
&lt;h3&gt;So where does that leave us?&lt;/h3&gt;
&lt;p&gt;The allure of the dynamic language is strong on numerous levels. Without having to worry about type details, the dynamic language programmer can typically slam out more work-per-line-of-code than his statically-typed compatriot, given that both write the same set of unit tests to verify the code. However, I think this idea that the statically-typed developer must produce the same number of unit tests as his dynamically-minded coworker is a fallacy--a large part of the point of a compiler is to provide those same tests, so why duplicate its work? Plus we have the guarantee that the compiler will always execute these tests, regardless of whether the programmer using it remembers to write those tests or not.&lt;/p&gt;
&lt;p&gt;Having said that, by the way, I think today&apos;s compilers (C++, Java and C#) are pretty weak in the type expressions they require and verify. Type-inferencing languages, like ML or Haskell and their modern descendents, F# and Scala, clearly don&apos;t require the degree of verbosity currently demanded by the traditional O-O compilers. I&apos;m pretty certain this will get fixed over time, a la how C# has introduced &lt;a href=&quot;http://blogs.tedneward.com/2005/09/22/Language+Innovation+C+30+Explained.aspx&quot;&gt;implicitly typed variables&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Meanwhile, why the rancor between these two camps? It&apos;s eerily reminiscent of the ill-will that flowed back and forth between the C++ and Java communities during Java&apos;s early days, leading me to believe that it&apos;s more a concern over job market and emplyability than it is a real technical argument. In the end, there will continue to be a ton of Java work for the rest of this decade and well into the next, and JRuby (and Groovy) afford the Java developer lots of opportunities to learn those dynamic languages and still remain relevant to her employer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;It&apos;s as Marx said, lo these many years ago: &amp;quot;From each language, according to its abilities, to each project, according to its needs.&amp;quot;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Oh, except Perl. Perl just sucks, period. :-)&lt;/p&gt;
&lt;h3&gt;PostScript&lt;/h3&gt;
&lt;p&gt;I find it deeply ironic that the news piece TSS cited at the top of the discussion claims that the Chandler project failed due to mismanagement, not its choice of implementation language. It doesn&apos;t even mention what language was used to build Chandler, leading me to wonder if anybody even read the piece before choosing up their sides and throwing dirt at one another.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Is Java &quot;Done&quot; like the Patriots, or &quot;Done&quot; like the Dolphins?</title>
      <link>http://blogs.newardassociates.com/blog/2008/java-done-like-the-patriots-or-done-like-the-dolphins.html</link>
      <pubDate>Tue, 15 Jan 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/java-done-like-the-patriots-or-done-like-the-dolphins.html</guid>
      	<description>
	&lt;p&gt;English is a wonderful language, isn&apos;t it? I&apos;m no linguist, but from what little study I&apos;ve made of other languages (French and German, so far), English seems to have this huge propensity, more so than the other languages, to put multiple meanings behind the same word. Consider, for example, the word &quot;done&quot;: it means &quot;completed&quot;, as in &quot;Are you finished with your homework? Yes, Dad, I&apos;m done.&quot;, or it can mean &quot;wiped out, exhausted, God-just-take-me-now-please&quot;, as in &quot;Good God, &lt;em&gt;another&lt;/em&gt; open-source Web framework? That&apos;s it, I give up. I&apos;m done. Code the damn thing in assembler for all I care.&quot;&lt;/p&gt;
&lt;p&gt;So is Java &quot;done&quot; like the Patriots, a job well accomplished, or &quot;done&quot; like the Dolphins, the less said, the better?&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;(For those of you who are not American football fans, the New England Patriots have gone completely undefeated this season, a mark only set once before in the game&apos;s history, and the Miami Dolphins almost went completely unvictorious this season, a mark never accomplished. &lt;em&gt;[&lt;strong&gt;Update:&lt;/strong&gt; Hamlet D&apos;Arcy points out, &quot;Actually, a winless season has been accomplished before. Tampa Bay started their first two seasons winless with an overall 0-26 record before finally winning its first game in 1977.&quot; Thanks, Hamlet; my fact-checking on that one was lax, as I was trusting the commentary by a sportscaster during the Dolphins-Ravens game, and apparently his fact-checking was a tad lax, as well. :-)]&lt;/em&gt; The playoffs are still going on, but the Patriots really don&apos;t look beatable by any of the teams remaining. Meanwhile, the Dolphins managed to eke one out just before the season ended, posting a final record of 1-15, something reserved usually for new teams in the league, not a team with historical greatness behind them. And that&apos;s it for Sports, back to you in the studio, Tom.)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.artima.com/weblogs/viewpost.jsp?thread=221903&quot;&gt;Bruce Eckel seems to suggest that Java is somewhere more towards Miami than New England&lt;/a&gt;, and that generics were the major culprit. (He also intimates that his criticism of generics has swayed Josh and Neal&apos;s opinions to now being critical of generics, something I highly doubt, personally. More on that later.) Now, I&apos;ll be the first to admit that I think generics in Java suck, and I&apos;ve said this before, but the fact remains, no one feature can sink a language. Consider multiple inheritance in C++, something that Stroustrup himself admits (in &lt;em&gt;Design and Evolution of C++&lt;/em&gt;) he did before templates or exceptions because he wanted to know how he could do it. Lots of people argued for years (decades, even) over MI and its inclusion in the language, and in the end....&lt;/p&gt;
&lt;p&gt;... in the end MI turns out to be a useful feature of the language, but not the way &lt;em&gt;anybody&lt;/em&gt; figured they would be. Ditto for templates, by the way. After looking at the Boost libraries, even just the basic examples using them, I feel like I&apos;m looking at Sanskrit or something. As Scott Meyers put it once, &quot;We&apos;re a long way from Stack-of-T here, folks.&quot;&lt;/p&gt;
&lt;p&gt;And that is my principal complaint about generics: the fact that they aren&apos;t fully reified down into the JVM means that we lost 90% of the power of generics, and more importantly, we lost all of the emergent behavior and functionality that came out of C++ templates. Nothing &lt;em&gt;new&lt;/em&gt; could come out of Java generics, because they were designed to do exactly what they were designed to do: give us type-safe collections. Whee. We&apos;re cooking with gas now, folks. Next thing you know, they&apos;ll give us printf() back, too.&lt;/p&gt; &lt;p&gt;(Oh, wait, they did that, too.)&lt;/p&gt;
&lt;p&gt;Fact is, there&apos;s a lot of things that could be done to Java as a language to make it more attractive, but doing so risks that core element that Sun refuses to surrender, that of backwards compatibility. This was evident as far back as JavaPolis 2006, when I interviewed Neal and Josh on the subject; when asked, point-blank, why generics didn&apos;t &quot;go all the way down&quot;, a la .NET generics do, they both basically said, &quot;that would break backwards compatibility, and that was a core concern from the start&quot;. (I disagreed with them, off-camera, mind you, particularly on the grounds that the Collections library, the major source of concern around backwards compatibility, could have been ported over, but then Neal pointed out to me that it wasn&apos;t just the library itself but all the places it was used, particularly all those libraries outside of Sun, that was at stake. Perhaps, but I still believe that a happier middle ground could have been eked out.) That is still the message today, from what I can see of Neal&apos;s and Josh&apos;s public statements.&lt;/p&gt; &lt;p&gt;And the fact is, so far as it goes, Java generics are (ugh) useful. Useful solely as a Java compiler trick, perhaps, and far more verbose than we&apos;d prefer, but useful nonetheless. Using them is about as exciting as using a new hammer, but they can at least get the job done.&lt;/p&gt;
&lt;p&gt;There, I&apos;ve made the obligatory &quot;generics don&apos;t &lt;em&gt;completely&lt;/em&gt; suck&quot; disclaimer, and I&apos;ll be the first one to tell you, I just live with the warnings when I write Java code. Possibly that&apos;s because I don&apos;t worry too much about type-safe collections in my code, but I know lots of other programmers (particularly those on teams where the team composition isn&apos;t perhaps as strong as they&apos;d like it to be) who do, and thus take the extra time to write their code to be generics-friendly and thus warning-free.&lt;/p&gt; &lt;p&gt;The mere fact that we have to &lt;em&gt;work&lt;/em&gt; at it to create code that is &quot;generics-friendly&quot; is part of the problem here. For all those who came from C++ years ago, you&apos;ll know what I mean when I say that &quot;Java generics are the new C++ const&quot;: Writing const-correct code was always a Good Thing To Do, it&apos;s just that it was also just such a Damn Hard Thing To Do. Which meant that nobody did it.&lt;/p&gt; &lt;p&gt;Languages should enable you to fall into the pit of success. That&apos;s the heart of the Principle of Least Surprise, even if it&apos;s not always said that way. (I&apos;m not sure that C# 3 does this, time will tell. I&apos;m reasonably certain that Ruby doesn&apos;t, despite the repeated insistence of Ruby advocates, many of whom I deeply respect. I&apos;m nervous that Scala and F# will fall into this same trap, owing to their unusual syntax in places. It will be fun to see how ActionScript 3 turns out.)&lt;/p&gt;
&lt;p&gt;Here&apos;s a thought: Let&apos;s leave Java where it is, and just start creating new JVM languages that cater to specific needs. You can call them Java, too, if you like. Or something else, like Scala or Clojure or Groovy or JRuby or CJ or whatever suits your fancy. Since everybody compiles down to JVM bytecode, it&apos;s all really academic--they&apos;re &lt;em&gt;all&lt;/em&gt; Java, in some fundamental way. Which means that Java can thus rest easy, knowing that it fought the good fight, and that others equally capable are carrying on the tradition of JVM programming.&lt;/p&gt;
&lt;p&gt;Eckel makes a good point:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Arguably one of the best features of C is that it hasn&apos;t changed at all for decades.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;... which completely ignores some of the changes that were proposed and accepted for the C99 standard, but we&apos;ll leave that alone for now. The point is, the core C language now is the same core C language that I learned back in my high school days, and most, if not all, C code from even that far back will still compile under today&apos;s compilers. (Granted, there&apos;s likely to be a ton of warnings if you&apos;re using old &quot;K-and-R&quot; C, but the code will still compile.)&lt;/p&gt;
&lt;p&gt;What about evolution, though? Don&apos;t languages need to evolve in order to stay relevant?&lt;/p&gt;
&lt;p&gt;Consider the C case: C++ came along, made a whole bunch of changes to the language, but went zooming off in its own direction, to the point where a standards-compliant C++ compiler won&apos;t compile even relatively recent C code.&lt;/p&gt; &lt;p&gt;And how many people have complained about that?&lt;/p&gt;
&lt;p&gt;By the way, if you&apos;re a C/C++ programmer and you haven&apos;t looked at &lt;a href=&quot;http://www.digitalmars.com&quot;&gt;D&lt;/a&gt;, you&apos;re about to get leaped on the evolutionary ladder again. Just an FYI. &lt;/p&gt; &lt;p&gt;As a matter of fact, if you&apos;re a Java or .NET programmer, you&apos;d be well-advised to take a look at D, too. It&apos;s one of the more interesting native-compilation languages I&apos;ve seen in a while, and yet arguably it&apos;s just what a C++ compiler author would come up with after studying Java and C# for a while (which, as far as I can tell, is exactly what happened). And because D can essentially mimic C bindings for dynamic libraries, it means that a Java guy can now write a JNI DLL in a garbage-collected language that (mostly) does away with pointer arithmetic for most of its work... just as Java did.&lt;/p&gt; &lt;p&gt;Heck, I&apos;d love to see a D-for-the-JVM variant. And D-for-the-CLR, while we&apos;re at it. Just for fun.&lt;/p&gt; &lt;p&gt;Let&apos;s do this: somebody take the old, pre-Java5 javac source, and release it as &quot;JWH&quot; (short for Java Work Horse), and maintain it as a separate branch of the Java compiler. Then we can hack on the new Java5 language for years, maybe call it &quot;JWNFF&quot; (short for Java With New-Fangled Features), and everybody can get back to work without complaints.&lt;/p&gt;
&lt;p&gt;Well, at least those who &lt;em&gt;want&lt;/em&gt; to go back to work can do so; there&apos;ll always be people who&apos;d rather complain than Get Stuff Done. &lt;em&gt;*shrug*&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Now, on the other hand, let&apos;s talk about the JVM, and specifically what needs to change there if the JVM platform is to be the workhorse of the 21st century like it was for the latter half of the last decade of the 20th....&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Of Fibers and Continuations</title>
      <link>http://blogs.newardassociates.com/blog/2008/of-fibers-and-continuations.html</link>
      <pubDate>Thu, 10 Jan 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/of-fibers-and-continuations.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://pragdave.blogs.pragprog.com/pragdave/2007/12/pipelines-using.html&quot;&gt;Dave explains Ruby fibers&lt;/a&gt;, as they&apos;re called in Ruby 1.9.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Now, before I get going here, let me explain my biases up front: in the Windows world, we&apos;ve had fibers for near on to half-decade, I think, and they&apos;re basically programmer-managed cooperative tasks. In other words, they&apos;re much like threads before threads were managed by the operating system--you decide when to switch to a different fiber, you manage the scheduling, the fiber just gives you a data structure and some basic housekeeping. (I know I&apos;m oversimplifying and glossing over details, but that&apos;s the core, as I remember it. It&apos;s been a while since I tried to use them.) Legend has it that fibers were introduced into the Win32 API on behalf of the SQL Server team, who need to take that kind of control over thread scheduling in order to best manage the CPU, but here&apos;s the rub: they never served much purpose otherwise.&lt;/p&gt;
&lt;p&gt;Frankly, nobody could figure out what to do with them. I&apos;m beginning to wonder if it was because our languages of the time (C, C++) didn&apos;t have any real idea of freezing execution of a task at a certain point, putting it aside, then coming back to it and restoring it. In other words, the very behavior we see out of a continuation.&lt;/p&gt; &lt;p&gt;In Dave&apos;s explanation, Ruby fibers take on a different meaning. According to Dave&apos;s explanation:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;A fiber is somewhat like a thread, except you have control over when it gets scheduled. Initially, a fiber is suspended. When you resume it, it runs the block until the block finishes, or it hits a &lt;code&gt;Fiber.yield&lt;/code&gt;. This is similar to a regular block yield: it suspends the fiber and passes control back to the &lt;code&gt;resume&lt;/code&gt;. Any value passed to &lt;code&gt;Fiber.yield&lt;/code&gt; becomes the value returned by &lt;code&gt;resume&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;They sound a lot like Win32 fibers combined with Python generators, with a touch more by way of API support. (The Win32 API version was codified using C bindings, for starters, not objects.) But Dave quickly points out that fibers can become full-fledged coroutines by allowing fibers to transfer control from one to another, which is interesting, though I suspect lots of people will explore this feature and write lots of bad code as a result. Oh, well: bright shiny new toys have that effect on programmers sometimes.&lt;/p&gt; &lt;p&gt;He then goes on to describe how Ruby can provide pipelines:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;As a starting point, let&apos;s write two fibers. One&apos;s a generator—it creates a list of even numbers. The second is a consumer. All it does it accept values from the generator and print them. We&apos;ll make the consumer stop after printing 10 numbers.  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; evens = Fiber.new do&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value = 0&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; loop do&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Fiber.yield value&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value += 2&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; consumer = Fiber.new do&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10.times do&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; next_value = evens.resume&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; puts next_value&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; consumer.resume  &lt;p&gt;Note how we had to use resume to kick off the consumer. Technically, the consumer doesn&apos;t have to be a Fiber, but, as we&apos;ll see in a minute, making it one gives us some flexibility.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Ah, the classic producer-consumer example. Gotta love it. The interesting thing here, though, is that evens, prior to the call to resume, has done &lt;em&gt;nothing&lt;/em&gt;. No execution has taken place. In essence, the fiber here is in &lt;em&gt;deferred execution&lt;/em&gt; mode (now, &lt;a href=&quot;http://blogs.msdn.com/charlie/archive/2007/12/09/deferred-execution.aspx&quot;&gt;where have I heard that before&lt;/a&gt;?), meaning nothing actually fires until asked for. It then runs until it hits the yield, essentially going to sleep again.&lt;/p&gt; &lt;p&gt;Is it me, or does this smell suspiciously like continuations?&lt;/p&gt; &lt;p&gt;More interesting, Dave goes on to define the consumer fiber to take the name of a source to resume, then shows how once can abstract the coupling between producer and consumer away even further by creating a filter that only allows multiples of three through the pipeline:&lt;/p&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;    def evens
      Fiber.new do
        value = 0
        loop do
          Fiber.yield value
          value += 2
        end
      end
    end
&lt;pre&gt;&lt;code&gt;def multiples_of_three(source)
  Fiber.new do
    loop do
      next_value = source.resume
      Fiber.yield next_value if next_value % 3 == 0
    end
  end
end

def consumer(source)
  Fiber.new do
    10.times do
      next_value = source.resume
      puts next_value
    end
  end
end

consumer(multiples_of_three(evens)).resume
&lt;/code&gt;&lt;/pre&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Running this, we get the output&lt;pre&gt;&lt;code&gt;0
6
12
18
. . .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is getting cool. We write little chunks of code, and then combine them to get work done. Just like a pipeline.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Actually, instead of calling it a pipeline, let&apos;s call it a &lt;em&gt;comprehension&lt;/em&gt; and be done with it.&lt;/p&gt;
&lt;p&gt;See, Ruby apparently has discovered the joys of functional programming, something that Scala and F# have baked in from the beginning, instead of bolted on from the outside. No offense intended to the Ruby community or to Matz, but I get a little lost as to exactly what Ruby&apos;s core concepts are--it&apos;s a scripting language, it&apos;s a development language, it&apos;s a DSL platform, it&apos;s object-oriented, it&apos;s functional, it&apos;s a bird, it&apos;s a plane, it&apos;s horribly confused.&lt;/p&gt;
&lt;p&gt;Dave touches on this point in one of his responses to comments:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The thing that&apos;s interesting to me about Ruby in this context is how much is can bend into multiple paradigms. Haskell does FP way better than Ruby. Smalltalk does OO (marginally) better. But Ruby does them all, and in a way that interoperates nicely.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;I like a lot of Ruby&apos;s core concepts--open classes, mixins, and so on--but I&apos;m worried that Ruby&apos;s trying to do too much, much as &lt;a href=&quot;http://java.sun.com&quot;&gt;another language I know and love&lt;/a&gt; is. Frankly, this desire to accommodate the nifty feature of the moment smacks a great deal of Visual Basic, and while VB certainly has its strengths, coherent language design and consistent linguistic facilities is not one of them. It&apos;s played havoc with people who tried to maintain code in VB, and it&apos;s played hell with the people who try to maintain the VB language. One might try to argue that the Ruby maintainers are just Way Smarter than the Visual Basic maintainers, but I think that sells the VB team pretty short, having met some of them.&lt;/p&gt;
&lt;p&gt;Don&apos;t get me wrong here, I think it&apos;s nifty that Ruby has come around to realize the power of atomic components doing one thing well, passing its results on into the pipeline for something else to process, and this is a large part of why PowerShell is, in my mind, the sleeper programming language of 2008/2009. Pipelines also scale very well, since they encourage immutable state, since the results of each processing step are essentially fed in from the outside and the results are passed back out to the next step in the chain--all state is passed from one step to the next, meaning I can run lots of these pipelines in parallel with no fear of deadlocks or bottlenecks, since each processing step is itself essentially state-free. This is also, in fact, a lot of how original transaction-processing systems were designed, which also scaled pretty well, at least until we got the bright idea to store mutable state in them (*cough* EJB *cough*).&lt;/p&gt;
&lt;p&gt;Oh, and for what it&apos;s worth, this concept is trivial to do in F#, via the pipeline operator ( &quot;|&amp;gt;&quot; ). Ditto for Scala. If you&apos;re going to think in pipelines, you may as well work with a language that has the concept baked in a little more deeply, IMHO. And before the Rubyists beat me over the head about this, Dave himself admits this is true in another comment response:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Paolo: I don&apos;t think Ruby or Smalltalk really do functional programming to any deep level. However, both can be used to implement particular FP constructs (such as generators).&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;And maybe, in the end, that&apos;s the important thing: recognizing what aspects of functional programming can be easily lifted into your language of choice and used to make your life simpler. Still, I&apos;m always looking for languages that take the concepts that float in my head and let me express them as first-class constructs, not as duck-taped partial implementations thereof. I felt the same way about doing &quot;objects&quot; in C (back in the Win16 programming day, before C++ Windows frameworks emerged), and about doing &quot;aspects&quot; in Java using interception.&lt;/p&gt;
&lt;p&gt;If you&apos;re going to think in a concept, you generally want a language that expresses that concept as a first-class citizen, or you&apos;ll get frustrated quickly. Ruby&apos;s fibers may be the gateway drug for developers to learn functional programming, but they&apos;re not going to get it at any deep level until they dive into Haskell or ML or one of its derivatives (Scala or F#). For example, once you see the power inherent in Scala&apos;s comprehensions, you never look at a simple for loop the same way again.&lt;/p&gt;
&lt;p&gt;Oh, and Groovyists? I&apos;m sure they could do this, but I dunno if it&apos;s worth it, given that Groovy and Scala, at some level, are fundamentally interoperable as well. (Note to self: must do a blog post about Groovy calling into Scala code, just to show it can be done. Y&apos;all hold me to that, if you don&apos;t see it in a week or two.)&lt;/p&gt;
&lt;p&gt;Meanwhile, the link between continuations and Ruby fibers (and Win32 fibers, while we&apos;re at it) still tickles at the back of my mind.... But that&apos;s a thought waiting to be explored another day.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2008 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2008/2008-tech-predictions.html</link>
      <pubDate>Wed, 26 Dec 2007 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2008/2008-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;As has become a tradition, &apos;tis time to offer up my predictions for the technical year 2008, and, more importantly, revisit my predictions for the technical year 2007 and see how close to the mark I was. (As usual, I&apos;ll simply offer up commentary and my own opinion--you&apos;re free to draw whatever conclusions you like about my abilities as a prognosticator.)&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;First, the predictions from 2007, in retrospect:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;/em&gt;&lt;em&gt;General: Analysts will call 2007 the Year of the {Something}, where I bet that {Something} will be either &quot;ESB&quot; or &quot;SOA&quot;. They will predict that companies adopting {Something} will save millions, if not billions, if only they rush to implement it now. They will tag this with a probability of .8 in order to CYA in case {Something} doesn&apos;t pan out. (Yes, I&apos;ve read far too many of these reports--I&apos;m personally convinced that each of the analyst companies has a template buried away in their basement that they pull out each time they need a new one, and they just do a global search-and-replace of &quot;{Something}&quot; with whatever the technology du jour happens to be.)&lt;/em&gt; &lt;em&gt;&lt;strong&gt;NOW: &lt;/strong&gt;&lt;/em&gt;Wasn&apos;t this the Year of the ESB?&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;/em&gt;&lt;em&gt;.NET: Thousands of developers will horribly abuse WPF in ways that can only be called nightmarish, thus once again proving the old adage that &quot;just because you can doesn&apos;t mean you should&quot; still holds. WPF&apos;s capabilities with video will prove, in many ways, to be the modern equivalent to the &quot;blink&quot; tag in HTML. This will provide some author with a golden opportunity: &quot;WPF Applications That Suck&quot;. Alan Cooper will re-release &quot;About Face&quot;, updated to include WPF UI elements.&lt;/em&gt; &lt;em&gt;&lt;strong&gt;NOW: &lt;/strong&gt;&lt;/em&gt;Well, it wasn&apos;t Alan Cooper, but Charles Petzold re-released his classics, updated for WPF. Fact is, WPF hasn&apos;t seemed to penetrate all that deeply into the programming world, so maybe this is better as a 2008 prediction, now that Visual Studio 2008 is in the hands of developers.&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;/em&gt;&lt;em&gt;.NET: Thousands of developers will look to Redmond for an answer to the question, &quot;Which should I use? BizTalk, Windows Workflow, or SQL Server Service Broker?&quot;, and get no clear answer.&lt;/em&gt; &lt;em&gt;&lt;strong&gt;NOW: &lt;/strong&gt;&lt;/em&gt;How many presentations at DevConnections, VSLive!, TechEd, and other .NET shows addressed this exact question? How much guidance from Microsoft was there on the subject? &apos;Nuff said.&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;/em&gt;&lt;em&gt;Windows: Microsoft will try, once again, to kill off the abomination that was called the Windows 95/98/Me line of operating systems, and will once again have to back off as industry outcries of protest (on behalf of little old ladies who are the only ones left running Windows 95/98/Me and probably haven&apos;t turned their machine on in months, at least not since the grandkids last visited) go ballistic.&lt;/em&gt; &lt;em&gt;&lt;strong&gt;NOW: &lt;/strong&gt;&lt;/em&gt;Granny Schottenwilkins in East Duluth, Minnesota died last year, so maybe &lt;em&gt;next&lt;/em&gt; year Microsoft will finally have enough momentum to kill Windows 16-bit.&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;/em&gt;&lt;em&gt;Windows: Ditto for Visual Basic 6.0, except now the outcry will be on behalf of developers who aren&apos;t capable of learning anything new. Sun will use the resulting PR to announce Project YAVKRWMITT (Yet Another VB Killer Really We Mean It This Time, pronounced &quot;YAV-kermit&quot;) on java.net. Meanwhile, efforts to make CLASSPATH into something a VB 6 guy actually has a prayer of understanding will go quietly ignored.&lt;/em&gt; &lt;em&gt;&lt;strong&gt;NOW: &lt;/strong&gt;&lt;/em&gt;Apparently Microsoft had enough problems getting Vista adoption going, so they didn&apos;t bother trying to kill VB 6 this year. Meanwhile, Sun continues to build NetBeans to attract developers from &quot;across the fence&quot;, except now its Ruby developers. (Apparently somebody finally showed Simon Phipps what VB 6 code &lt;em&gt;really&lt;/em&gt; looks like, and he made the prudent decision to leave it in Microsoft&apos;s hands....)&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;/em&gt;&lt;em&gt;Java: JSR 277 will continue to churn along, and once the next draft ships, publicly nobody will like what we produce, though quietly everybody will admit it&apos;s a far cry better than what we have now, and when it ships in JDK 7 will be adopted widely and quietly.&lt;/em&gt; &lt;em&gt;&lt;strong&gt;NOW: &lt;/strong&gt;&lt;/em&gt;We shipped a straw man implementation, which so far as I can tell, nobody bothered to look at, probably because it was a source patch on top of the OpenJDK bits, which nobody else knew how to build....&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;/em&gt;&lt;em&gt;Java: Thousands of new ideas and proposals to extend the Java language in various ways will flood into the community, now that developers can start hacking on it for themselves thanks to the OpenJDK. Only a small fraction of these will ever get beyond the concept stage, and maybe one or two will actually be finished and released to the Web for consideration by the community and the JCP. Thousands more Java developers craving Alpha-Geek status will stick a &quot;Hello, world&quot; message into the compiler&apos;s startup sequence, then claim &quot;experienced with modifying the OpenJDK Java compiler&quot; on their resume and roundly criticize Java in one way or another by saying, &quot;Well, I&apos;ve looked at the code, and let me tell you....&quot;.&lt;/em&gt; &lt;em&gt;&lt;strong&gt;NOW: &lt;/strong&gt;&lt;/em&gt;Numerous language-extension projects emerging on Sourceforge and java.net, none of which appear to have any code behind them... What&apos;s it say on &lt;em&gt;your&lt;/em&gt; resume, by the way?&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;/em&gt;&lt;em&gt;.NET: Somewhere, a developer will realize that SQL Server 2005 can be a SOAP/WSDL XML service endpoint, and open it up as a private back-channel for his application to communicate with the database through the firewall &quot;for performance reasons&quot; (meaning, &quot;So I can avoid having to talk to the app server in between my web server and my database&quot;). With any luck, the DBA will kill him and hide the body before anybody can find and exploit it.&lt;/em&gt; &lt;em&gt;&lt;strong&gt;NOW: &lt;/strong&gt;&lt;/em&gt;&quot;Body of dead developer found underneath raised floor in server room. Story, at 11. In related news, WhizzBang Corp filed for bankruptcy, owing to the complete collapse of their stock after news of their entire customer base personal details database being discovered on the Web was made public....&quot;&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;/em&gt;&lt;em&gt;General: Yet Another Virus That&apos;s Microsoft&apos;s Fault will rip through the Internet, and nobody will notice that the machines affected are the ones that aren&apos;t routinely administered or receive updates/patches. Companies will threaten Microsoft with million-dollar lawsuits, yet will fire none of their system administrators who lovingly lavish whole days tuning their Linux IRC servers yet leave the Windows Exchange Server still running Windows NT 4.0.&lt;/em&gt; &lt;em&gt;&lt;strong&gt;NOW: &lt;/strong&gt;&lt;/em&gt;Surprisingly, this didn&apos;t happen. Either we&apos;re shockingly bland to the viruses ripping through the Internet now, or else the virus creators are falling behind the anti-virus defenders, or else the viruses have learned to lay low, waiting for the master signal to go off simultaneously.&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;/em&gt;&lt;em&gt;General: Interest in JSON will escalate wildly, hyped as the &quot;natural replacement for XML&quot; in building browser-to-server connections, owing to its incredible simplicity in expressing &quot;object&quot; data. Folks, JSON is a useful format, but it&apos;s not a replacement for XML (nor is XML a replacement for it, either). What made XML so popular was not is hierarchical format (Lord above, that&apos;s probably the worst part of it, from where we as developers sit), nor its HTML-like simplified-SGML syntax. What made XML interesting was the fact that everybody lined up behind it--Microsoft, Sun, BEA, Oracle, IBM, there&apos;s not a big vendor that didn&apos;t express its undying love and devotion to XML. I sincerely doubt JSON will get that kind of rallying effect. (And if you&apos;re going to stand there and suggest that JSON is better because its simpler and therefore more approachable for developers to build support for themselves, quite honestly, I thought we were trying to get out of developers building all this communications infrastructure--isn&apos;t that what the app servers and such taught us?)&lt;/em&gt; &lt;em&gt;&lt;strong&gt;NOW: &lt;/strong&gt;&lt;/em&gt;Well, JSON continues to be of interest to those who are also hand-writing their JavaScript code on their web pages, which means that to the top-of-the-web-pyramid ubergeek, JSON is &quot;clearly the right way to go&quot;, while the rest of the industry just doesn&apos;t give a damn so long as the code works.&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;/em&gt;&lt;em&gt;General: Interest in Java/.NET interopability will rise as companies start to realize that (a) the WS-* &quot;silver bullet&quot; isn&apos;t, (b) ESB, XML, and SOA are just acronyms and won&apos;t, in of themselves, solve all the integration problems, and (c) we have lots of code in both Java and .NET that need to talk to each other. This may be a self-serving prediction, but I got a LOT of interest towards the end of this year in the subject, so I&apos;m guessing that this is going to only get bigger as the WS-* hype continues to lose its shine in the coming years.&lt;/em&gt; &lt;em&gt;&lt;strong&gt;NOW: &lt;/strong&gt;&lt;/em&gt;It got bigger, then drained away. I guess either the world figured out their story here, or everybody&apos;s busy rewriting all their apps in Ruby.&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;/em&gt;&lt;em&gt;Ruby: Interest in Java/Ruby and .NET/Ruby interoperability is going to start quietly making its presence felt, as people start trying to wire up their quick-to-write &quot;stovepipe&quot; RAILS apps against other systems in their production data center, and find that Ruby really is a platform of its own. RubyCLR or JRuby may be part of the answer here, but there&apos;s likely some hidden mines there we haven&apos;t seen yet.&lt;/em&gt; &lt;em&gt;&lt;strong&gt;NOW: &lt;/strong&gt;&lt;/em&gt;JRuby now runs faster than the native Ruby interpreter. IronRuby (the logical successor to RubyCLR) looks to do the same for the CLR side, plus we get a dynamic language runtime out of it. Ruby may be the best language running on somebody else&apos;s platform in 2008.&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN:&lt;/strong&gt; &lt;/em&gt;&lt;em&gt;Languages: A new meme will get started: &quot;JavaScript was that thing, that little toy language, that you used to do stuff in the HTML browser. ECMAScript, on the other hand, is a powerful and flexible dynamic programming language suitable for use in all sorts of situations.&quot; Pass it on. If you get it, don&apos;t tell anybody else. (Don&apos;t laugh--it worked for &quot;The Crying Game&quot;.) It&apos;s the only way ECMAScript will gain widespread acceptance and shed the &quot;toy&quot; label that JavaScript has.&lt;/em&gt; &lt;em&gt;&lt;strong&gt;NOW: &lt;/strong&gt;&lt;/em&gt;And now ECMAScript 4 is coming, with a whole new set of features that make even the Ruby guys shiver in anticipation.&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN:&lt;/strong&gt; Languages: Interest in functional-object hybrid languages will grow. Scala, Jaskell, F#, and others not-yet-invented will start to capture developers&apos; attention, particularly when they hear the part about functional languages being easier to use in multi-core systems because it encourages immutable objects and discourages side effects (meaning we don&apos;t have to worry nearly so much about writing thread-safe code).&lt;/em&gt; &lt;em&gt;&lt;strong&gt;NOW: &lt;/strong&gt;&lt;/em&gt;It grew, and it continues to grow. New languages in general are being released (see Clojure, Jaskell, dynalang, and others), and lots of them are incorporating functional language concepts. If you&apos;ve never programmed in Haskell, now&apos;s a good time to learn, because those concepts and syntax are fast making their way towards you...&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;Languages: Interest in Domain-specific languages will reach a peak this year, but a small backlash will begin next year. Meanwhile, more and more developers will realize that one man&apos;s &quot;DSL&quot; is another man&apos;s &quot;little language&quot;, something UNIX has been doing since the early 70&apos;s. This will immediately take the shine off of DSLs, since anything that we did in the 70&apos;s must be bad, somehow. (Remember disco?) &lt;strong&gt;NOW: &lt;/strong&gt;&lt;/em&gt;Apparently people haven&apos;t made the connection yet. Give it time, give it time...&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;General: Rails will continue to draw developers who want quick-fix solutions/technologies, and largely that community will ignore the underlying power of Ruby itself. The draw will start to die down once Rails-esque feature ideas get folded into Java toolkits. (Rails will largely be a non-issue with the .NET community, owing to the high-productivity nature of the drag-and-drop interface in Visual Studio.) &lt;strong&gt;NOW:&lt;/strong&gt;&lt;/em&gt; In the Java world, see Grails. In the .NET world, see the new MVC container for ASP.NET. In both worlds? Sit back and chortle at how each side chases the other, and quietly look for the best of both. Look like a genius. Retire to Caribbean country on your luxury yacht and supermodel girlfriends.&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;Java: Interface21 is going to start looking like a &quot;big vendor&quot; alongside BEA and IBM. I was talking with some of the I21 folks in Aarhus, Denmark at JAOO, and one of them casually mentioned that they were looking at a Spring 2.1 release somewhere in mid-2008. Clearly Spring is settling into eighteen-month major-version release cycles like all the big (meaning popular), established software systems have a tendency to do. This is both a good thing and a bad thing--it&apos;s good in that it means that Spring is now becoming an established part of the Java landscape and thus more acceptable to use in production environments, but it&apos;s bad in that Spring is now going to face the inevitable problem all big vendors face: trying to be all things to all people. This is dangerous, both for Interface21 and the people relying on Spring, largely because it means that Spring faces a very real future of greater complexity (and there are those, myself included, who believe that Spring is too complex already, easily on par with the complexity seen in EJB, POJOs notwithstanding).&lt;/em&gt;&amp;nbsp;&lt;strong&gt;&lt;em&gt;NOW:&lt;/em&gt;&lt;/strong&gt; Spring hit the 2.1 release earlier than 2008... sort of. They actually went one step better, deciding that the next release of Spring isn&apos;t a &quot;2.1&quot;, but a &quot;2.5&quot;. (Apparently Microsoft marketing isn&apos;t the only one who likes to jerk around version numbers.) When combined with their re-branding as &quot;SpringSource&quot;, they&apos;re just a re-org away from being a Real Corporation.&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;General: Marc Fleury will get a golden parachute from Red Hat (at their request and to their immense relief), and hopefully will retire to his own small island (might I suggest Elba, la petite corporal?) to quietly enjoy his millions. A shame that the people who did most of the real work on JBoss won&apos;t see a commensurate reward, but that&apos;s the way the business world works, I guess.&lt;/em&gt; &lt;strong&gt;&lt;em&gt;NOW:&lt;/em&gt;&lt;/strong&gt; Has anybody paid any attention to Fleury since his &lt;a href=&quot;http://www.localtechwire.com/business/local_tech_wire/news/story/1198568/&quot;&gt;&quot;extended paternity leave&quot;&lt;/a&gt;? Maybe it&apos;s just me, but the Internet has been blissfully quiet the last half-year or so....&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;General: Some company will get millions to build an enterprise product on the backs of RSS and/or Atom, thus proving that VCs are just as stupid and just as vulnerable to hype now as they were back in the DotCom era.&lt;/em&gt; &lt;strong&gt;&lt;em&gt;NOW:&lt;/em&gt;&lt;/strong&gt; I think I jumped the gun on this one. Unless, of course, you think about Flickr and Twittr as extended RSS/ATOM feeds....&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;General: Somebody will attempt to use the phrase &quot;Web 2.0&quot; in a serious discussion, and I will be forced to kill them for attempting to use a vague term in a vain effort to sound intelligent.&lt;/em&gt; &lt;strong&gt;&lt;em&gt;NOW:&lt;/em&gt;&lt;/strong&gt; Tim O&apos;Reilly must be dipped in lemon juice after being subjected to two dozen papercuts for creating this term. I actually heard somebody who should have known better ask, &quot;So how do I log on to this Web 2.0 thing?&quot; Apparently he got it confused with Internet2 (which is a boondoggle in its own right by this point.)&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;Web clients: Ajax will start to lose its luster when developers realize the power of Google Maps isn&apos;t in Ajax, but in the fact that it&apos;s got some seriously cool graphics and maps. (Or, put another way, when developers realize that Ajax alone won&apos;t make their apps as cool as Google Maps, that&apos;s it&apos;s the same old DHTML from 1998, the hype will start to die down.) &lt;strong&gt;NOW:&lt;/strong&gt;&lt;/em&gt;&amp;nbsp; Have people started building real apps with this stuff yet? Everything so far looks like demos and research prototypes to me....&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;XML: Somebody, somewhere, will realize that REST != HTTP. He will be roundly criticized by hordes of HTTP zealots, and quietly crawl away to go build simpler and more robust systems that use transports other than HTTP. &lt;strong&gt;NOW: &lt;/strong&gt;&lt;/em&gt;Anybody? Anybody? Bueller?&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;XML: Somebody, somewhere, will read the SOAP 1.2 specification. H.P. Lovecraft once suggested, loosely paraphrased, the the day Man understands the nature of the universe, he will either be driven into gibbering insanity, or flee back into ignorance in self-preservation. Ditto for the day Man reads the SOAP 1.2 spec and realizes that SOAP is, in fact, RESTful. &lt;strong&gt;NOW:&lt;/strong&gt;&lt;/em&gt; Paging Mr. Davis, Mr. Scott Davis, please answer the white courtesy telephone...&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;Security: The US Government will continue its unbelievable quest to waste money on &quot;security&quot; by engaging in yet more perimeter security around airports and other indefensible locations, thus proving that none of them have bothered to read Schneier and learn that real security is a three-part tuple: prevention, detection, and response. &lt;strong&gt;NOW:&lt;/strong&gt;&lt;/em&gt; Paging Mr. [DELETED], Mr. [REDACTED] [DELETED], you have a [INSUFFICIENT CLEARANCE]....&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;Security: Thousands of companies will follow in the US Government&apos;s footsteps by doing exactly the same thing. (Folks, you can&apos;t solve all your problems with cryptography, no matter how big the key size--you just end up with the basic problem of where to store the keys, and no, burying them inside the code isn&apos;t going to hide them effectively.) &lt;strong&gt;NOW:&lt;/strong&gt;&lt;/em&gt; Anybody had a look at some of these &quot;secure&quot; website approaches recently?&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;Security: More and more rootkits-shipping-with-a-product will be discovered. We used to call it &quot;getting close to the metal&quot;, now it&apos;s a &quot;rootkit&quot;. With great power comes great responsibility... and, as many consumers have already discovered, with great power also comes a tendency to create greater instability...&lt;strong&gt; NOW:&lt;/strong&gt;&lt;/em&gt; Rootkits, extensions, call it what you will, but they&apos;re growing all over the place....&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;General: Parrot will ship a 1.0 release. Oh, wait, hang on, sorry, I bumped into the crystal ball and accidentally set it to 2017.&lt;/em&gt; &lt;strong&gt;&lt;em&gt;NOW:&lt;/em&gt;&lt;/strong&gt; Parrot is all but dead, near as I can tell. Too bad, too, but maybe if they&apos;d had a more realistic approach to building a unified type system....&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;.NET: Microsoft will ship Orcas (NetFX 3.5). (Sorry, crystal ball&apos;s still set on 2017. Trying to fix it...) &lt;strong&gt;NOW:&lt;/strong&gt;&lt;/em&gt; They shipped. &apos;Nuff said.&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;.NET: Vista will surpass Windows XP in market penetration. (Let&apos;s see, almost got it set back to 2007, bear with me... There. Got it.) &lt;strong&gt;NOW:&lt;/strong&gt;&lt;/em&gt; They wish. Cue Vista SP1. &apos;Nuff said.&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;General: I will blog more than I did this year. (Hell, I couldn&apos;t blog less, even if I tried.)&lt;/em&gt; &lt;strong&gt;&lt;em&gt;NOW:&lt;/em&gt;&lt;/strong&gt; Well....&lt;/li&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;THEN: &lt;/strong&gt;General: Pragmatic XML Services, Pragmatic .NET Project Automation and Effective .NET will ship. (Wait, is the crystal ball still on 2017...?)&lt;strong&gt; NOW:&lt;/strong&gt;&lt;/em&gt; I wish. &apos;Nuff said.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Next, my predictions for 2008:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;em&gt;General: The buzz around building custom languages will only continue to build.&lt;/em&gt; More and more tools are emerging to support the creation of custom programming languages, like Microsoft&apos;s Phoenix, Scala&apos;s parser combinators, the Microsoft DLR, SOOT, Javassist, JParsec/NParsec, and so on. Suddenly, the whole &quot;write your own lexer and parser and AST from scratch&quot; idea seems about as outmoded as the idea of building your own String class. Granted, there are cases where a from-hand scanner/lexer/parser/AST/etc is the Right Thing To Do, but there are times when building your own String class is the Right Thing To Do, too. Between the rich ecosystem of dynamic languages that could be ported to the JVM/CLR, and the interesting strides being made on both platforms (JVM and CLR) to make them more &quot;dynamic-friendly&quot; (such as being able to reify classes or access the call stack directly), the probability that your company will find a need that is best answered by building a custom language are only going to rise.&lt;/li&gt; &lt;li&gt;&lt;em&gt;General: The hype surrounding &quot;domain-specific languages&quot; will peak in 2008, and start to generate a backlash&lt;/em&gt;. Let&apos;s be honest: when somebody looks you straight in the eye and suggests that &quot;scattered, smothered and covered&quot; is a domain-specific language, the term has lost all meaning. A lexicon unique to an industry is not a domain-specific language; it&apos;s a lexicon. Period. If you can incorporate said lexicon into your software, thus making it accessible to non-technical professionals, that&apos;s a good thing. But simply using the lexicon doesn&apos;t make it a domain-specific language. Or, alternatively, if you like, &lt;em&gt;every single API designed for a particular purpose is itself a domain-specific language&lt;/em&gt;. This means that Spring configuration files are a DSL. Deployment descriptors are a DSL. The Java language is a DSL (since the domain is that of programmers familiar with the Java language). See how nonsensical this can get? Until somebody comes up with a workable definition of the term &quot;domain&quot; in &quot;domain-specific language&quot;, it&apos;s a nonsensical term. The &lt;em&gt;idea&lt;/em&gt; is a powerful one, mind you--creating something that&apos;s more &quot;in tune&quot; with what users understand and can use easily is a technique that&apos;s been proven for decades now. Anybody who&apos;s ever watched an accountant rip an entirely new set of predictions for the new fiscal outlook based entirely on a few seed numbers and a deeply-nested set of Excel macros knows this already. Whether you call them domain-specific languages or &quot;little languages&quot; or &quot;user-centric languages&quot; or &quot;macro language&quot; is really up to you.&lt;/li&gt; &lt;li&gt;&lt;em&gt;General: &lt;/em&gt;&lt;em&gt;Functional languages will begin to make their presence felt.&lt;/em&gt; Between Microsoft&apos;s productization plans for F# and the growing community of Scala programmers, not to mention the inherently functional concepts buried inside of LINQ and the concurrency-friendly capabilities of side-effect-free programming, the world is going to find itself working its way into functional thinking either directly or indirectly. And when programmers start to see the inherent capabilities inside of Scala (such as Actors) and/or F# (such as asynchronous workflows), they&apos;re going to embrace the strange new world of functional/object hybrid and never look back.&lt;/li&gt; &lt;li&gt;&lt;em&gt;General: MacOS is going to start posting some serious market share numbers, leading lots of analysts to predict that Microsoft Windows has peaked and is due to collapse sometime within the remainder of the decade&lt;/em&gt;. Mac&apos;s not only a wonderful OS, but it&apos;s some of the best hardware to run Vista on. That will lead not a few customers to buy Mac hardware, wipe the machine, and install Vista, as many of the uber-geeks in the Windows world are already doing. This will in turn lead Gartner (always on the lookout for an established trend they can &quot;predict&quot; on) to suggest that Mac is going to end up with 115% market share by 2012 (.8 probability), then sell you this wisdom for a mere price of $1.5 million (per copy).&lt;/li&gt; &lt;li&gt;&lt;em&gt;General: Ted will be hired by Gartner... if only to keep him from smacking them around so much.&lt;/em&gt; .0001 probability, with probability going up exponentially as my salary offer goes up exponentially. (Hey, I&apos;ve got kids headed for college in a few years.) ;-)&lt;/li&gt; &lt;li&gt;&lt;em&gt;General: MacOS is going to start creaking in a few places.&lt;/em&gt; The Mac OS is a wonderful OS, but it&apos;s got its own creaky parts, and the more users that come to Mac OS, the more that software packages are going to exploit some of those creaky parts, leading to some instability in the Mac OS. It won&apos;t be widespread, but for those who are interested in finding it, they&apos;re there. Assuming current trends (of customers adopting Mac OS) hold, the Mac OS 10.6 upgrade is going to be a &lt;em&gt;very &lt;/em&gt;interesting process, indeed.&lt;/li&gt; &lt;li&gt;&lt;em&gt;General: Somebody is going to realize that iTunes is the world&apos;s biggest monopoly on music, and Apple will be forced to defend itself in the court of law, the court of public opinion, or both.&lt;/em&gt; Let&apos;s be frank: if this were Microsoft, offering music that can only be played on Microsoft music players, the world would be through the roof. All UI goodness to one side, the iPod represents just as much of a monopoly in the music player business as Internet Explorer did in the operating system business, and if the world doesn&apos;t start taking Apple to task over this, then &quot;justice&quot; is a word that only applies when losers in an industry want to drag down the market leader (which I firmly believe to be the case--nobody likes more than to pile on the successful guy). &lt;/li&gt; &lt;li&gt;&lt;em&gt;General: Somebody is going to realize that the iPhone&apos;s &quot;nothing we didn&apos;t write will survive the next upgrade process&quot; policy is nothing short of draconian.&lt;/em&gt; As my father, who gets it right every once in a while, says, &quot;If I put a third-party stereo in my car, the dealer doesn&apos;t get to rip it out and replace it with one of their own (or nothing at all!) the next time I take it in for an oil change&quot;. Fact is, if I buy the phone, I own the phone, and I own what&apos;s on it. Unfortunately, this takes us squarely into the realm of DRM and IP ownership, and we all know how clear-cut that is... But once the general public starts to understand some of these issues--and I think the iPhone and iTunes may just be the vehicle that will teach them--look out, folks, because the backlash will be &lt;em&gt;huge&lt;/em&gt;. As in, &quot;Move over, Mr. Gates, you&apos;re about to be joined in infamy by your &lt;em&gt;other&lt;/em&gt; buddy Steve....&quot;&lt;/li&gt; &lt;li&gt;&lt;em&gt;Java: The OpenJDK in Mercurial will slowly start to see some external contributions.&lt;/em&gt; The whole point of Mercurial is to allow for deeper control over which changes you incorporate into your build tree, so once people figure out how to build the JDK and how to hack on it, the local modifications will start to seep across the Internet....&lt;/li&gt; &lt;li&gt;&lt;em&gt;Java: SpringSource will soon be seen as a vendor like BEA or IBM or Sun.&lt;/em&gt; Perhaps with a bit better reputation to begin, but a vendor all the same.&lt;/li&gt; &lt;li&gt;&lt;em&gt;.NET: Interest in OpenJDK will bootstrap similar interest in Rotor/SSCLI.&lt;/em&gt; After all, they&apos;re both VMs, with lots of interesting ideas and information about how the managed platforms work.&lt;/li&gt; &lt;li&gt;&lt;em&gt;C++/Native:&lt;/em&gt; &lt;em&gt;If you&apos;ve not heard of LLVM before this, you will.&lt;/em&gt; It&apos;s a compiler and bytecode toolchain aimed at the native platforms, complete with JIT and GC.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Java: Somebody will create Yet Another Rails-Killer Web Framework.&lt;/em&gt; &apos;Nuff said.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Native: Developers looking for a native programming language will discover D, and be happy.&lt;/em&gt; Considering D is from the same mind that was the core behind the Zortech C++ compiler suite, and that D has great native platform integration (building DLLs, calling into DLLs easily, and so on), not to mention automatic memory management (except for those areas where you want manual memory management), it&apos;s definitely worth looking into. &lt;a href=&quot;http://www.digitalmars.com&quot;&gt;www.digitalmars.com&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;em&gt;&lt;/em&gt;See you all next year.... &lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Quotes on Writing</title>
      <link>http://blogs.newardassociates.com/blog/2007/quotes-on-writing.html</link>
      <pubDate>Sat, 8 Dec 2007 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2007/quotes-on-writing.html</guid>
      	<description>
	&lt;p&gt;This is, without a doubt, the most accurate quote &lt;em&gt;ever&lt;/em&gt; about the &amp;quot;fun&amp;quot; of writing a book:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Writing a book is an adventure. To begin with, it is a toy and an amusement; then it becomes a mistress, and then it becomes a master, and then a tyrant. The last phase is that just as you are about to be reconciled to your servitude, you kill the monster, and fling him out to the public. (&lt;a href=&quot;http://www.brainyquote.com/quotes/quotes/w/winstonchu136000.html&quot;&gt;Source&lt;/a&gt;: Winston Churchill)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Keep that in mind, all you who are considering authoring as a career or career supplement.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Were I to offer my own, it would be like so:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Writing a book is like having a child.&lt;/p&gt;
&lt;p&gt;Trying is the best part, in some ways. You have this idea, this burning sensation in your heart, that just &lt;em&gt;has&lt;/em&gt; to get out into the world. But you need a partner, a publisher who will help you bring your vision to life. You write proposals, you write tables of contents, you imagine the book cover in your mind. Then, YES! You get a publisher to agree. You sign the contract, fax it in, and you are on the way! We are &lt;em&gt;authoring!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;At first, it is wonderful and exciting and full of potential. You run into a few hangups, a few periods of nausea as you realize the magnitude of what you&apos;re really doing. You resolve to press on. As you continue, you begin to feel like you&apos;re in control again, but you start to get this sense like it&apos;s an albatross, a weight around your neck. Before long, you&apos;re dragging your feet, you can&apos;t seem to muster the energy to do anything, just get this thing &lt;em&gt;done&lt;/em&gt;. The deadline approaches, the sheer horror of what&apos;s left to be done paralyzes you. You look your editor in the eye (literally or figuratively) and say, &amp;quot;I can&apos;t do this.&amp;quot; The editor says, &amp;quot;Push&amp;quot;. You whimper, &amp;quot;Don&apos;t make me do this, just cancel the contract.&amp;quot; The editor says, &amp;quot;Push&amp;quot;. You scream at them, &amp;quot;This is YOUR fault, you MADE me do this!&amp;quot; The editor says, &amp;quot;Push&amp;quot;. Then, all of a sudden, it&apos;s done, it&apos;s out, it&apos;s on the shelf, and you take photos and show it off to all the friends, neighbors and family, who look at you a little sympathetically, and don&apos;t mention how awful you really look in that photo.&lt;/p&gt;
&lt;p&gt;As the book is out in the world, you feel a sense of pride an joy at it. You imagine it profoundly changing the way people look at the world. You imagine it reaching bestseller lists. You&apos;re already practicing the speech for the Nobel. You&apos;re sitting in your study, you reach out and grab one of the free copies still sitting on your desk, and you open to a random page. Uh, oh. There&apos;s a typo, or a mistake, or something that clearly got past you and the technical reviewers and the copyeditors. Damn. Oh, well, one mistake can&apos;t make that much difference.&lt;/p&gt;
&lt;p&gt;Then the reviews come in on Amazon. People like it. People post good reviews. One of them is not positive. You get angry: this is your &lt;em&gt;baby&lt;/em&gt; they are attacking. How DARE they. You make plans to find large men with Italian names and track down that reviewer. You suddenly realize your overprotectiveness. You laugh at yourself weakly. You try to convince yourself that there&apos;s no pleasing some people.&lt;/p&gt;
&lt;p&gt;Then someone comes up to you at a conference or interview or other gathering, and says, &amp;quot;Wow, you wrote that? I have that book on my shelf!&amp;quot; and suddenly it&apos;s all OK. It may not be perfect, but it&apos;s yours, and you love it all the same, warts and all.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Nearly a dozen books later, it&apos;s always the same.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>A Dozen Levels of Done</title>
      <link>http://blogs.newardassociates.com/blog/2007/a-dozen-levels-of-done.html</link>
      <pubDate>Wed, 5 Dec 2007 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2007/a-dozen-levels-of-done.html</guid>
      	<description>
	&lt;p&gt;Michael Nygard (author of the &lt;em&gt;great&lt;/em&gt; book &lt;em&gt;Release It!&lt;/em&gt;), writes that &amp;quot;&lt;a href=&quot;http://www.michaelnygard.com/blog/2007/11/a_dozen_levels_of_done.html&quot;&gt;[his] definition of &apos;done&apos; continues to expand&lt;/a&gt;&amp;quot;.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Currently, his definition reads:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A feature is not &amp;quot;done&amp;quot; until all of the following can be said about it:&lt;br /&gt;
* All unit tests are green.&lt;br /&gt;
* The code is as simple as it can be.&lt;br /&gt;
* It communicates clearly.&lt;br /&gt;
* It compiles in the automated build from a clean checkout.&lt;br /&gt;
* It has passed unit, functional, integration, stress, longevity, load, and resilience testing.&lt;br /&gt;
* The customer has accepted the feature.&lt;br /&gt;
* It is included in a release that has been branched in version control.&lt;br /&gt;
* The feature&apos;s impact on capacity is well-understood.&lt;br /&gt;
* Deployment instructions for the release are defined and do not include a &amp;quot;point of no return&amp;quot;.&lt;br /&gt;
* Rollback instructions for the release are defined and tested.&lt;br /&gt;
* It has been deployed and verified.&lt;br /&gt;
* It is generating revenue.&lt;br /&gt;
Until all of these are true, the feature is just unfinished inventory.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As much as I agree with the first 11, I&apos;m not sure I agree with #12. Not because it&apos;s not important--too many software features are added with no positive result--but because it&apos;s too hard to measure the revenue a particular program, much less a particular software &lt;em&gt;feature&lt;/em&gt;, is generating.&lt;/p&gt;
&lt;p&gt;My guess is that this is also conflating the differences between &amp;quot;features&amp;quot; and &amp;quot;releases&amp;quot;, since they aren&apos;t always one and the same, and that not all &amp;quot;features&amp;quot; will be ones mandated by the customer (making #6 somewhat irrelevant). Still, this is an important point to any and all development shops:&lt;/p&gt;
&lt;p&gt;What do &lt;em&gt;you&lt;/em&gt; call &amp;quot;done&amp;quot;?&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>A Book Every Developer Must Read</title>
      <link>http://blogs.newardassociates.com/blog/2007/a-book-every-developer-must-read.html</link>
      <pubDate>Sun, 7 Oct 2007 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2007/a-book-every-developer-must-read.html</guid>
      	<description>
	&lt;p&gt;This is not a title I convey lightly, but Michael Nygard&apos;s &lt;em&gt;Release It!&lt;/em&gt; deserves the honor. It&apos;s the first book I&apos;ve ever seen that addresses the issues of building software that&apos;s Production-friendly and sysadmin-approachable. He describes a series of antipatterns describing a variety of software failures, and offers up a series of solutions (patterns, if you will) to building software systems designed to combat said failures.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;From the back cover:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Every website project is really an enterprise integration project: the stakes are high and the projects complex. In this world where good marketing can be fatal to yor website, where networks are unreliable, and where astronomically unlikely coincidences happen daily, you need all the help you can get.&lt;br /&gt;
...&lt;br /&gt;
You&apos;re a whiz at development. But 80% of typical project lifecyle cost can occur in production--not in development.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Although Michael&apos;s personal experience stems mostly from the Java space, the lessons and stories he offers up are equally relevant to Java, .NET, C++, Ruby, PHP, and any other language or platform you can imagine. Michael Nygard not only knows the Ten Fallacies of Enterprise Development, he &lt;em&gt;breathes&lt;/em&gt; them.&lt;/p&gt;
&lt;p&gt;Go. Now. Buy. Read. Don&apos;t write another line of code until you do.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Hard Questions About Architects</title>
      <link>http://blogs.newardassociates.com/blog/2007/hard-questions-about-architects.html</link>
      <pubDate>Thu, 20 Sep 2007 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2007/hard-questions-about-architects.html</guid>
      	<description>
	&lt;p&gt;I get e-mail from blog readers, and this one--literally--stopped me in my tracks as I was reading. Rather than interpret, I&apos;ll just quote (with permission) the e-mail and respond afterwards.&lt;/p&gt;
&lt;!--more--&gt;
&lt;blockquote&gt;
&lt;p&gt;Hi Ted,&lt;br /&gt;
I had a job interview last Friday which I wanted to share with you. It was for a “Solutions Architect” role with a large Airline here in New Zealand. I had a preliminary interview with the head Architect which went extremely well, and I was called in a few days later for an interview with the other three guys on the Architecture team.&lt;br /&gt;
The second interview started off with the usual pleasantries, and then the technical grilling began with:&lt;br /&gt;
&lt;strong&gt;“What are the best practices that you would put in place on a project?”&lt;/strong&gt;&lt;br /&gt;
I replied “I’ve come to realise that there is no such thing as ’Best Practice’ in architecture – everything is contextual.”&lt;br /&gt;
Well, it went down like a sh*t sandwich! The young German guy who asked the question looked at me like some sort of heretic and said – “ I disagree”. I thought to myself, no damn it – I’m going to push it to see where this guys argument goes, so I said “I can take any best practice you can think of, and by changing the context, I can render that best practice a worst practice”. He didn’t like that very much, but I thought, ‘bugger him, I know I’m right’.&lt;br /&gt;
He then came out with the next question “What do you do when your architectural principles are compromised”. I asked “what do you mean”, and he indicated that an application he designed recently, was found to be far too expensive to implement So he asked again ‘what would you do’?&lt;br /&gt;
I replied “redesign it”. He scoffed at this answer, and reiterated “but what if the redesign was compromising your architectural principles”? So I asked “what is more important. Your principles, or achieving a business objective?”. I don’t remember exactly what his answer was, but it was along the lines of “you have to maintain a corporate standard”.&lt;br /&gt;
His next attack was at extreme programming. Having seen that I had used extreme programming one of my recent projects (in addition to also using waterfall, more recently, on others), he asked “don’t you think that the very risky nature of extreme programming is at odds with it’s ability to deliver software consistently?”. This was a bit of a stunner. I indicated that, once again, it was contextual. XP is appropriate on some projects, but it is not on others. On the XP project I worked on, it was entirely appropriate. We delivered early, within budget, the client got what he wanted, and we got a few million dollars worth of work out of it. Not surprisingly, he didn’t have a lot to say to me after that.&lt;br /&gt;
Having worked as a consultant for a number of years now, I have been entirely focused on adding &lt;b&gt;business value&lt;/b&gt;. I was stunned to hear first hand, how divorced from the business this “architect” was. Clearly he has to maintain some sort of structure with their corporate systems, but surely each business solution should be assessed primarily in the context of it’s own business objectives.&lt;br /&gt;
The interview was good in the respect that I was able to quickly establish that it wasn’t the place for me, but it did leave me with some unanswered questions:&lt;br /&gt;
* How could their idea of an architect (being the policemen of corporate best practice) be so far removed from someone like myself, who aims to make case by case judgements based on pragmatism and experience?&lt;br /&gt;
* Is architecture supposed to be facilitative or restrictive?&lt;br /&gt;
* What relevance do architects have today? Are they just overpaid, out of touch developers?&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Shane Paterson&lt;br /&gt;
Hands on Architect Type&lt;br /&gt;
(for lack of a more relevant title)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Wow.&lt;/p&gt;
&lt;p&gt;For starters, Shane, kudos to you for sticking to your guns, and for figuring out really quickly that this was clearly not a place you wanted to work--a lot of developers have a mentality that says that they need the company more than the company needs them, sort of a &amp;quot;job at any price&amp;quot; mindset. Interviews aren&apos;t supposed to be the place where candidates grovel and say whatever the company wants them to hear--an interview is supposed to be a vetting process for both sides.&lt;/p&gt;
&lt;p&gt;But on to your questions:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;How could their idea of an architect be so far removed from someone like myself?&lt;/em&gt; I can&apos;t answer this one solidly, but I can say that the definition of an architect seems to be vague and indiscriminate a term, only exceeded in opacity by the term &amp;quot;software&amp;quot; itself. For some companies I&apos;ve worked for, the &amp;quot;architect&amp;quot; was as you describe yourself, someone whose hands were dirty with code, acting as technical lead, developer, sometimes-project-manager, and always focused on customer/business value as well as technical details. At other places, the architect (or &amp;quot;architect team&amp;quot;) was a group of developers who had to be promoted (usually due to longevity) with no clear promotion path available to them other than management. This &amp;quot;architect team&amp;quot; then lays down &amp;quot;corporate standards&amp;quot;, usually based on &amp;quot;industry standards&amp;quot;, with little to no feedback as to the applicability of their standards to the problems faced by the developers underneath them. A friend of mine on the NFJS tour, Brian Sletten, tells a story of how he consulted on a project, implementing the (powerful) 1060 Netkernel toolkit at the core of the system, to resounding success. Then, on deployment, the &amp;quot;architecture team&amp;quot; took a look, pronounced the system to be incompatible with their &amp;quot;official standards&amp;quot;, and &lt;em&gt;forced new development of a working product&lt;/em&gt;. In other words, the fact that it worked (and could easily be turned to interoperate with their SOAP-based standard, of which there were zero existing services) was in no way going to stand as an impediment to their enforcement of the corporate standard.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Is architecture supposed to be facilitative or restrictive?&lt;/em&gt; Ah, this is a harder one to answer. In essence, both. Now, before the crowd starts getting out their torches and pitchforks to have a good old-fashioned lynching, hear me out.&lt;/p&gt;
&lt;p&gt;Architecture is intended to be facilitative, of course, in that a good architecture should enable developers to build applications quickly and easily, without having to spend significant amounts of time re-inventing similar infrastructure across multiple projects. A good architecture will also facilitate interoperability across applications, ensure a good code quality, ensure good maintainability, provide for future extensibility, and so on. All of this, I would argue, falls under the heading of &amp;quot;facilitation&amp;quot;.&lt;/p&gt;
&lt;p&gt;But an architecture is also intended to be restrictive, in that it should channel software developers in a direction that leads to all of these successes, and away from potential decisions that would lead to prolems later. In other words, as Microsoft&apos;s CLR architect Rico Mariani put it, a good architecture should enable developers to &amp;quot;fall into the pit of success&amp;quot;, where if you just (to quote the proverbial surfer) &amp;quot;go with the flow&amp;quot;, you make decisions that lead to all of those good qualities we just discussed.&lt;/p&gt;
&lt;p&gt;This is asking a lot of an architecture, granted. But that&apos;s the ideal.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;What relevance do architects have today?&lt;/em&gt; Well, this is a dangerous question, in that you&apos;re asking it of one who considers himself an architect and technologist, so take this with the usual grain of salt. Are we just overpaid out-of-touch developers? God, I hope not. Fowler talks about architecture being irrelevant in an agile project, but I disagree with that notion pretty fundamentally: an architect is the captain of the ship, making the decisions that cross multiple areas of concern (navigation, engineering, and so on), taking final responsibility for the overall health of the ship and its crew (project and its members), able to step into any station to perform those duties as the need arises (write code for any part of the project should they lose a member). He has to be familiar with the problem domain, the technology involved, and keep an eye out on new technologies that might make the project easier or answer new customers&apos; feature requests.&lt;/p&gt;
&lt;p&gt;And if anybody stands up at this point and says, &amp;quot;Hey, wait a minute, that&apos;s a pretty tall order for anybody to fill!&amp;quot;, then you start to get an idea of why architects do, frequently, get paid more than developers do. Having to know the business, the technology at a high and low level of detail, keeping your hands in the code, and watching the horizon for new developments in industry, is a pretty good way to burn out any free time you might have thought you&apos;d have.&lt;/p&gt;
&lt;p&gt;Granted, all of these answers notwithstanding, there&apos;s a large number of &amp;quot;architects&amp;quot; out there whose principal goal is to simply remain employed. To do that, they cite &amp;quot;best practices&amp;quot; established by &amp;quot;industry experts&amp;quot; as a cover for making decisions of their own, because nobody ever gets fired for choosing what industry &amp;quot;best practices&amp;quot; dictate. That&apos;s partly why I hate that term: it&apos;s a cop-out. It&apos;s basically relying on articles on popular websites and magazines to do your thinking for you. Inevitably, when somebody at a conference says the word, &amp;quot;Best Practice&amp;quot;, listeners&apos; minds turn off, their pens turn on, and they dutifully enscribe this bit of knowledge into their projects at home, &lt;em&gt;without considering the applicability to their project or corporate culture&lt;/em&gt;. Nothing, not a single technology, not a single development methodology, not even a single tool, is &lt;em&gt;always&lt;/em&gt; the right answer.&lt;/p&gt;
&lt;p&gt;In the end, I think what Shane ran into was an &amp;quot;architect&amp;quot; with an agenda and an alpha-geek complex. He refused to consider somebody with a competing point of view, because God forbid somebody show him &lt;em&gt;not&lt;/em&gt; to be the expert he&apos;s hoodwinked everybody else at work to think he is. Unfortunately I&apos;ve run across this phenomenon too often to call it statistical error, and the only thing you can do is to do exactly what you did, Shane: get the hell out of Dodge.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The First Strategy: Declare War on your Enemies</title>
      <link>http://blogs.newardassociates.com/blog/2007/the-first-strategy-declare-war-on-your-enemies-the-polarity-strategy.html</link>
      <pubDate>Sat, 28 Jul 2007 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2007/the-first-strategy-declare-war-on-your-enemies-the-polarity-strategy.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;Software is endless battle and conflict, and you cannot develop effectively unless you can identify the enemies of your project. Obstacles are subtle and evasive, sometimes appearing to be strengths and not distractions. You need clarity. Learn to smoke out your obstacles, to spot them by the signs and patterns that reveal hostility and opposition to your success. Then, once you have them in your sights, have your team declare war. As the opposite poles of a magnet create motion, your enemies--your opposites--can fill you with purpose and direction. As people and problems that stand in your way, who represent what you loathe, oppositions to react against, they are a source of energy. Do not be naive: with some problems, there can be no compromise, no middle ground.&lt;/em&gt;&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;In the early 1970s, Margaret Thatcher shook up British politics by refusing to take the style of the politicians before her: where they were smooth and conciliatory, she was confrontational, attacking her opponents directly. She bucked the conventional wisdom, attacking her opponents mercilessly where historically politicians sought to reassure and compromise. Her opponents had no choice but to respond in kind. Thatcher&apos;s approach polarized the population, seizing the attention, attracting the undecided and winning a sizable victory.&lt;/p&gt;
&lt;p&gt;But now she had to rule, and as she continued down her obstinate, all-in style of &amp;quot;radicalism&amp;quot; politics, she seemed to gain more enemies than any one politician could hold off. Then, in 1982, Argentina attacked the British Falkland Islands in the South Atlantic. Despite the distance--the Falklands were almost diametrically opposite the globe from the British home islands, off the tip of South America--Thatcher never hesitated, dispatching the British armed forces to respond to the incursion with deadly force, and the Argentinians were beaten. Suddenly, her obstinacy and radicalism were seen in a different light: courage, nobility, resolute and confident.&lt;/p&gt;
&lt;p&gt;Thatcher, as an outsider (a middle-class woman and a right-wing radical), chose not to try and &amp;quot;fit in&amp;quot; with the crowd, but to stake her territory clearly and loudly. Life as an outsider can be hard, but she knew that if she tried to blend in, she could easily be replaced. Instead, she set herself up at every turn as one woman against an army of men.&lt;/p&gt;
&lt;p&gt;As Greene notes,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We live in an era in which people are seldom directly hostile. The rules of engagement--social, political, military--have changed, and so must your notion of the enemy. An up-front enemy is rare now and is actually a blessing. ... Although the world  is more competitive than ever, outward aggression is discouraged, so people have learned to go underground, to attack unpredictably and craftily. ... Understand: the word &apos;enemy&apos;--from the Latin &lt;em&gt;inimicus&lt;/em&gt;, &amp;quot;not a friend&amp;quot;--has been demonized and politicized. Your first task as a strategist is to widen your concept of the enemy, to include in that group those who are working against you, thwarting you, even in subtle ways.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Software projects face much the same kind of problem: there are numerous forces that are at work trying to drag the project down into failure. While agile books love to assume an environment in which the agile methodology is widely accepted and embraced, reality often intrudes in very rude ways. Sometimes management&apos;s decision to &amp;quot;go agile&amp;quot; is based not to try and deliver software more successfully, but to simply take the latest &amp;quot;fad&amp;quot; and throw it into the mix, such that when it fails, management can say, &amp;quot;But we followed industry best practices, it clearly can&apos;t be &lt;em&gt;management&lt;/em&gt; at fault.&amp;quot; (This is the same idea behind the statement, &amp;quot;Nobody ever got fired for buying IBM (or Microsoft or Java or ...).&amp;quot; Sometimes the users are not as committed to the project as we might hope, and at times, the users are even contradictory to one another, as each seeks to promote their own agenda within the project.&lt;/p&gt;
&lt;p&gt;As a software development lead (or architect, or technical lead, or project manager, or agile coach, or whatever), you need to learn how to spot these enemies to your project, identify them clearly, and make it clear that you see them as an enemy that will not be tolerated. This doesn&apos;t mean always treat them openly hostile--sometimes the worst enemies can be turned into the best friends, if you can identify what drives them to the position that they take, and work to meet their needs. Case in point: system administrators frequently find themselves at odds with developers, because the developer seeks (by nature) to change the system, and sysadmins seek (by nature) to keep everything &lt;em&gt;status quo&lt;/em&gt;. Recognizing that sysadmins have historically been blindsided by projects that essentially ignored &lt;em&gt;their&lt;/em&gt; needs (such as a need to know that the system is still running, or the need to be able to easily add users, change security policies, or diagnose failures quickly at 3AM in the morning) means that we as developers can either treat them as enemies to be overcome, or win them as friends by incorporating their needs into the project. But they are either &amp;quot;for us&amp;quot; or &amp;quot;against us&amp;quot;, and not just a group to be ignored.&lt;/p&gt;
&lt;p&gt;Other enemies are not to be tolerated at any level: apathy, sloth, or ignorance are all too common among developer teams. Ignorance of how underlying technologies work. Apathy as to the correctness of the code being created. Sloth in the documentation or tests. These are enemies that, given enough time and inattention, will drag the project down into the tar pits of potential failure. They cannot be given any quarter. Face them squarely, with no compromise. Your team, if they hold these qualities, must be shown that there is no tolerance for them. Hold brown-bag lunches once a week to talk about new technologies, and their poential impact on the team or company or project. Conduct code reviews religiously, during active development (rather that at the end as a token gesture), with no eye towards criticizing the author of the code, but the code itself. Demand perfection in the surrounding artifacts of the project: the help files, the user documentation, the graphics used for buttons and backdrops and menus.&lt;/p&gt;
&lt;p&gt;Do not wait for the enemies of your project to show themselves, either--actively seek them out and crush them. Take ignorance, for example. Do not just &amp;quot;allow&amp;quot; each of your developers to research new technologies, but demand it of them: have each one give a brown-bag presentation in turn. In a four-man team, this means that each developer will have a month in which to find something new to discover, analyze, discuss and present. They do not have to have all the answers to the technology, and in fact, if the technology is sufficiently large or interesting, they can spend the next month investigating a new element or new use of the technology. Demanding this of your developers means they are forced to educate themselves, and forced to raise their own awareness of the changing world. (Naturally, developers must be given time to do this research; anecdotally, giving them Friday afternoons to do this experimentation and research, when energy and interest in the work week is already typically at an ebb, works well.)&lt;/p&gt;
&lt;p&gt;Wherever possible, avoid enemies that are large and hard to pinpoint. Simply saying &amp;quot;We need to have better quality code&amp;quot; is too amorphous and too vague. Developers have nothing to measure against. Personalize your enemies, eyeball to eyeball. Put names to them, make them clearly visible to all involved. &amp;quot;We will have 100% code coverage in our unit tests&amp;quot; is a clearly-defined goal, and anything that prevents that goal from being reached will be clearly visible. &amp;quot;We will not ship code that fails to pass any unit test&amp;quot; is another clear goal, but must be paired with something that avoids the natural &amp;quot;Well, then, we&apos;ll not write any unit tests, and we&apos;ll have met that goal!&amp;quot; response. Demanding a ratio of unit-test-lines-to-lines ratio is a good start: &amp;quot;We will have three lines of unit test code per line of code&amp;quot; now offers a measurable, identifiable enemy that can be stared in the face. Go so far as to make a ceremony out of it: call the developers into a room, put a poster on a wall, and make your intentions clear. Motivate them. &amp;quot;When we presented the release of the payroll system to the HR department last year, the users called it &apos;barely acceptable&apos; and &apos;hard to use&apos;. I &lt;em&gt;refuse&lt;/em&gt; to allow that to happen again. The system we build for them this year will be amazing. It will be reliable. It will have those features they need to get their job done &lt;em&gt;(and be specific here)&lt;/em&gt;, and we will accept no excuse otherwise.&amp;quot;&lt;/p&gt;
&lt;p&gt;One of the world&apos;s most successful software companies, Microsoft is no stranger to the polarity strategy. The company as a whole as declared war on its enemies in a variety of fields, and with few exceptions, has won in almost every conflict. Microsoft actively courts conflict and confrontation. The presence of a well-established competitor in a particular field is no barrier to entry; Microsoft has routinely entered fields with dominant competitors and come out ahead in the end. Witness their entries into the word-processor and spreadsheet markets held at the time by dominant competitors WordPerfect and Lotus 1-2-3, their entry into the video-game console market against well-established competitors Sega and Nintendo, and more recently, the mobile entertainment device market (the Zune) against the iPod. In the latter, the battle has just begun, and the market remains firmly in the hands of the iPod, but let it not be forgotten that Microsoft is not one to retreat quickly from a battle.&lt;/p&gt;
&lt;p&gt;Microsoft is also known to do this within their projects; developers who are committed to a project yet seem hesitant or lax in their work are asked if they are really &amp;quot;on board&amp;quot; with this project. The legends of Microsoft developers putting in 80-plus hours a week on a project are somewhat true, but not because Microsoft management expects it of them, but because developers have been willing to put that kind of time into the project in order to succeed.&lt;/p&gt;
&lt;p&gt;And Microsoft management itself has declared war on its enemies, time and again, looking to eliminate any and all opposition the successful release of software. Distractions? Every developer gets his own office. Household chores? Microsoft has been known to offer their developers laundry services at work. Computing resources? It&apos;s not at all uncommon to walk into a Microsoft developers&apos; office and see multiple CPUs (under desks, in corners, laptops, and so on) and monitors all over the room. Bodily needs? Refrigerators on every floor, stocked with sodas of every variety, water, juices, anything that the thirsty developer could need, all free for the taking. Even fatigue is an enemy: Microsoft buildings have video game consoles, foosball tables, bean bag chairs, and more tools of relaxational activities to help the developer take a break when necessary, so that they can resume the fight refreshed.&lt;/p&gt;
&lt;p&gt;Greene notes further,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are always hostile people and destructive relationships. The only way to break out of a negative dynamic is to confront it. Repressing your anger, avoiding the person threatening you, always looking to conciliate--these common strategies spell ruin. Avoidance of conflict becomes a habit, and you lose the taste for battle. Feeling guilty is pointless; it is not your fault you have enemies. Feeling wronged or victimized is equally futile. In both cases you are looking inward, concentrating on yourself and your feelings. Instead of internalizing a bad situation, externalize it and face your enemy. It is the only way out.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To adapt this to software, instead of simply talking about the hopeless situation in which you find yourself--your company has no interest in agile, your team is just too &amp;quot;inexperienced&amp;quot; to tackle the kinds of projects you are being given, and so on--externalize it. Face the enemy. Your company has no interest in agile? Fine--instead of trying to talk them into it, take the radical approach, &lt;em&gt;do&lt;/em&gt; a project in an agile fashion (even without upper management&apos;s knowledge if necessary), and show them the results. Can&apos;t get the IT budget to allow for a source-control server or continuous integration server? Use your desktop machine instead. Face the enemy, confront it, and defeat it.&lt;/p&gt;
&lt;p&gt;Enemies are not evil, and should not be seen as something to avoid. Enemies give us something against which to measure ourselves, to use as a foil against which to better ourselves. They motivate and focus your beliefs. Have a co-worker who refuses to see the benefits of dynamic languages? Avoiding him simply avoids an opportunity for you to learn from him and to better your arguments and approaches. Have a boss who doesn&apos;t see what the big deal behind a domain-specific language is? Have conversations on the subject, to understand her reluctance and opposition, and build a small DSL to show her the benefits of doing so. Don&apos;t avoid these people, for they offer you opportunities to better yourself and your understanding.&lt;/p&gt;
&lt;p&gt;Enemies also give you a standard against which to judge yourself. It took Joe Frazier to make Muhammad Ali a truly great boxer. The samurai of Japan had no guage of their excellence unless they challenged the best swordsmen they could find. For the Indianapolis Colts of last year, each victory was hollow unless they could beat their arch-rivals, the New England Patriots. The bigger the opponent, the greater your reward, even in defeat, for if you lose, you have opportunities to analyze the results and discover how and why you lost, then correct your strategy for the next time. For there will &lt;em&gt;always&lt;/em&gt; be a next time.&lt;/p&gt;
&lt;p&gt;Don&apos;t seek to eschew enemies, either. Enemies give us options and purpose. Julius Caesar identified Pompey as his enemy early in his rise to the throne. Everything he did from then on was measured against Pompey, to put him in a stronger position to meet his enemy. Once he defeated Pompey, however, Caesar lost his way, and eventually fell because he viewed himself as a god and above all other men. Enemies force on you a sense of realism and humility.&lt;/p&gt;
&lt;p&gt;Remember, enemies surround you and your project, and sometimes even within your project. Keep a sharp eye out, so that once spotted, they can be identified, analyzed, and handled. Show no quarter to those enemies: they must either join you to help you in your quest to build great software, or be ruthlessly eliminated from your path. They can either benefit from the project, or they can be removed from the battlefield entirely. Some enemies--ignorance, apathy, sloth--are not easily defeated, nor once defeated will they remain so. Never lay down your arms against them or trust your arms to someone else--you are the last line of your own defense.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The 33 Strategies of Software Development</title>
      <link>http://blogs.newardassociates.com/blog/2007/the-strategies-of-software-development.html</link>
      <pubDate>Fri, 13 Jul 2007 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2007/the-strategies-of-software-development.html</guid>
      	<description>
	&lt;p&gt;At a software conference not too long ago, I was asked what book I was currently reading that I&apos;d recommend, and I responded, &amp;quot;Robert Greene&apos;s &lt;em&gt;The 33 Strategies of War&amp;quot;&lt;/em&gt;. When asked why I&apos;d recommend this, the response was pretty simple: &amp;quot;Because I believe that there&apos;s more parallels to what we do in military history than in constructing buildings.&amp;quot;&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Greene&apos;s book is an attempt at a distillation of what all the most successful generals and military leaders throughout history used to make them so successful. A lot of these concepts and ideas are just generally good practices, but a fair amount of them actually apply pretty directly to software development (whether you call it &amp;quot;agile&amp;quot; or not). Consider this excerpt from the Preface, for example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The war [that exists in the real world] exists on several levels. Most obviously, we have our rivals on the other side. The world has become increasingly competitive and nasty. In politics, business, even the arts, we face opponents who will do almost anything to gain an edge. More troubling and complex, however, are the battles we face with those who are supposedly on our side. There are those who outwardly play the team game, who act very friendly and agreeable, but who sabotage us behind the scenes, ues the group to promote their own agenda. Others, more difficult to spot, play subtle games of passive aggression, offering help that never comes, instilling guilt as a secret weapon. On the surface everything seems peaceful enough, but just below it, it is every man and woman for him- or herself, this dynamic infecting even families and relationships. The culture may deny this reality and promote a gentler picture, but we know it and feel it, in our battle scars.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Without trying to paint a paranoid picture, this &amp;quot;dynamic of war&amp;quot; frequently infects software development teams and organizations; developers vs. management, developers vs. system adminstrators, developers vs. DBAs, even developers vs. architects or developers vs. developers. His book, then, suggests that we need to face this reality and learn how to deal with it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What we need are not impossible and inhuman ideals of peace and cooperation to live up to, and the confusion that brings us, but rather practical knowledge on how to deal with conflict and the daily battles we face. And this knowledge is not about how to be more forceful in getting what we want or defending ourselves but rather how to be more rational and strategic when it comes to conflict, channeling our aggressive impulses instead of denying or repressing them. If there is an ideal to aim for, it should be that of the strategic warrior, the man or woman who manages difficult situations and people through deft and intelligent maneuver.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;... and I want that man or woman heading up my project team.&lt;/p&gt;
&lt;p&gt;It may seem incongruous to draw parallels between war and software development, because in war there is an obvious &amp;quot;enemy&amp;quot;, an obvious target for our aggression and intentions and strategies and tactics. It turns out, however, that the &amp;quot;enemy&amp;quot; in software development is far more nebulous and amorphous, that of &amp;quot;failure&amp;quot;, which can be just as tenacious and subversive. This enemy won&apos;t ever try to storm your cubicles and kill you or try to hold you for ransom, but a lot of the strategies that Greene talks about aren&apos;t so much about how to kill people, but how to think strategically, which is, to my mind, something we all of us have to do more of.&lt;/p&gt;
&lt;p&gt;Consider this, for example; Greene suggests &amp;quot;six fundamental ideals you should aim for in transforming yourself into a strategic warrior in daily life&amp;quot;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Look at things as they are, not as your emotions color them&lt;/em&gt;. Too often, it&apos;s easy to &amp;quot;lose your head&amp;quot; and see the situation in emotional terms, rather than rational ones. &amp;quot;Fear will make you overestimate the enemy and act too defensively&amp;quot;; in other words, fear will cause you to act too conservatively and resist taking the necessary gamble on a technology or idea that will lead to success. &amp;quot;Anger and impatience will draw you into rash actions that will cut off your options&amp;quot;; or, anger and impatience will cause you to act rashly with respect to co-workers (such as DBAs and sysadmins) or technology decisions that may leave you with no clear path forward. &amp;quot;The only remedy is to be aware that the pull of emotion is inevitable, to notice it when it is happening, and to compensate for it.&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Judge people by their actions&lt;/em&gt;. &amp;quot;What people say about themselves [on resumes, in meetings, during conversations] does not matter; people will say anything. Look at what they have done; deeds do not lie.&amp;quot; Which means, you have to have a way by which to measure those deeds, meaning you have to have a good &amp;quot;feel&amp;quot; for what&apos;s going on in your department--simply listening to reports in meetings is often not enough. &amp;quot;In looking back at a defeat [failed project], you must identify the things you could have done differently. It is your own bad strategies, not the unfair opponent [or management decisions or unhelpful IT department, or whatever], that are to blame for your failures. You are responsible for the good and bad in your life.&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Depend on your own arms&lt;/em&gt;. &amp;quot;... people tend to rely on things that seem simple and easy or that have worked before. ... But true strategy is psychological--a matter of intelligence, not material force. ... But if your mind is armed with the art of war, there is no power that can take that away. In the middle of a crisis, your mind will find its way to the right solution. ... As Sun-tzu says, &apos;Being unconquerable lies with yourself.&apos; &amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Worship Athena, not Ares&lt;/em&gt;. This one probably doesn&apos;t translate directly; Athena was the goddess of war in its form seen in guile, wisdom, and cleverness, whereas Ares was the god of war in its direct and brutal form. Athena always fought with the utmost intelligence and subtlety; Ares fought for the sheer joy of blood. Probably the closest parallel here would be to suggest that we seek subtle solutions, not brute force ones, meaning look for answers that don&apos;t require hiring thousands of consultants and developers. But that&apos;s a stretch.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Elevate yourself above the battlefield&lt;/em&gt;. &amp;quot;In war, strategy is the art of commanding the entire miliary operation. Tactics, on the other hand, is the skill of forming up the army for battle [project] itself and dealing with the immediate needs of the battlefield. Most of us in life are tacticians, not strategists.&amp;quot; Too many project managers (and team members) never look beyond the immediate project in front of them to consider the wider implications of their actions. &amp;quot;To have the power that only strategy can bring, you must be able to elevate yourself above the battlefield, to focus on your long-term objectives, to craft an entire campaign, to get out of the reactive mode that so many battles in life lock you into. Keeping your overall goals in mind, it becomes much easier to decide when to fight [or accept a job or accept a project] and when to walk away.&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Spiritualize your warfare&lt;/em&gt;. &amp;quot;... the greatest battle is with yourself--your weaknesses, your emotions, your lack of resolution in seeing things through to the end. You must declare unceasing war on yourself. As a warrior in life, you welcome combat and conflict as ways to prove yourself, to better your skills, to gain courage, confidence and experience.&amp;quot; That means we should never let fear or doubt stop us from tackling a new challenge (but, similarly, we shouldn&apos;t risk others&apos; welfare on wild risks). &amp;quot;You want more challenges, and you invite more war [or projects].&amp;quot;&lt;/ul&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Granted, it&apos;s not a complete 1-to-1 match, but there&apos;s a lot that the average developer can learn from the likes of Sun-Tzu, MacArthur, Julies Caesar, Genghis Khan, Miyamoto Musashi, Erwin Rommel, or Carl von Clausewitz.&lt;/p&gt;
&lt;p&gt;Just for reference purposes, the original 33 strategies (some of which may not be easy or even possible to adapt) are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Declare war on your enemies: The Polarity Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Do not fight the last war: The Guerilla-War-of-the-Mind Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Amidst the turmoil of events, do not lose your presence of mind: The Counterbalance Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a sense of urgency and desperation: The Death-Ground Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Avoid the snares of groupthink: The Command-and-Control Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Segment your forces: The Controlled-Chaos Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Transform your war into a crusade: Morale Strategies&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pick your battles carefully: The Perfect-Economy Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Turn the Tables: The Counterattack Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a threatening presence: Deterrence Strategies&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Trade space for time: The Nonengagement Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lose battles but win the war: Grand Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Know your enemy: The Intelligence Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Overwhelm resistance with speed and suddenness: The Blitzkrieg Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Control the dynamic: Forcing Strategies&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hit them where it hurts: The Center-of-Gravity Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Defeat them in detail: The Divide-and-Conquer Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Expose and attack your opponent&apos;s soft flank: The Turning Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Envelop the enemy: The Annihiliation Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Maneuver them into weakness: The Ripening-for-the-sickle Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Negotiate while advancing: The Diplomatic-War Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Know how to end things: The Exit Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Weave a seamless blend of fact and fiction: Misperception Strategies&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Take the line of least expectation: The Ordinary Extraordinary Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Occupy the moral high ground: The Righteous Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Deny them targets: The Strategy of the Void&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Seem to work for the interests of others while furthering your own: The Alliance Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Give your rivals enough rope to hang themselves: The One-Upmanship Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Take small bites: The Fait Accompli Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Penetrate their minds: Communication Strategies&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Destroy them from within: The Inner-Front Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dominate while seeming to submit: The Passive-Aggression Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sow uncertainty and panic through acts of terror: The Chain-Reaction Strategy&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What I&apos;m planning to do, then, is go through the 33 strategies of war, analogize as necessary/possible, and publishthe results. Hopefully people find it useful, but even if you don&apos;t think it&apos;s going to help, it&apos;ll help me internalize the elements I want to through the process just for my own use. And, in the end, that&apos;s the point of &amp;quot;spiritualize your warfare&amp;quot;: trying to continuously enhance yourself.&lt;/p&gt;
&lt;p&gt;Naturally, I invite comment and debate; in fact, I&apos;d really encourage it, because I&apos;m not going to promise that these are 100%-polished ideas or concepts, at least as how they apply to software. So please, feel free to comment, either publicly on the blog or privately through email, whether you agree or not. (Particularly if you don&apos;t agree--the more the idea is tested, the better it stands, or the sooner it gets refactored.)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The relational database needs no &quot;defense&quot;</title>
      <link>http://blogs.newardassociates.com/blog/2007/the-relational-database-needs-no-defense.html</link>
      <pubDate>Mon, 11 Jun 2007 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2007/the-relational-database-needs-no-defense.html</guid>
      	<description>
	&lt;p&gt;Anyone who is deeply enmeshed in a technology feels compelled to defend that technology when any sort of &amp;quot;threat&amp;quot; (or perception of threat) appears on the horizon, and apparently Gavin is no different. Sure enough, as people (apparently in this case, myself) start to talk about approaches to persistence that don&apos;t involve Hibernate, Gavin feels compelled to point to these other technologies using inflammatory terms and a certain amount of FUD. I felt a certain responsibility to respond, since it seems that he&apos;s taking a direct shot at the db4o articles I&apos;ve written and discussed before.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;(By the way, it&apos;s also entirely possible that he&apos;s taking aim against ActiveRecord and Rails, which I don&apos;t consider to be an &amp;quot;object database&amp;quot; at all; if that&apos;s the case, then I apologize ahead of time for misunderstanding the intent--and the points--of the piece. But the arguments he makes seem pretty relevant to the OODBMS-vs-RDBMS discusison as well, so much so that it was a db4o employee who pointed out the blog entry to me in the first place. In any event, though, Gavin&apos;s piece raises some issues that deserve to be discussed, regardless of the context of Rails or OODBMSs.)&lt;/p&gt;
&lt;p&gt;First of all, let me state quite clearly, &lt;i&gt;the relational database needs no defense&lt;/i&gt;. Take whatever comparitive criteria you like, the RDBMS has been, and will, in the absence of a nearly catastrophic change to the contrary, continue to be, the choice of businesses all over the world for storing data in a format that&apos;s easily-accessed from a variety of different systems. The RDBMS clearly &amp;quot;owns&amp;quot; the corporate data center, from Fortune X&apos;s (meaning X can be just about any number you choose to put there) down through single-person shops. To shake that kind of (dare I say it?) monopoly would require a kind of technology shift on the scale of the move from the mini- and mainframe to the PC. Those kinds of shifts don&apos;t happen very often, and when they do, it&apos;s because of a huge competitive advantage.&lt;/p&gt;
&lt;p&gt;Furthermore, I wil go on the record and say it here: neither the OODBMS nor the HODBMS (hierarchically-oriented database system, a la the &amp;quot;XML database&amp;quot;) makes that kind of case. Not right now, and probably not ever. They have compelling reasons for existence, but not so strong a case that they could displace the RDBMS from the &amp;quot;enterprise data&amp;quot; throne. That said, however, since when does one tool solve &lt;i&gt;all&lt;/i&gt; problems? They have their own &lt;i&gt;raisons d&apos;etre&lt;/i&gt;, and to simply say that the OODBMS or HODBMS should be ignored just because &amp;quot;we&apos;ve always used an RDBMS&amp;quot; is a crime just as great.&lt;/p&gt;
&lt;p&gt;Now, having said that, let&apos;s take a look at Gavin&apos;s points:&lt;/p&gt;
&lt;li&gt;&lt;i&gt;&quot;Object databases were a total failure and still are.&quot;&lt;/i&gt; Actually, he&apos;s right, from the perspective that the OODBMS clearly has not penetrated the corporate environment to the same degree that the RDBMS has. But, by that same token, the RDBMS, nearly a decade after its introduction, had about the same degree of success. Ask the folks who were around when Oracle 1 was released, and they&apos;ll tell you about the criticisms leveled at the RDBMS that are, in a startling replay of the past, now being applied to the OODBMS today. The first generation of &lt;i&gt;anything&lt;/i&gt; is always crap... including O/R-Ms. Fortunately for both O/R-Ms and OODBMSs, neither is in their first generation stage anymore.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;&quot;the systems are often not called &quot;object databases&quot; in today&apos;s marketing literature, but we will call them that anyway, since that is what they are.&quot;&lt;/i&gt; Actually, all of the OODBMS vendors are pretty ready to call themselves OODBMSs, and I have to say, Gavin, you&apos;d know that if you talked to them for more than, say, 30 seconds, or took the time to research the subject and &lt;i&gt;listen&lt;/i&gt; to what they had to say. The folks who don&apos;t bother calling their systems &quot;object databases&quot; anymore are the very folks he&apos;s defending: Oracle, DB/2, and so on. (Anybody remember &quot;Oracle Objects&quot;? Table + sprocs == objects? Oy, what a mess.) But don&apos;t feel too bad, Gavin, you&apos;re in good company--Chris Date himself makes this same mistake (though he at least admits that true &quot;object&quot; support in the database model requires features that aren&apos;t present in todays RDBMS products, not that he&apos;s a big fan of those products anyway), so at least you&apos;re in good comapny. (Again, if you&apos;re talking Rails being an &quot;object database&quot;, total agreement, it&apos;s not even close. But in all the years I&apos;ve been hanging out with Dave Thomas, Bruce Tate, Stu Halloway, Justin Gehtland, and a bunch of the other Rails advocates/evangelists/lecturers/authors, I&apos;ve never heard any of them make this assertion.)&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Object-relational mapping isn&apos;t that hard, so there&apos;s no need to eliminate it.&lt;/i&gt; Sorry, Gavin, but the fact is, this remains, and always will remain, a point of difference between you and I, and between you and a fairly large number of developers I&apos;ve spoken to over the years at conferences and consulting engagements and classes. For simple table-to-class mappings, you&apos;re right, it&apos;s a pretty simple thing. It is, however, still a &quot;dual schema&quot; problem, in that now you have two competing &quot;sources of truth&quot; that have to be reconciled to one another, the database schema, and the object model. Now, perhaps if all the projects you&apos;ve ever done are projects where the developer gets to define both, then the problem doesn&apos;t appear, but if you&apos;re in an &quot;enterprise&quot; world where the database schema is managed by a team of DBAs and is shared across projects, you don&apos;t have the flexibility to &quot;refactor&quot; the schema like you can your object model. (Anyone who&apos;s ever tried to build a CORBA or DCOM system that stretches across corporate or division or department boundaries understands the problems of trying to create a domain model--or schema--that serves all groups well without sacrificing performance, elegance, or normal form.) I particularly like this statement:
&lt;blockquote&gt;
So, from this point of view, ORM is at least as good as an object database for all usecases, and handles other usecases (indeed, the common cases) which the object database approach does not.
&lt;/blockquote&gt;
... particularly since he doesn&apos;t bother to go on to describe those use cases that the ORM handles that the OODBMS does not. Examples? &apos;Tis very easy to make assertions, but without backing them up....
&lt;/li&gt;
&lt;li&gt;Oh, and the comment that &quot;If you just want to &quot;throw some objects in the database&quot;, you&apos;ll never need to write a single mapping annotation.&quot; really sort of proves the point I try to make in the ODMG.org paper: if you just want to &quot;throw some objects in the database&quot;, why do you bother having an RDBMS in the first place? There are DBAs that are in open revolt at the idea, particularly since you&apos;ve also just conveniently left out any sort of indexing or other tuning decisions that will make the database perform at all reasonably. But, I suppose, if you&apos;re willing to argue &quot;&lt;i&gt;development speed uber alles&quot;&lt;/i&gt;, then sure, go ahead. Never mind the fact that an OODBMS will handle this exact situation, because that&apos;s exactly what they were made for. I repeat the statements I made in the ODMB paper: if you want persistence to just be an implementation detail, then why bother with the RDBMS in the first place? (It&apos;s not like any self-respecting DBA is going to want to take your slapdash relational schema, anyway...)&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Don&apos;t use the OODBMS because it creates a tight coupling between your code and your data storage, and the language you use today won&apos;t necessarily be around tomorrow.&lt;/i&gt; Um... exactly. This is, surprisingly enough, exactly the point I&apos;m trying to make in the ODMG paper: that an OODBMS creates a tight coupling between code and data, and sometimes, that&apos;s &lt;i&gt;not&lt;/i&gt; what you want. Nothing is a silver bullet, everything comes with a price and a consequence of using it. It&apos;s only the honest vendors that will tell you when not to use their stuff, and from experience, the db4o guys (the only ones I can concretely speak to) are the first to stand up and tell you that they aren&apos;t trying to replace the RDBMS. So why spread the FUD that they are?&lt;/li&gt;
&lt;li&gt;&lt;i&gt;OODBMSs are trying to pull the wool over your eyes with benchmarks.&lt;/i&gt; So, again, rather than display his own benchmark that directly contradicts the benchmark offered by the OODBMS folks, Gavin chooses to say, &quot;Look at all the reasons why they run faster, and look, these reasons are all clearly bogus.&quot; Which is kind of astute of him: lawyers are taught in law school that if the law isn&apos;t on your side, argue the facts, and if the facts aren&apos;t on your side, argue the law, and if neither is on your side, argue really really loudly. Toss out a benchmark of your own, Gavin, and then we can discuss the decisions you make in your benchmark and see if they&apos;re reasonable decisions to make for my own projects, so I can make an informed decision, rather than one based on your assertions and loud arguments that amount to &quot;Duh!&quot;.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;OODBMSs are faster because they run in-process.&lt;/i&gt; Some do, yes. Most can run either in-proc or out-of-proc, which (gasp!) is something that RDBMSs can do, too. Or have you not noticed HSQL and Derby recently? And yes, running the RDBMS in-proc performs better than running the RDBMS out-of-proc. Running &lt;i&gt;anything&lt;/i&gt; in-proc performs better than running out-of-proc. And yes, you&apos;re right, sometimes you don&apos;t have the option of in-proc. But in a situation where you&apos;re just &quot;throwing objects into the database&quot;, and nobody else is connecting to this data (in other words, you can be tightly coupled to the data storage), why take that overhead if it&apos;s not necessary? Choosing an out-of-proc database because &quot;somebody may want to get to this data someday&quot; is YAGNI, pure and simple.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;&quot;... the problem is that existing, mature RDBMS systems happen to not be written in Java (see Benefit #3).&quot;&lt;/i&gt; Ouch. Don&apos;t let the Cloudscape developers hear you say that. Granted, HSQL is not what I&apos;d call a &quot;heavy-duty&quot; RDBMS, but Gavin, not &lt;i&gt;everything&lt;/i&gt; has to be stored in Oracle. Sometimes a lighter-weight database--MySQL, HSQL, Postgres, or even (gasp!) Access--is good enough. Or are you advocating that everybody should be using clustered J2EE servers to build their 5-user department calendar app? (Maybe it&apos;s a Seam thing, I dunno.)&lt;/li&gt;
&lt;li&gt;&lt;i&gt;OODBMSs don&apos;t scale because they share a lot of state across concurrent threads.&lt;/i&gt; Any architecture that shares state across concurrent threads will have a hard time scaling, but... aren&apos;t you the guy arguing that stateful session beans are better than stateless? And how is this different from an RDBMS sharing state across concurrent threads? The transaction model isn&apos;t any different between the OODBMS and the RDBMS...&lt;/li&gt;
&lt;li&gt;&lt;i&gt;OODBMS benchmarks suck because they measure ORM with caching turned off.&lt;/i&gt; As well they should, because not all ORM users can use caching. Particularly if they need to bypass the ORM for particularly sophisticated straight-up SQL queries. (Unless, of course, one subscribes to the belief that HQL or OQL is just as powerful as SQL itself, and therefore can do anything that SQL can do...) That said, it&apos;s still a fair argument, and benchmarks, if they&apos;re to be at all useful to the general community (as opposed to being just plain marketing fluff), should detail exactly how they were run so a technology investigator can re-run the benchmark on their own, see if the results match, and tune them as desired to better match their architectural constraints or opportunities.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;&quot;Things that do more stuff are slower&quot;.&lt;/i&gt; Agreed... but how is this refuting the point? If an O/R-M is doing more stuff than an OODBMS, but the end result is the same from the programmer&apos;s perspective, the fact tha the O/R-M has to do more stuff shouldn&apos;t be held against it? That&apos;s like suggesting that Tonya Harding should have gotten a do-over in the Olympics because she was kinda upset about all the bad publicity.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;&quot;Fetching hierarchical data.... there is no a priori reason why an object database should be any faster than an ORM solution for this.&quot;&lt;/i&gt; Absolutely! The problem is with the general approach of trying to manage the associations of the object model and the fact that the complete object graph (which doesn&apos;t have to be a hierarchy, by the way) frequently is larger than the programmer wants to pull across the wire. (Which is another great reason to look into an in-proc solution: no wires involved.) This will remain a problem--pending a perfect solution, which I believe does not exist, since the decision whether to eager- or lazy-fetch elements or associations will vary on a case-by-case basis--for both the OODBMS and the O/R-M world.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Gavin concludes with this:&lt;/p&gt;
&lt;blockquote&gt;
If you think that relational technology is for persisting the state of your application, you&apos;ve missed the point. The value of the relational model is that it&apos;s democratic. Anyone&apos;s favorite programming language can understand sets of tuples of primitive values. Relational databases are an integration technology, not just a persistence technology. And integration is important. That&apos;s why we are stuck with them.
&lt;/blockquote&gt;
&lt;p&gt;Agreed! He makes my point for me: if you are in a situation where the data needs to be loosely coupled from the object model, then you need an RDBMS, and you cannot assume that the relational schema can closely mirror the object model--which essentially makes the point that the relational schema is the big winner in the dual schema decision (which is a perfectly fine decision to make, so long as you accept that your object model might suffer in its &amp;quot;purity&amp;quot; as a result). You have essentially acknowledged the dual schema problem, and chosen to let the relational schema be core definition. (Arguably, this is the only reasonable decision to make if your relational schema is fixed ahead of time.)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Management Lessons for Developers</title>
      <link>http://blogs.newardassociates.com/blog/2007/management-lessons-for-developers.html</link>
      <pubDate>Tue, 10 Apr 2007 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2007/management-lessons-for-developers.html</guid>
      	<description>
	&lt;p&gt;Others may say that developers can&apos;t be managers, but I fail to accept that; I just think developers need to get the basics about management in short, easy-to-remember doses.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;With that, I now offer the &amp;quot;Five-Minute Manager&amp;quot;:&lt;/p&gt;
&lt;h4&gt;Lesson #1: Communication&lt;/h4&gt;
&lt;p&gt;A man is getting into the shower just as his wife is finishing up her shower, when the doorbell rings. The wife quickly wraps herself in a towel and runs downstairs. When she opens the door, there stands Bob, the next-door neighbor.&lt;/p&gt;
&lt;p&gt;Before she says a word, Bob says, &amp;quot;I&apos;ll give you $800 to drop that towel.&amp;quot;&lt;/p&gt;
&lt;p&gt;After thinking for a moment, the woman drops her towel and stands naked in front of Bob. After a few seconds, Bob hands her $800 and leaves.&lt;/p&gt;
&lt;p&gt;The woman wraps back up in the towel and goes back upstairs. When she gets to the bathroom, her husband asks, &amp;quot;Who was that?&amp;quot;&lt;/p&gt;
&lt;p&gt;&amp;quot;It was Bob the next door neighbor,&amp;quot; she replies.&lt;/p&gt;
&lt;p&gt;&amp;quot;Great,&amp;quot; the husband says, &amp;quot;did he say anything about the $800 he owes me?&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Moral:&lt;/strong&gt; If you share critical information with your coworkers and employees in a timely fashion, you may be in a position to prevent avoidable exposure.&lt;/p&gt;
&lt;h4&gt;Lesson #2: Knowledge&lt;/h4&gt;
&lt;p&gt;A priest offered a Nun a lift. She got in and crossed her legs, forcing her gown to reveal a leg. The priest nearly had an accident. After controlling the car, he stealthily slid his hand up her leg.&lt;/p&gt;
&lt;p&gt;The nun said, &amp;quot;Father, remember Psalm 129?&amp;quot;&lt;/p&gt;
&lt;p&gt;The priest removed his hand. But, changing gears, he let his hand slide up her leg again.&lt;/p&gt;
&lt;p&gt;The nun once again said, &amp;quot;Father, remember Psalm 129?&amp;quot;&lt;/p&gt;
&lt;p&gt;The priest apologized &amp;quot;Sorry, sister, but the flesh is weak.&amp;quot;&lt;/p&gt;
&lt;p&gt;Arriving at the convent, the nun sighed heavily and went on her way.&lt;/p&gt;
&lt;p&gt;On his arrival at the church, the priest rushed to look up Psalm 129. It said, &amp;quot;Go forth and seek, further up you will find glory.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Moral:&lt;/strong&gt; If you are not well informed, you might miss a great opportunity.&lt;/p&gt;
&lt;h4&gt;Lesson #3: Politics&lt;/h4&gt;
&lt;p&gt;A sales rep, an administration clerk, and the manager are walking to lunch when they find an antique oil lamp. They rub it and a Genie comes out and says, &amp;quot;I&apos;ll give each of you just one wish.&amp;quot;&lt;/p&gt;
&lt;p&gt;&amp;quot;Me first! Me first!&amp;quot; says the admin clerk. &amp;quot;I want to be in the Bahamas, driving a speedboat, without a care in the world.&amp;quot;&lt;/p&gt;
&lt;p&gt;Puff! She&apos;s gone.&lt;/p&gt;
&lt;p&gt;&amp;quot;Me next! Me next!&amp;quot; says the sales rep. &amp;quot;I want to be in Hawaii, relaxing on the beach with my personal masseuse, an endless supply of Pina Coladas and the love of my life.&amp;quot;&lt;/p&gt;
&lt;p&gt;Puff! He&apos;s gone.&lt;/p&gt;
&lt;p&gt;&amp;quot;OK, you&apos;re up,&amp;quot; the Genie says to the manager.&lt;/p&gt;
&lt;p&gt;The manager says, &amp;quot;I want those two back in the office after lunch.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Moral:&lt;/strong&gt; Always let your boss (or your customer) have the first say.&lt;/p&gt;
&lt;h4&gt;Lesson #4: Relativity&lt;/h4&gt;
&lt;p&gt;An eagle was sitting on a tree, resting, doing nothing. A small rabbit saw the eagle and asked him, &amp;quot;Can I also sit like you and do nothing?&amp;quot;&lt;/p&gt;
&lt;p&gt;The eagle answered: &amp;quot;Sure, why not.&amp;quot;&lt;/p&gt;
&lt;p&gt;So, the rabbit sat on the ground below the eagle and rested.&lt;/p&gt;
&lt;p&gt;All of a sudden, a fox appeared, jumped on the rabbit and ate it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Moral:&lt;/strong&gt; To be sitting and doing nothing, you must be sitting very, very high up.&lt;/p&gt;
&lt;h4&gt;Lesson #5: Sincerity&lt;/h4&gt;
&lt;p&gt;A turkey was chatting with a bull. &amp;quot;I would love to be able to get to the top of that tree,&amp;quot; sighed the turkey, &amp;quot;but I haven&apos;t got the energy.&amp;quot;&lt;/p&gt;
&lt;p&gt;&amp;quot;Well, why don&apos;t you nibble on some of my droppings?&amp;quot;, replied the bull. &amp;quot;They&apos;re packed with nutrients.&amp;quot;&lt;/p&gt;
&lt;p&gt;The turkey pecked at a lump of dung, and found it actually gave him enough strength to reach the lowest branch of the tree. The next day, after eating some more dung, he reached the second branch. Finally after a fourth night, the turkey was proudly perched at the top of the tree.&lt;/p&gt;
&lt;p&gt;He was promptly spotted by a farmer, who shot him out of the tree.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Moral:&lt;/strong&gt; BS might get you to the top, but it won&apos;t keep you there.&lt;/p&gt;
&lt;p&gt;... and if you really thought you could learn to be a manager in five minutes, allow me to suggest that you take my course, &amp;quot;How to Bilk Management of Loads of Cash, the Easy Way&amp;quot;, only $5995 for five days....&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Programming Promises (or, the Professional Programmer&apos;s Hippocratic Oath)</title>
      <link>http://blogs.newardassociates.com/blog/2007/programming-promises.html</link>
      <pubDate>Fri, 26 Jan 2007 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2007/programming-promises.html</guid>
      	<description>
	&lt;p&gt;Ever thought about an oath for programmers?&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Michael.NET, apparently inspired by my &amp;quot;Check Your Politics At The Door&amp;quot; post, and equally peeved at &lt;a href=&quot;http://blogs.msdn.com/reedme/archive/2007/01/10/is-your-daylight-going-to-be-saved-this-year.aspx&quot;&gt;another post on blogs.msdn.com&lt;/a&gt;, hit a note of pure inspiration when he created his list of &lt;a href=&quot;http://michaeldotnet.blogspot.com/2007/01/programming-promises.html&quot;&gt;&amp;quot;Programming Promises&amp;quot;&lt;/a&gt;, which I repeat below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I promise to get the job done.&lt;/li&gt;
&lt;li&gt;I promise to use whatever tools I need to, regardless of politics.&lt;/li&gt;
&lt;li&gt;I promise to listen to the Closed Source and Open Source zealots equally, and then dismiss them.&lt;/li&gt;
&lt;li&gt;I promise to support, as long as I am able, any closed source applications I may release.&lt;/li&gt;
&lt;li&gt;I promise to release open source any applications I can not, or will not, support.&lt;/li&gt;
&lt;li&gt;I promise to learn as many languages and libraries as possible, regardless of politics.&lt;/li&gt;
&lt;li&gt;I promise to engage with as many other programmers as possible, both in person and online, in order to learn from them; regardless of politics.&lt;/li&gt;
&lt;li&gt;I promise to not bash Microsoft nor GNU, nor others like them, everyone has a place in our industry.&lt;/li&gt;
&lt;li&gt;I promise to use both Windows and Linux, both have their uses.&lt;/li&gt;
&lt;li&gt;I promise to ask questions when I don&apos;t know the answer, and answer questions when I do.&lt;/li&gt;
&lt;li&gt;I promise to learn from my mistakes, and to try to the first time.&lt;/li&gt;
&lt;li&gt;I promise to listen to any idea, however crazy it may sound.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In many ways, this strikes me as fundamentally similar to the &lt;A href=&quot;http://en.wikipedia.org/wiki/Hippocratic_Oath&quot;&gt;Hippocratic Oath&lt;/A&gt; that all doctors must take as part of their acceptance into the ranks of the medical profession. For most, this isn&apos;t just a bunch of words they recite as entry criteria, this is something they firmly believe and adhere to, almost religiously. It seems to me that our discipline could use something similar. Thus, do I swear by, and encourage others to similarly adopt, the Oath of the Conscientious Programmer:&lt;/p&gt;
&lt;blockquote&gt;
I swear to fulfill, to the best of my ability and judgment, this covenant:
&lt;ul&gt;
&lt;li&gt;I will respect the hard-won scientific gains of those programmers and researchers in whose steps I walk, and gladly share such knowledge as is mine with those who are to follow. That includes respect for both those who prefer to keep their work to themselves, as well as those who seek improvement through the open community.&lt;/li&gt;
&lt;li&gt;I will apply, for the benefit of the customer, all measures [that are] required, avoiding those twin traps of gold-plating and computing nihilism.&lt;/li&gt;
&lt;li&gt;I will remember that there is humanity to programming as well as science, and that warmth, sympathy, and understanding will far outweigh the programmer&apos;s editor or the vendor&apos;s tool.&lt;/li&gt;
&lt;li&gt;I will not be ashamed to say &amp;quot;I know not,&amp;quot; nor will I fail to call in my colleagues when the skills of another are needed for a system&apos;s development, nor will I hold in lower estimation those colleagues who ask of my opinions or skills.&lt;/li&gt;
&lt;li&gt;I will respect the privacy of my customers, for their problems are not disclosed to me that the world may know. Most especially must I tread with care in matters of life and death, or of customers&apos; perceptions of the same. If it is given me to save a project or a company, all thanks. But it may also be within my power to kill a project, for the company&apos;s greater good; this awesome responsibility must be faced with great humbleness and awareness of my own frailty. Above all, I must not play at God, and remain open to others&apos; ideas or opinions.&lt;/li&gt;
&lt;li&gt;I will remember that I do not create a report, or a data entry screen, but tools for human beings, whose problems may affect the person&apos;s family and economic stability. My responsibility includes these related problems, if I am to care adequately for those who are technologically impaired.&lt;/li&gt;
&lt;li&gt;I will actively seek to avoid problems that are time-locked, for I know that software written today will still be running long after I was told it would be replaced.&lt;/li&gt;
&lt;li&gt;I will remember that I remain a member of society, both our own and of the one surrounding all of us, with special obligations to all my fellow human beings, those sound of mind and body as well as the clueless.&lt;/li&gt;
&lt;li&gt;If I do not violate this oath, may I enjoy life and art, respected while I live and remembered with affection thereafter. May I always act so as to preserve the finest traditions of my calling and may I long experience the joy of the thanks and praise from those who seek my help.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I, Ted Neward, so solemnly swear.&lt;/p&gt;
&lt;/blockquote&gt;

	</description>
    </item>
    <item>
      <title>More on Ethics</title>
      <link>http://blogs.newardassociates.com/blog/2007/more-on-ethics.html</link>
      <pubDate>Fri, 26 Jan 2007 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2007/more-on-ethics.html</guid>
      	<description>
	&lt;p&gt;While traveling not too long ago, I saw a great piece on ethics, and wished I&apos;d kept the silly magazine (I couldn&apos;t remember which one) because it was just a really good summation of how to live the ethical life.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;While wandering around the Web with Google tonight, &lt;a href=&quot;http://www.hemispheresmagazine.com/nov06/cybersidebar.html&quot;&gt;I found it&lt;/a&gt; (scroll down a bit, to after the bits on Prohibition and Laughable Laws); in summary, the author advocates a life around five basic points:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do no harm&lt;/li&gt;
&lt;li&gt;Make things better&lt;/li&gt;
&lt;li&gt;Respect others&lt;/li&gt;
&lt;li&gt;Be fair&lt;/li&gt;
&lt;li&gt;Be loving&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Seems pretty simple, no? The problems occur, of course, in the interpretation and execution. For example, how exactly do we define &amp;quot;better&amp;quot;, when we seek to make things better? Had I the power, I would create a world where all people are free to practice whatever religious beliefs they hold, but clearly if those religious beliefs involve human sacrifice, then it&apos;s of dubious belief that my actions made the world &amp;quot;better&amp;quot;. (Of course, said practitioners would probably disagree.)&lt;/p&gt;
&lt;p&gt;It&apos;s also pretty hard to actually follow through on these on a daily basis. The author, Bruce Weinstein, makes this pretty clear in this example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For example, how often do we really keep “do no harm” in mind during our daily interactions with people? If a clerk at the grocery store is nasty to us, don’t we return the nastiness and tell ourselves, &amp;quot;Serves them right?&amp;quot; We may, but if we do, we harm the other person. In so doing, we harm our own soul—and this is one of the reasons why we shouldn’t return nastiness with more of the same.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ouch. Guilty as charged.&lt;/p&gt;
&lt;p&gt;There&apos;s a quiz attached to the article, and I highly suggest anyone who cares about their own ethical behavior take it; some of the questions are pretty clear-cut (at least to me), but some of them fall into that category of &amp;quot;Well, I know what I &lt;em&gt;should&lt;/em&gt; say I would do, but...&amp;quot;, and some of them are just downright surprising.&lt;/p&gt;
&lt;p&gt;Personally, I think these five points are points that every developer should also advocate and life their life by, since, quite honestly, I think we as an industry do a pretty poor job on all five points. Clearly we violate #1 when we&apos;re not careful with security measures in the code; too many programmers (and projects) fail to realize that &amp;quot;better&amp;quot; in #2 is from the customers&apos; perspective, not our own; too many programmers look down on anyone who&apos;s not technical in some way, or even those who disagree with them, thus violating #3; too many consultants I&apos;ve met (thankfully none I can call &amp;quot;friends&amp;quot;) will take any excuse to overbill a client (#4); and so on, and so on, and so on.&lt;/p&gt;
&lt;p&gt;Maybe I&apos;m getting negative in my old age, but it just seems to me that there&apos;s too much shouting and posturing going on (&lt;em&gt;cough&lt;/em&gt; Fleury &lt;em&gt;cough&lt;/em&gt;) and not enough focus on the people to whom we are ultimately beholden: our customers. Do what&apos;s right for them, even if it&apos;s not the easy thing to do, even when they don&apos;t think they need it (such as the incapcitated friend in the quiz), and you can never go wrong.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2007 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2007/2007-tech-predictions.html</link>
      <pubDate>Mon, 1 Jan 2007 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2007/2007-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;Here we go again: the annual review of last year&apos;s predictions, and a set of new ones for the new year.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Now, in what&apos;s become an ongoing tradition, this is the time of year when I peer into the patented Ted Neward Crystal Ball (TM) (operators are standing by!), see what it tells me about technology trends and ideas for the coming year, and report them to you. The usual disclaimers apply, meaning I&apos;m not getting any sort of endorsement deals to mention anybody&apos;s technology here, I&apos;m not speaking for anybody but myself in this, and so on. And, in order to prove that I&apos;m not an analyst group like Forrester or Burton or any of those other yahoos, in a separate post, I&apos;ll look over my predictions for 2006 and see how they panned out, thus proving that the patented Ted Neward Crystal Ball (TM) is &lt;strike&gt;just as capable of mistakes as any other crystal ball&lt;/strike&gt; of course, right all the time. :-)&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;OK, time to face the music and look back at my predictions from last year:&lt;/p&gt;
&lt;p&gt;2006 was an interesting year, in that a lot of interesting things happened this year for developers. For the .NET crowd, Visual Studio 2005 and SQL Server 2005 finally became widely available to them (yes, it shipped in 2005 but it took a bit for it to percolate through the community), and NetFX 3 (aka .NET 3.0, aka Indigo/Avalon/Workflow) shipped in Q4, not to mention Vista itself, meaning there was all kinds of new stuff to play with. For the Java crowd, Spring 2.0 shipped, Geronimo 1.0 shipped, and Sun decided to finally open the doors on the JDK (apparently not realizing that a lot of us had already slipped in the back way through the doors marked &amp;quot;SCSL license&amp;quot; and &amp;quot;JRL license&amp;quot; since JDK 1.2...). Meanwhile, Ruby continued to amaze those who&apos;d never seen a dynamic/scripting language before, and Rails continued to amaze developers who&apos;d never seen a VB demo before. More WS-* specs shipped, people started talking about JavaScript Object Notation (JSON), RSS/Atom continued to draw attention in droves, and marketing guys looked for all kinds of places they could hang the Tim O&apos;Reilly-inspired &amp;quot;Web 2.0&amp;quot; meme anywhere they could. And yet, through it all, developers somehow ignored the noise and kept working.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;The hype surrounding Ajax will slowly fade, as people come to realize that there&apos;s really nothing new here, just that DHTML is cool again. As &lt;A href=&quot;http://www.almaer.com/blog/archives/001122.html&quot; target=_blank&gt;Dion points out&lt;/A&gt;, Ajax will become a toolbox that you use in web development without thinking that &amp;quot;I am doing Ajax&amp;quot;. Just as we don&apos;t think about &amp;quot;doing HTML&amp;quot; vs &amp;quot;doing DOM&amp;quot;.&lt;/em&gt; Well, much as I might have wanted this to take place, it doesn&apos;t seem to have happened--Ajax is as much a buzzword (if not more so) than it was in 2005. In fact, it now seems to have grown to the same buzzwordy status as &amp;quot;Web 2.0&amp;quot;, in that we&apos;re starting to lose sight of it as its acronym originally defined it to be: Asynchronous Javascript And XML. Now people are talking about using JSON, about using it synchronously, and... hey, it&apos;s just a matter of time before somebody points out the flaws in Javascript and starts suggesting other dynamic languages for the browser....&lt;/li&gt;
&lt;li&gt;&lt;em&gt;The release of EJB 3 may actually start people thinking about EJB again, but hopefully this time in a more pragmatic and less hype-driven fashion. (Yes, EJB does have its place in the world, folks--it&apos;s just a much smaller place than most of the EJB vendors and book authors wanted it to be.)&lt;/em&gt; Hah. Fat chance. Though the EJB-bashing wave has slipped to an all-time low, it seems, it&apos;s still ready to rear its ugly head any time somebody suggests that there might be something about EJB that doesn&apos;t suck. Still, the luster is starting to wear off on Spring, which means that (a) people are starting to look at it critically, rather than taking it for granted as a media darling, and (b) people will start to re-evaluate EJB as a viable technology rather than just demonize it. Maybe.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Vista will be slipped to 2007, despite Microsoft&apos;s best efforts. In the meantime, however, WinFX (which is effectively .NET 3.0) will ship, and people will discover that Workflow (WWF) is by far the more interesting of the WPF/WCF/WWF triplet. Notice that I don&apos;t say &amp;quot;powerful&amp;quot; or &amp;quot;important&amp;quot;, but &amp;quot;interesting&amp;quot;.&lt;/em&gt; Here we go: did Vista ship, or not? Officially, Vista was released to manufacturing (RTM&apos;ed), but it&apos;s not available to consumers yet, and won&apos;t be until later this month or next. WinFX... er, I mean .NET 3.0... er, I mean NetFX3... whatever... shipped at the same time Vista did, though, and developers in the .NET space are beginning to hear more about this thing called &amp;quot;Workflow&amp;quot;. It&apos;s still a mystery to most, I think, but then so is WCF.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scripting languages will hit their peak interest period in 2006; Ruby conversions will be at its apogee, and its likely that somewhere in the latter half of 2006 we&apos;ll hear about the first major Ruby project failure, most likely from a large consulting firm that tries to duplicate the success of Ruby&apos;s evangelists (Dave Thomas, David Geary, and the other Rubyists I know of from the NFJS tour) by throwing Ruby at a project without really understanding it. In other words, same story, different technology, same result. By 2007 the Ruby Backlash will have begun.&lt;/em&gt; Has the Ruby backlash begun? Hard to say--certainly there are those who&apos;ve been rolling out Rails apps that have found problems with deploying Rails, but for now Rails--and thus Ruby--remain the media darling. Maybe by 2008.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interest in building languages that somehow bridge the gap between static and dynamic languages will start to grow, most likely beginning with E4X, the variant of ECMAScript (Javascript to those of you unfamiliar with the standards) that integrates XML into the language.&lt;/em&gt; Bah--this was an easy one to call. E4X hasn&apos;t yet really gained a lot of traction, but that may be because nobody&apos;s really talking about it or writing about it. That part might just require more time, or it may never happen--depends on how badly developers want an easier way to work with XML. Suffice it to say, we&apos;ll see lots of E4X-like features show up in other languages as we go; some have already shown up in other languages, such as Flex&apos;s ActionScript, for example.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Java developers will start gaining interest in building rich Java apps again. (Freely admit, this is a long shot, but the work being done by the Swing researchers at Sun, not least of which is Romain Guy, will by the middle of 2006 probably be ready for prime-time consumption, and there&apos;s some seriously interesting sh&lt;/em&gt;t in there.)* Well, you can ask Scott Delap if you&apos;re not convinced, but certainly there&apos;s been a growing interest in building Eclipse RIAs. Swing (justifiably or not) still remains in the doghouse, however.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Somebody at Microsoft starts seriously hammering on the CLR team to support continuations. Talk emerges about supporting it in the 4.0 (post-WinFX) release.&lt;/em&gt; I have no empirical or anecdotal proof, but the rumors abound...&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Effective Java (2nd Edition) will ship. (Hardly a difficult prediction to make--Josh said as much in the Javapolis interview I did with him and Neal Gafter.)&lt;/em&gt; Whoops. Apparently Josh is busy.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Effective .NET will ship. Pragmatic XML Services will ship.&lt;/em&gt; Whoops. Apparently I was busy, too.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;JDK 6 will ship, and a good chunk of the Java community self-proclaimed experts and cognoscente will claim it sucks.&lt;/em&gt; It did ship, and many did claim it sucks. The coolness of JSR 223 (the scripting support) definitely worked to offset a lot of the cries-of-suckiness, though the last-second dropping of the data-mapping capabilities specified in JDBC 4.0 (WTF, Sun?!?) caught a lot of us by (unhappy) surprise. It also raises the question as to efficacy of the JCP documents when Sun feels completely comfortable changing them at the Very Last Second....&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Java developers will seriously begin to talk about what changes we want/need to Java for JDK 7 (&amp;quot;Dolphin&amp;quot;). Lots of ideas will be put forth. Hopefully most will be shot down. With any luck, Joshua Bloch and Neal Gafter will still be involved in the process, and will keep tight rein on the more... aggressive... ideas and turn them into useful things that won&apos;t break the spirit of the platform.&lt;/em&gt; Well, witness the closures debate between Josh on the one hand, and Neal on the other, and you can clearly see that they&apos;re still involved in the process, though not in the manner I&apos;d envisioned. That said, though, the JDK 7 discussions are already ramping up; look for an interview I did with Neal Gafter at Javapolis this year to show up on &lt;A href=&quot;http://www.parleys.com&quot;&gt;Parleys.com&lt;/A&gt; in the very near future, in which we talked about this exact subject. Some interesting ideas will emerge out of this debate, both for JDK 7 and releases beyond...&lt;/li&gt;
&lt;li&gt;&lt;em&gt;My long-shot hope, rather than prediction, for 2006: Sun comes to realize that the Java platform isn&apos;t about the language, but the platform, and begin to give serious credence and hope behind a multi-linguistic JVM ecosystem.&lt;/em&gt; Wow. Witness the acquisition of the JRuby pair by Sun, and the scripting support in JDK 6, and maybe, just maybe, I can claim a point on this one.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;My long-shot dream: JBoss goes out of business, the JBoss source code goes back to being maintained by developers whose principal interest is in maintaining open-source projects rather than making money, and it all gets folded together with what the Geronimo folks are doing. In other words, the open-source community stops the infighting and starts pulling oars in the same direction at the same time. For once.&lt;/em&gt; Well, you can&apos;t win them all.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Not sure how that leaves the score, but there you go....&lt;/p&gt;
&lt;p&gt;Now, without further ado... here&apos;s 2007&apos;s list.
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;General: Analysts will call 2007 the Year of the {Something}&lt;/b&gt;, where I bet that {Something} will be either &quot;ESB&quot; or &quot;SOA&quot;. They will predict that companies adopting {Something} will save millions, if not billions, if only they rush to implement it now. They will tag this with a probability of .8 in order to CYA in case {Something} doesn&apos;t pan out. (Yes, I&apos;ve read far too many of these reports--I&apos;m personally convinced that each of the analyst companies has a template buried away in their basement that they pull out each time they need a new one, and they just do a global search-and-replace of &quot;{Something}&quot; with whatever the technology &lt;i&gt;du jour&lt;/i&gt; happens to be.)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;.NET: Thousands of developers will horribly abuse WPF in ways that can only be called nightmarish&lt;/b&gt;, thus once again proving the old adage that &quot;just because you &lt;i&gt;can&lt;/i&gt; doesn&apos;t mean you &lt;i&gt;should&lt;/i&gt;&quot; still holds. WPF&apos;s capabilities with video will prove, in many ways, to be the modern equivalent to the &quot;blink&quot; tag in HTML. This will provide some author with a golden opportunity: &quot;WPF Applications That Suck&quot;. Alan Cooper will re-release &quot;About Face&quot;, updated to include WPF UI elements.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;.NET: Thousands of developers will look to Redmond for an answer to the question, &quot;Which should I use? BizTalk, Windows Workflow, or SQL Server Service Broker?&quot;&lt;/b&gt;, and get no clear answer.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Windows: Microsoft will try, once again, to kill off the abomination that was called the Windows 95/98/Me line of operating systems&lt;/b&gt;, and will once again have to back off as industry outcries of protest (on behalf of little old ladies who are the only ones left running Windows 95/98/Me and probably haven&apos;t turned their machine on in months, at least not since the grandkids last visited) go ballistic.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Windows: Ditto for Visual Basic 6.0,&lt;/b&gt; except now the outcry will be on behalf of developers who aren&apos;t capable of learning anything new. Sun will use the resulting PR to announce Project YAVKRWMITT (Yet Another VB Killer Really We Mean It This Time, pronounced &quot;YAV-kermit&quot;) on java.net. Meanwhile, efforts to make CLASSPATH into something a VB 6 guy actually has a prayer of understanding will go quietly ignored.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Java: JSR 277 will continue to churn along&lt;/b&gt;, and once the next draft ships, publicly nobody will like what we produce, though quietly everybody will admit it&apos;s a far cry better than what we have now, and when it ships in JDK 7 will be adopted widely and quietly.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Java: Thousands of new ideas and proposals to extend the Java language in various ways will flood into the community&lt;/b&gt;, now that developers can start hacking on it for themselves thanks to the OpenJDK. Only a small fraction of these will ever get beyond the concept stage, and maybe one or two will actually be finished and released to the Web for consideration by the community and the JCP. Thousands more Java developers craving Alpha-Geek status will stick a &quot;Hello, world&quot; message into the compiler&apos;s startup sequence, then claim &quot;experienced with modifying the OpenJDK Java compiler&quot; on their resume and roundly criticize Java in one way or another by saying, &quot;Well, I&apos;ve &lt;i&gt;looked&lt;/i&gt; at the code, and let me tell you....&quot;.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;.NET: Somewhere, a developer will realize that SQL Server 2005 can be a SOAP/WSDL XML service endpoint&lt;/b&gt;, and open it up as a private back-channel for his application to communicate with the database through the firewall &quot;for performance reasons&quot; (meaning, &quot;So I can avoid having to talk to the app server in between my web server and my database&quot;). With any luck, the DBA will kill him and hide the body before anybody can find and exploit it.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;General: Yet Another Virus That&apos;s Microsoft&apos;s Fault will rip through the Internet&lt;/b&gt;, and nobody will notice that the machines affected are the ones that aren&apos;t routinely administered or receive updates/patches. Companies will threaten Microsoft with million-dollar lawsuits, yet will fire none of their system administrators who lovingly lavish whole days tuning their Linux IRC servers yet leave the Windows Exchange Server still running Windows NT 4.0.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;General: Interest in JSON will escalate wildly&lt;/b&gt;, hyped as the &quot;natural replacement for XML&quot; in building browser-to-server connections, owing to its incredible simplicity in expressing &quot;object&quot; data. Folks, JSON is a useful format, but it&apos;s not a replacement for XML (nor is XML a replacement for it, either). What made XML so popular was not is hierarchical format (Lord above, that&apos;s probably the &lt;i&gt;worst&lt;/i&gt; part of it, from where we as developers sit), nor its HTML-like simplified-SGML syntax. What made XML interesting was the fact that &lt;i&gt;everybody&lt;/i&gt; lined up behind it--Microsoft, Sun, BEA, Oracle, IBM, there&apos;s not a big vendor that didn&apos;t express its undying love and devotion to XML. I sincerely doubt JSON will get that kind of rallying effect. (And if you&apos;re going to stand there and suggest that JSON is better because its simpler and therefore more approachable for developers to build support for themselves, quite honestly, I thought we were trying to get &lt;i&gt;out&lt;/i&gt; of developers building all this communications infrastructure--isn&apos;t that what the app servers and such taught us?)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;General: Interest in Java/.NET interopability will rise&lt;/b&gt; as companies start to realize that (a) the WS-* &quot;silver bullet&quot; isn&apos;t,  (b) ESB, XML, and SOA are just acronyms and won&apos;t, in of themselves, solve all the integration problems, and (c) we have lots of code in both Java and .NET that need to talk to each other. This may be a self-serving prediction, but I got a LOT of interest towards the end of this year in the subject, so I&apos;m guessing that this is going to only get bigger as the WS-* hype continues to lose its shine in the coming years.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ruby: Interest in Java/Ruby and .NET/Ruby interoperability is going to start quietly making its presence felt&lt;/b&gt;, as people start trying to wire up their quick-to-write &quot;stovepipe&quot; RAILS apps against other systems in their production data center, and find that Ruby really is a platform of its own. RubyCLR or JRuby may be part of the answer here, but there&apos;s likely some hidden mines there we haven&apos;t seen yet.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Languages: A new meme will get started: &quot;JavaScript was that thing, that little toy language, that you used to do stuff in the HTML browser. ECMAScript, on the other hand, is a powerful and flexible dynamic programming language suitable for use in all sorts of situations.&quot;&lt;/b&gt; Pass it on. If you get it, don&apos;t tell anybody else. (Don&apos;t laugh--it worked for &quot;The Crying Game&quot;.) It&apos;s the only way &lt;strike&gt;JavaScript&lt;/strike&gt; ECMAScript will gain widespread acceptance and shed the &quot;toy&quot; label that JavaScript has.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Languages: Interest in functional-object hybrid languages will grow.&lt;/b&gt; Scala, Jaskell, F#, and others not-yet-invented will start to capture developers&apos; attention, particularly when they hear the part about functional languages being easier to use in multi-core systems because it encourages immutable objects and discourages side effects (meaning we don&apos;t have to worry nearly so much about writing thread-safe code).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Languages: Interest in Domain-specific languages will reach a peak this year&lt;/b&gt;, but a small backlash will begin next year. Meanwhile, more and more developers will realize that one man&apos;s &quot;DSL&quot; is another man&apos;s &quot;little language&quot;, something UNIX has been doing since the early 70&apos;s. This will immediately take the shine off of DSLs, since anything that we did in the 70&apos;s &lt;i&gt;must&lt;/i&gt; be bad, somehow. (Remember disco?)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;General: Rails will continue to draw developers who want quick-fix solutions/technologies&lt;/b&gt;, and largely that community will ignore the underlying power of Ruby itself. The draw will start to die down once Rails-esque feature ideas get folded into Java toolkits. (Rails will largely be a non-issue with the .NET community, owing to the high-productivity nature of the drag-and-drop interface in Visual Studio.)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Java: Interface21 is going to start looking like a &quot;big vendor&quot; alongside BEA and IBM&lt;/b&gt;. I was talking with some of the I21 folks in Aarhus, Denmark at JAOO, and one of them casually mentioned that they were looking at a Spring 2.1 release somewhere in mid-2008. Clearly Spring is settling into eighteen-month major-version release cycles like all the big (meaning popular), established software systems have a tendency to do. This is both a good thing and a bad thing--it&apos;s good in that it means that Spring is now becoming an established part of the Java landscape and thus more acceptable to use in production environments, but it&apos;s bad in that Spring is now going to face the inevitable problem all big vendors face: trying to be all things to all people. This is dangerous, both for Interface21 and the people relying on Spring, largely because it means that Spring faces a very real future of greater complexity (and there are those, myself included, who believe that Spring is too complex already, easily on par with the complexity seen in EJB, POJOs notwithstanding).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;General: Marc Fleury will get a golden parachute from Red Hat&lt;/b&gt; (at their request and to their immense relief), and hopefully will retire to his own small island (might I suggest Elba, &lt;i&gt;la petite corporal&lt;/i&gt;?) to quietly enjoy his millions. A shame that the people who did most of the real work on JBoss won&apos;t see a commensurate reward, but that&apos;s the way the business world works, I guess.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;General: Some company will get millions to build an enterprise product on the backs of RSS and/or Atom&lt;/b&gt;, thus proving that VCs are just as stupid and just as vulnerable to hype now as they were back in the DotCom era.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;General: Somebody will attempt to use the phrase &quot;Web 2.0&quot; in a serious discussion&lt;/b&gt;, and I will be forced to kill them for attempting to use a vague term in a vain effort to sound intelligent.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Web clients: Ajax will start to lose its luster&lt;/b&gt; when developers realize the power of Google Maps isn&apos;t in Ajax, but in the fact that it&apos;s got some seriously cool graphics and maps. (Or, put another way, when developers realize that Ajax alone won&apos;t make their apps as cool as Google Maps, that&apos;s it&apos;s the same old DHTML from 1998, the hype will start to die down.)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;XML: Somebody, somewhere, will realize that REST != HTTP.&lt;/b&gt; He will be roundly criticized by hordes of HTTP zealots, and quietly crawl away to go build simpler and more robust systems that use transports other than HTTP.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;XML: Somebody, somewhere, will read the SOAP 1.2 specification.&lt;/b&gt; H.P. Lovecraft once suggested, loosely paraphrased, the the day Man understands the nature of the universe, he will either be driven into gibbering insanity, or flee back into ignorance in self-preservation. Ditto for the day Man reads the SOAP 1.2 spec and realizes that SOAP is, in fact, RESTful.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Security: The US Government will continue its unbelievable quest to waste money on &quot;security&quot;&lt;/b&gt; by engaging in yet more perimeter security around airports and other indefensible locations, thus proving that none of them have bothered to read Schneier and learn that real security is a three-part tuple: prevention, detection, and response.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Security: Thousands of companies will follow in the US Government&apos;s footsteps&lt;/b&gt; by doing exactly the same thing. (Folks, you can&apos;t solve all your problems with cryptography, no matter how big the key size--you just end up with the basic problem of where to store the keys, and no, burying them inside the code &lt;i&gt;isn&apos;t&lt;/i&gt; going to hide them effectively.)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Security: More and more rootkits-shipping-with-a-product will be discovered.&lt;/b&gt; We used to call it &quot;getting close to the metal&quot;, now it&apos;s a &quot;rootkit&quot;. With great power comes great responsibility... and, as many consumers have already discovered, with great power also comes a tendency to create greater instability...&lt;/li&gt;
&lt;li&gt;&lt;b&gt;General: Parrot will ship a 1.0 release.&lt;/b&gt; Oh, wait, hang on, sorry, I bumped into the crystal ball and accidentally set it to 2017.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;.NET: Microsoft will ship Orcas (NetFX 3.5).&lt;/b&gt; (Sorry, crystal ball&apos;s still set on 2017. Trying to fix it...)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;.NET: Vista will surpass Windows XP in market penetration.&lt;/b&gt; (Let&apos;s see, almost got it set back to 2007, bear with me... There. Got it.)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;General: I will blog more than I did this year.&lt;/b&gt; (Hell, I couldn&apos;t blog &lt;i&gt;less&lt;/i&gt;, even if I tried.)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;General: &lt;i&gt;Pragmatic XML Services&lt;/i&gt;, &lt;i&gt;Pragmatic .NET Project Automation&lt;/i&gt; and &lt;i&gt;Effective .NET&lt;/i&gt; will ship.&lt;/b&gt; (Wait, is the crystal ball still on 2017...?)&lt;/li&gt;
&lt;/ul&gt;
Same time, next year....&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Vietnam of Computer Science</title>
      <link>http://blogs.newardassociates.com/blog/2006/thoughts-on-vietnam-commentary.html</link>
      <pubDate>Tue, 27 Jun 2006 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2006/thoughts-on-vietnam-commentary.html</guid>
      	<description>
	&lt;p&gt;Numerous folks have taken me to task (some here in comments, some through private email, some through still other channels) over the last blog post; rather than try to respond to all individually, I figured it makes more sense to address the more salient points here:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;How dare you use the Vietnam War as an analogy for something so trivial as object/relational mapping?&amp;quot;&lt;/em&gt;&lt;/strong&gt; First of all, let&apos;s make a few facts clear. My father served in Vietnam. I have friends in Iraq right now. My best friend from high school served in the Navy during the first Iraq. I studied Vietnam--along with numerous other wars and coflicts--for several years as an International Relations major in college, focused specifically on military history. I have nothing but deep respect for all soldiers, of all nations, who go off to risk their lives in services to their country. I am appalled at how quickly governments (ours and others) chuck troops into a situation without thinking of the long-term strategy. I&apos;ve spent more time studying war and its effects on the solidiers, the governments and the people than most people have spent watching TV. I am very aware of the ghosts I&apos;m treading upon when I use the word &amp;quot;Vietnam&amp;quot;, and quite frankly, folks, we as a nation have yet to come to terms with what happened there. Rambo films don&apos;t exorcise ghosts, much as we might want them to. POW-MIA flags don&apos;t, either. Please don&apos;t bring your ghosts in with you when approaching this subject, and I&apos;ll leave mine behind as well.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;The Vietnam War is a bad analogy for O/R-M.&amp;quot;&lt;/em&gt;&lt;/strong&gt; Vietnam remains, for most Americans, as the quintessential symbol for &amp;quot;bloody, ugly, unresolvable quagmire&amp;quot;. And, as some have pointed out in comments on the blog post already, all analogies break down eventually, and this one is no different--as one commenter put it, nobody ever died from a bad O/R-M tool. (Though the day is not far off when such could occur, given the incredible spread of technology into all corners of our lives--it&apos;s not too hard to imagine a day when a patient dies because a doctor received incorrect information about a medical allergy from the enterprise system he/she uses to call up patient records.) That said, however, I assert that the analogy is appropriate, and relevant, for a variety of reasons. One, because just as development teams frequently believe that the object/relational problem is &amp;quot;solvable&amp;quot;, so too did the US government believe that the Communist insurgency (which was more of an independence movement than a Communist movement, we&apos;ve since realized) was &amp;quot;solvable&amp;quot; in South Indochina. Two, development teams frequently believe that with &amp;quot;just a little bit more work, we&apos;re almost there...&amp;quot; (wherever &amp;quot;there&amp;quot; is, in the minds of the architect or team lead), just as the US government frequently predicted that the Viet Cong were on the verge of defeat, just a few more troops and the war is over... Three, the analogy holds because even as team leads and architects approach this problem having been burned before, they still attempt solutions to the problem, just as many of the US administrations&apos; advisors believed that Vietnam was a dead-end and ill-fated, they still went in there anyway.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;You aren&apos;t being fair--after all, {insert-name-of-favorite-O/R-M-tool-here} doesn&apos;t suffer from that problem.&amp;quot;&lt;/em&gt;&lt;/strong&gt; Not yet, it doesn&apos;t. Or it does, but you just haven&apos;t run into it yet. Either answer is possible. And in the early years of the Vietnam conflict, we didn&apos;t suffer the problems that we commonly associate with the War--the poor morale, the rampant drug use among the military, the widespread unpopularity of the conflict back home, and so on. The danger here is on the far end of the Slippery Slope, not the near end.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;You aren&apos;t being fair--when you balance the pros and cons...&amp;quot;&lt;/em&gt;&lt;/strong&gt; Perhaps not. But as someone who&apos;s built three O/R-M&apos;s in his lifetime, and refuses to build another one because they all faced the same end, despite very different beginnings, I worry more about the Slippery Slope and where it leaves us in the end. If your team can stay perched on the side of the Slope that yields the most benefits, then more power to you; but I worry about the day when the new college intern says to himself, &amp;quot;You know, with a bit more investment, I bet we could add inheritance....&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Some languages do allow for varying numbers of fields.&amp;quot;&lt;/em&gt;&lt;/strong&gt; Actually, no, most of the languages cited as examples, including Ruby, don&apos;t allow for varying fields. Ruby has a feature called &amp;quot;open classes&amp;quot;, in which you can change the definition of the class at any time, but it&apos;s still (very loosely) a class-based language. (The implementation of Ruby, from what I can see, seems to back this point--each object holds a pointer back to the class object it stems from, which means, at least to me, it&apos;s loosely class-based.) We can debate the semantics of this point for days, and frankly I welcome the discussion, but not in the context of this one. We can save that for another post/thread at another time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;OK, but where can I go to get more info about O/R-M so I don&apos;t fall into the quagmire?&amp;quot;&lt;/em&gt;&lt;/strong&gt; Excellent question. Roy Osherove has started a community site about O/R-Ms, which I think holds promise for discussion on the topic. The JDO crowd had several resources available at JDOCentral, and there&apos;s lots of discussion about O/R-M (stretching back several years) on TheServerSide. BEA, with its acquisition of Solarmetric, now owns one of the better O/R-M tools on the market, Kodo, and they&apos;re likely to still have numerous white papers and such on the subject.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;OK, but where can I go to get more info about object persistence tools?&amp;quot;&lt;/em&gt;&lt;/strong&gt; Right now, the only one I have any faith in is the db4o project; in fact, I&apos;m speaking at their first user/developer conference in London in a few weeks. I&apos;ve used others (such as Versant) in the past, and frankly, wasn&apos;t incredibly impressed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;OK, but where can I go to get more info about these other languages/approaches?&amp;quot;&lt;/em&gt;&lt;/strong&gt; Keep your eye on LINQ, for starters, as that&apos;s one of the first mainstream attempts to bring some of these ideas into traditional statically-typed object platforms. Scala and F# I already mentioned. Ruby is another place to spend some time, as there&apos;s a lot of features Ruby has that are trying to make their way into other languages. And, although I will likely gather some serious heat for saying this, Visual FoxPro may have some of the most interesting &amp;quot;best of both worlds&amp;quot; mojo in the entire language space on this subject.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;Great post!&amp;quot;&lt;/em&gt;&lt;/strong&gt; Thanks.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Make no mistake about it: I am deeply sympathetic to anyone who lost somebody--figuratively or literally--to the Vietnam conflict. I feel equally sympathetic to anyone who lost somebody in the Korean War (as my family did), World War Two, or even World War One before that. In fact, my sympathies go out to anyone lost in any of the conflicts across history and the globe in which men and women die for an ideal or symbol. It is an unfortunate statement about human affairs that we see war as the ultimate arbiter over power disputes between nations, but this is the world we live in now. If you don&apos;t care for that, then I encourage you to actively work to change it, regardless of your politics. I have far more respect for someone who virulently disagrees with my political viewpoints and actively promotes their own, than I do for those who agree with my politics and do nothing but complain.&lt;/p&gt;
&lt;p&gt;Perhaps history will record Vietnam as America&apos;s greatest military failure, perhaps not. There is ample evidence to suggest that Vietnam will forever act as a check on American territorial expansionism (remember, Hawaii and Alaska gained statehood after World War Two), and more importantly, as a checkpoint to hold flagrant use of American military muscle in place. But be that as it may, the fact remains that Vietnam had an incalculable effect on American foreign policy and domestic agenda, and will continue to do so for the next several generations. And, as numerous examples from my own experience and others can attest, the use of O/R-M can have the same effect (relativisitically speaking) on a development team&apos;s efforts.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;2023 Thoughts and Edits:&lt;/em&gt;&lt;/strong&gt; A decade and a half after I wrote this, the essay remains just as actively and hotly debated as ever, so I thought it would be appropriate to revisit some of the thoughts from 17 years ago.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Outrage over war as an analogy.&lt;/em&gt;&lt;/strong&gt; Look, let&apos;s get past that right now. When certain media pundits are screaming about a &amp;quot;War on Christmas&amp;quot;, we&apos;ve clearly lost all sense of the term &amp;quot;war&amp;quot;. More to the point, what most people mean by &amp;quot;war&amp;quot; is what the political scientists refer to as &amp;quot;total war&amp;quot;--the complete commitment of every aspect of national life to the victorious conclusion of some military conflict. Honestly, that term didn&apos;t apply to the US involvement in Vietnam, either, so if we&apos;re going to debate this further, we need to start being really precise with our terminology and analogies, and it just isn&apos;t worth it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;O/R-M tool doesn&apos;t suffer from that problem....&lt;/em&gt;&lt;/strong&gt; Yeah, turns out they all did, somewhere along the line.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;But wait! NoSQL! NewSQL! Multimodel databases!&amp;quot;&lt;/em&gt;&lt;/strong&gt; Oh, this gets interesting, and possibly meriting an essay of its own sometime. Suffice it to say that the impedance mismatch of objects to relations doesn&apos;t apply when the database stores document, but then we&apos;re dealing with the impedance mismatch of objects to documents. Data&apos;s &amp;quot;shape&amp;quot; doesn&apos;t get any less &amp;quot;shaped&amp;quot; just because it&apos;s different from what it used to be.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;You didn&apos;t understand dynamic languages well enough!&amp;quot;&lt;/em&gt;&lt;/strong&gt; I heard this more than a few times over the last 17 years, and I don&apos;t quite know how to tell people that &amp;quot;yes, I &lt;em&gt;do&lt;/em&gt; understand dynamic languages&amp;quot; other than to say, yes, your language of choice (Python, Ruby, Javascript, and a few others to boot) certainly have the metaobject capabilities to add new fields to an existing class, but all of that has to happen at runtime, and unless the database metadata is verified as part of the exercise, it&apos;s still not verified and therefore subject to some of the same typos and errors that a schema-validating database is supposed to protect you from.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;quot;What ever happened to...?&amp;quot;&lt;/em&gt;&lt;/strong&gt; Sadly, LINQ decided that it wasn&apos;t as interested in doing more to combine sets and objects, and instead Microsoft chose to put all their work into Entity Framework with a LINQ provider on top of that, despite the fact that LINQ could&apos;ve actually really tackled this whole thing quite effectively. &lt;em&gt;sigh&lt;/em&gt; No other language I&apos;ve seen has come quite that close, although there&apos;s been some interesting multi-model languages in the academic arena that have explored this idea, and (I thought) had some promising successes. But in the meantime, in the mainstream languages, we are still no further along than we were almost two decades ago.&lt;/p&gt;
&lt;p&gt;Which is what I find the saddest part of everything.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>The Vietnam of Computer Science</title>
      <link>http://blogs.newardassociates.com/blog/2006/the-vietnam-of-computer-science.html</link>
      <pubDate>Mon, 26 Jun 2006 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2006/the-vietnam-of-computer-science.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(At Microsoft&apos;s TechEd 2004 in San Diego, I was involved in a conversation at an after-conference event with Harry Pierson and Clemens Vasters, and as is typical when the three of us get together, architectural topics were at the forefront of our discussions. An crowd gathered around us, and it turned into an impromptu birds-of-a-feather session. The subject of object/relational mapping technologies came up, and it was there and then that I first coined the phrase, &amp;quot;Object/relational mapping is the Vietnam of Computer Science&amp;quot;. In the intervening time, I&apos;ve received numerous requests to flesh out the discussion behind that statement, and given Microsoft&apos;s recent announcement regarding &amp;quot;entity support&amp;quot; in ADO.NET 3.0 and the acceptance of the Java Persistence API as a replacement for both EJB Entity Beans and JDO, it seemed time to do exactly that.)&lt;/em&gt;&lt;/p&gt;
&lt;!--more--&gt;
&lt;blockquote&gt;
&lt;p&gt;NOTE: Translations that I&apos;m aware of:&lt;br /&gt;
&lt;strong&gt;8 November 2012&lt;/strong&gt;: A Bulgarian translation of this essay is &lt;a href=&quot;http://openspacelands.com/vietnam-computer-science/&quot;&gt;here&lt;/a&gt;; thanks to Dimitar Teykiyski for the work.&lt;br /&gt;
&lt;strong&gt;2 May 2025&lt;/strong&gt;: A Czech transation of this essay is &lt;a href=&quot;https://blog.zvestov.cz/software%20development/2025/04/29/vietnam-informatiky&quot;&gt;here&lt;/a&gt;; much thanks to&lt;br /&gt;
Luboš Račanský for the heavy lifting on that one.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;(2022 Note: This piece is now fifteen years old. I&apos;ve been tempted a few times to trim the historical section down--that&apos;s one of the piece&apos;s most-frequent complaints--but in the interests of not having multiple copies of it floating around, I&apos;ve kept it here. If you want to skip the history lesson, &lt;a href=&quot;#tech&quot;&gt;here&lt;/a&gt; is a quick link to the technology bits. --TN)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;No armed conflict in US history haunts the American military more than the Vietnam War, aka &amp;quot;Vietnam&amp;quot;. So many divergent elements coalesced to create the most decisive turning point in modern American history that it defies any layman&apos;s attempt to tease them apart. And yet, the story of Vietnam is fundamentally a simple one: The United States began a military project with simple yet unclear and conflicting goals, and quickly became enmeshed in a quagmire that not only brought down two governments (one legally, one through force of arms), but also deeply scarred American military doctrine for the next four decades (at least).&lt;/p&gt;
&lt;p&gt;Although it may seem trite to say it, &lt;strong&gt;&lt;em&gt;Object/Relational Mapping is the Vietnam of Computer Science&lt;/em&gt;&lt;/strong&gt;. It represents a quagmire which starts well, gets more complicated as time passes, and before long entraps its users in a commitment that has no clear demarcation point, no clear win conditions, and no clear exit strategy.&lt;/p&gt;
&lt;h2&gt;History&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.pbs.org/battlefieldvietnam/history/index.html&quot;&gt;PBS has a good synopsis of the war&lt;/a&gt;, but for those who are more interested in Computer Science than Political/Military History, the short version goes like this:&lt;/p&gt;
&lt;p&gt;South Indochina, now known as Vietnam, Thailand, Laos and Cambodia, has a long history of struggle for autonomy. Before French colonial rule (which began in the mid-1800s), South Indochina wrestled for regional independence from China. During World War Two, the Japanese conquered the area, only to be later &amp;quot;liberated&amp;quot; by the Allies, leading France to resume their colonial rule (as did the British in their colonial territories elsewhere in Asia and India). Following WWII, however, the people of South Indochina, having thrown off one oppressor, extended their anti-occupation efforts to fight the French instead of the Japanese, and in 1954 the French capitulated, signing the Geneva Peace Accords to formally grant Vietnam its independence. Unfortunately, global pressures perverted the efforts somewhat, and instead of a lasting peace agreement a temporary solution was created, dividing the nation at the 17th parallel, creating two nations where formerly no such division existed. Elections were to be held in 1956 to reunify the country, but the US feared that too much power would be given to the Communist Party of Vietnam through these elections, and instead backed a counter-Communist state south of the 17th parallel and formed a series of multilateral agreements around it, such as SEATO. The new nation of South Vietnam was born, and its first (dubiously) elected leader was Ngo Dinh Diem, a staunchly anti-Communist who almost immediately declared his country under Communist attack. The Eisenhower Administration remained supportive of the Diem government, but Diem&apos;s loyalty with the people was almost nonexistent from the beginning.&lt;/p&gt;
&lt;p&gt;By the time the US Democratic Party&apos;s John F Kennedy came to the White House, things were coming to a head in South Vietnam. Kennedy sent a team to Vietnam to research the conditions there and help formulate his strategy on the issue. In what&apos;s now known as the &amp;quot;December 1961 White Paper&amp;quot;, an argument for an increase in military, technical and economic aid was presented, along with large-scale American &amp;quot;advisers&amp;quot; to help stabilize the Diem government and eliminate the National Liberation Front, dubbed the $g(Viet Cong) by the US. What&apos;s not as widely known, however, is that a number of Kennedy&apos;s advisers argued against that buildup, calling Vietnam a &amp;quot;dead-end alley&amp;quot;.&lt;/p&gt;
&lt;p&gt;Faced with two diametrically opposite paths, Kennedy, as was typical for his administration, chose a middle path: instead of either a massive commitment or a complete withdrawal, Kennedy instead chose to seek a limited settlement, sending aid but not large numbers of troops, a path that was almost doomed from the beginning. Through a series of strategic blunders, including the forced relocation of rural villagers (known as the Strategic Hamlet Program), Diem&apos;s support was so deeply eroded that Kennedy hesitatingly and haltingly supported a coup, during which Diem was killed. Three weeks later, Kennedy was also assassinated, throwing the domestic US political scene into turmoil as well. Ironically, the conflict began by Kennedy would in fact later be associated most closely with his replacement.&lt;/p&gt;
&lt;h3&gt;Johnson&apos;s War&lt;/h3&gt;
&lt;p&gt;At the time of the Kennedy assassination, Vietnam had 16,000 American advisers in place, most of whom weren&apos;t involved in daily combat operations. Kennedy&apos;s Vice President and new replacement, however, Lyndon Baines Johnson (LBJ), was not convinced that this path was leading to success, and came to believe that more aggressive action was needed. Seizing on a dubious incident in which Vietnamese patrol boats attacked American destroyers[1] in the Gulf of Tonkin, Johnson used pro-war sentiment in Congress to pass a resolution that gave him powers to conduct military action without an explicit declaration of war. To put it simply, Johnson wanted to fight this war &amp;quot;in cold blood&amp;quot;: &amp;quot;This meant that America would go to war in Vietnam with the precision of a surgeon with little noticeable impact on domestic culture. A limited war called for limited mobilization of resources, material and human, and caused little disruption in everyday life in America.&amp;quot; (&lt;a href=&quot;http://www.pbs.org/battlefieldvietnam/history/index.html&quot;&gt;source&lt;/a&gt;) In essence, it would be a war whose only impact would be felt by the Vietnamese--American life and society would go on without any notice of the events in Vietnam, thus leaving Johnson to pursue his first great love, his &amp;quot;Great Society&amp;quot;, a domestic agenda designed to fix many of US society&apos;s ills, such as poverty[2]. History, of course, knows better, and--perhaps cruelly--calls the Vietnam conflict &amp;quot;Johnson&apos;s War&amp;quot;.&lt;/p&gt;
&lt;p&gt;Initially, it must be noted that Vietnam-as-disaster is a more recent perception; Americans polled as late as 1967 were convinced that the war was a good thing, that Communism needed to be stopped and that Vietnam, should it fall, would be the first of a series of nations to succumb to Communist subversion. This &amp;quot;Domino Theory&amp;quot; was a common refrain for American politics in the latter half of the 20th century. Concerns of this sort plagued American foreign policy ever since the Communists successfully or nearly-successfully subverted several European governments during hte latter half of the 1940&apos;s, and then China in the 50&apos;s. (It must be noted that Eisenhower and $g(John Foster Dulles), formulators of the theory, never included Vietnam in their ring of dominos that must be preserved, and in fact Eisenhower was surprisingly apathetic about Vietnam during some of his meetings with Kennedy during the White House transition.)&lt;/p&gt;
&lt;p&gt;In 1968, however, the Vietnam experience turned significantly, as the North Vietnamese and Viet Cong launched the Tet Offensive, a campaign that put to lie all of the reassurances of the American government that it was winning the war in Vietnam. Ironically, as had been the case for much of the war, the NVA/VC forces lost a substantial number of troops, far more than their American opponents, yet the Tet Offensive is widely considered by historians to be the breaking point of American will in the war. Following that, popular opinion turned on Johnson, and in a dramatic news conference, he announced that he would not seek re-election. Furthermore, he announced that he would seek a negotiated settlement with the Vietnamese.&lt;/p&gt;
&lt;h3&gt;Nixon&apos;s Promise&lt;/h3&gt;
&lt;p&gt;Unfortunately, American negotiating position was seriously weakened by the very protests that had brought the Americans to the negotiating table in the first place; NVA/VC leadership recognized that the NVA/VC forces, despite staggering military losses that nearly broke them (several times), could simply continue to do as they were doing, and wring concessions from the Americans without offering any in return. Running on a platform that consisted mostly of a promise to &amp;quot;Get America out of Vietnam&amp;quot;, Johnson&apos;s successor, Republican $g(Richard Nixon), tried several tactics to bring pressure to the NVA/VC forces to bargain, including increased air-combat presence (such as the Christmas bombings and Operation Menu) and regular violations of nearby Laos and Cambodia, pursuing the line of supplies from North Vietnam to cells in South Vietnam. Nothing worked, however, and in 1973 Nixon&apos;s administration signed the Paris Peace Agreement, ending American involvement in that conflict. Two years later, South Vietnam had been overrun, and on April 30, 1975, Communist forces captured Saigon, the capital of Vietnam, forcing the evacuation of the American embassy and the most memorable image of the war, that of streams of fleeing people seeking space on the Huey helicopter perched on the roof of the embassy.&lt;/p&gt;
&lt;h3&gt;War&apos;s End&lt;/h3&gt;
&lt;p&gt;The Second South Indochina War was over, America had experienced its most profound defeat ever in its history, and Vietnam became synonymous with &amp;quot;quagmire&amp;quot;. Its impact on American culture was immeasurable, as it taught an entire generation of Americans to fear and mistrust their government, it taught American leaders to fear any amount of US military casualties, and brought the phrase &amp;quot;clear exit strategy&amp;quot; directly into the American political lexicon. Not until $g(Ronald Reagan) used the American military to &amp;quot;liberate&amp;quot; the small island nation of Grenada would American military intervention be considered a possible tool of diplomacy by American presidents, and even then only with great sensitivity to domestic concern, as Bill Clinton would find out during his peacekeeping missions to Somalia and Kosovo. In quantifiable terms, too, Vietnam&apos;s effects clearly fell short of Johnson&apos;s goal of a war in &amp;quot;cold blood&amp;quot;. Final tally: 3 million Americans served in the war, 150,000 seriously wounded, 58,000 dead, and over 1,000 MIA, not to mention nearly a million NVA/Viet Cong troop casualties, 250,000 South Vietnamese casualties, and hundreds of thousands--if not millions, as some historians advocated--of civilian casualties.&lt;/p&gt;
&lt;h3&gt;Lessons of Vietnam&lt;/h3&gt;
&lt;p&gt;Vietnam presents an interesting problem to the student of military and political history--exactly what went wrong, when, and where? Obviously, the US government&apos;s unwillingness to admit its failures during the war makes for an easy scapegoat, but no government in the history of modern society has ever been entirely truthful with its population about its fortunes of war; one such example includes (but is not limited to) the same US government&apos;s careful censorship of activities during World War Two, fifty years earlier, known in American history as &amp;quot;the last &apos;good&apos; war&amp;quot;. It&apos;s also tempting to point to the lack of a military objective as the crucial failing point of Vietnam, but other non-military objectives have been successfully executed by the US and other governments without the kind of colossal failure accompanying Vietnam&apos;s story. Moreover, it&apos;s important to note that the US did, in fact, have a clear objective in what it wanted out of the conflict in South Indochina: to stop the fall of the South Vietnam government, and, barring that, the cessation of the &amp;quot;spread&amp;quot; of Communism. Was it the reluctance of the US government to unleash the military to its fullest capabilities, as General William Westmoreland always claimed? Certainly the failure in Vietnam was not a military one; the casualty figures make it clear that the US, by any other measure, was clearly winning.&lt;/p&gt;
&lt;p&gt;So what were the principal failures in Vietnam? And, more importantly, what does all this have to do with O/R Mapping?&lt;/p&gt;
&lt;h2 id=&quot;tech&quot;&gt;Vietnam and O/R mapping&lt;/h2&gt;
In the case of Vietnam, the United States political and military apparatus was faced with a deadly form of the Law of Diminishing Returns. In the case of automated Object/Relational Mapping, it&apos;s the same concern--that early successes yield a commitment to use O/R-M in places where success becomes more elusive, and over time, isn&apos;t a success at all due to the overhead of time and energy required to support it through all possible use-cases. In essence, the biggest lesson of Vietnam--for any group, political or otherwise--is to know when to &quot;cut bait and run&quot;, as fishermen say. Too often, as was the case in Vietnam, it is easy to justify further investment in a particular course of action by suggestion that abandoning that course somehow invalidates all the work--or, in Vietnam&apos;s case, the lives of American soldiers--that have already been paid. Phrases like &quot;We&apos;ve gone this far, surely we can see this thing through&quot; and &quot;To back out now is to throw away everything we&apos;ve sacrificed up until this point&quot; become commonplace. At least during the later, deeply bitter years of the second half of Vietnam, questions of patriotism came into question: if you didn&apos;t support the war, you were clearly a traitor, a Communist, obviously &quot;unAmerican&quot;, disrespectful of all American veterans of any war fought on any soil for whatever reason, and you probably kicked your dog to boot. (It didn&apos;t help the protestors&apos; cause that they blamed the soldiers for the war, holding them accountable--sometimes personally--for the decisions made by military and political leaders, most of whom neither the soldiers nor the protestors had ever met.)
&lt;p&gt;Recognizing that all analogies fail eventually, and that the subject of Vietnam is deeper than this essay can examine, there are still lessons to be learned here in an entirely different arena. One of the key lessons of Vietnam was the danger of what&apos;s colloquially called &amp;quot;the Slippery Slope&amp;quot;: that a given course of action might yield some early success, yet further investment into that action yields decreasingly commensurate results and increasibly dangerous obstacles whose only solution appears to be greater and greater commitment of resources and/or action. Some have called this &amp;quot;the Drug Trap&amp;quot;, after the way pharmaceuticals (legal or illegal) can have diminished effect after prolonged use, requiring upped dosage in order to yield the same results. Others call this &amp;quot;the Last Mile Problem&amp;quot;: that as one nears the end of a problem, it becomes increasingly difficult in cost terms (both monetary and abstract) to find a 100% complete solution. All are basically speaking of the same thing--the difficulty of finding an answer that allows our hero to &amp;quot;finish off&amp;quot; the problem in question, completely and satisfactorily.&lt;/p&gt;
&lt;p&gt;We begin the analysis of Object/Relational Mapping--and its relationship to the Second South Indochina War--by examining the reasons for it in the first place. What drives developers away from using traditional relational tools to access a relational database, and to prefer instead tools such as O/R-M&apos;s?&lt;/p&gt;
&lt;h3&gt;The Object-Relational Impedence Mismatch&lt;/h3&gt;
&lt;p&gt;To say that objects and relational data sets are somehow constructed differently is typically not a surprise to any developer who&apos;s ever used both; except in extremely simplistic situations, it becomes fairly obvious to recognize that the way in which a relational data store is designed is subtly--and yet profoundly--different than how an object system is designed.&lt;/p&gt;
&lt;p&gt;Object systems are typically characterized by four basic components: &lt;em&gt;identity&lt;/em&gt;, &lt;em&gt;state&lt;/em&gt;, &lt;em&gt;behavior&lt;/em&gt; and &lt;em&gt;encapsulation&lt;/em&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;State&lt;/em&gt; is a pretty self-explanatory concept, most closely akin to &amp;quot;the data&amp;quot;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Identity&lt;/em&gt; is an implicit concept in most O-O languages, in that a given object has a unique identity that is distinct from its state (the value of its internal fields)--two objects with the same state are still separate and distinct objects, despite being bit-for-bit mirrors of one another. This is the &amp;quot;identity vs. equivalence&amp;quot; discussion that occurs in languages like C++, C# or Java, where developers must distinguish between &amp;quot;a == b&amp;quot; and &amp;quot;a.equals(b)&amp;quot;.&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;behavior&lt;/em&gt; of an object is fairly easy to see, a collection of operations clients can invoke to manipulate, examine, or interact with objects in some fashion. (This is what distinguishes objects from passive data structures in a procedural language like C.)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Encapsulation&lt;/em&gt; is a key detail, preventing outside parties from manipulating internal object details, thus providing evolutionary capabilities to the object&apos;s interface to clients.[3]&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From this we can derive more interesting concepts, such as &lt;em&gt;type&lt;/em&gt;, a formal declaration of object state and behavior, &lt;em&gt;association&lt;/em&gt;, allowing types to reference one another through a lightweight reference rather than complete by-value ownership (sometimes called composition), &lt;em&gt;inheritance&lt;/em&gt;, the ability to relate one type to another such that the relating type incorporates all of the related type&apos;s state and behavior as part of its own, and &lt;em&gt;polymorphism&lt;/em&gt;, the ability to substitute an object in where a different type is expected.&lt;/p&gt;
&lt;p&gt;Relational systems describe a form of knowledge storage and retrieval based on predicate logic and truth statements. In essence, each row within a table is a declaration about a fact in the world, and SQL allows for operator-efficient data retrieval of those facts using predicate logic to create inferences from those facts. [Date04] and [Fussell] define the relational model as characterized by &lt;em&gt;relation&lt;/em&gt;, &lt;em&gt;attribute&lt;/em&gt;, &lt;em&gt;tuple&lt;/em&gt;, &lt;em&gt;relation value&lt;/em&gt; and &lt;em&gt;relation variable&lt;/em&gt;. A &lt;em&gt;relation&lt;/em&gt; is, at its heart, a truth predicate about the world, a statement of facts (&lt;em&gt;attributes&lt;/em&gt;) that provide meaning to the predicate. For example, we may define the relation &amp;quot;PERSON&amp;quot; as &lt;code&gt;{SSN, Name, City}&lt;/code&gt;, which states that &amp;quot;there exists a PERSON with a Social Security Number SSN who lives in City and is called Name&amp;quot;. Note that in a relation, attribute ordering is entirely unspecified. A &lt;em&gt;tuple&lt;/em&gt; is a truth statement within the context of a relation, a set of attribute values that match the required set of attributes in the relation, such as &amp;quot;&lt;code&gt;{PERSON SSN=&apos;123-45-6789&apos; Name=&apos;Catherine Kennedy&apos; City=&apos;Seattle&apos;}&lt;/code&gt;&amp;quot;. Note that two tuples are considered identical if their relation and attribute values are also identical. (This is, again, in contrast to an object system in which two objects are only identical if they have the same unique identifier--typically a memory address.)&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;relation value&lt;/em&gt;, then, is a combination of a relation and a set of tuples that match that relation, and a &lt;em&gt;relation variable&lt;/em&gt; is, like most variables, a placeholder for a given relation, but can change value over time. Thus, a relation variable &lt;code&gt;People&lt;/code&gt; can be written to hold the relation &lt;code&gt;{PERSON}&lt;/code&gt;, and consist of the relation value&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{ {PERSON SSN=&apos;123-45-6789&apos; Name=&apos;Catherine Kennedy&apos; City=&apos;Seattle&apos;},
  {PERSON SSN=&apos;321-54-9876&apos; Name=&apos;Charlotte Neward&apos; City=&apos;Redmond&apos;},
  {PERSON SSN=&apos;213-45-6978&apos; Name=&apos;Cathi Gero&apos; City=&apos;Redmond&apos;} }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These are commonly referred to as tables (relation variable), rows (tuples), columns (attributes), and a collection of relation variables as a database. These basic element types can be combined against one another using a set of operators (described in some detail in Chapter 7 of [Date04]): restrict, project, product, join, divide, union, intersection and difference, and these form the basis of the format and approach to SQL, the universally-acceptance language for interacting with a relational system from operator consoles or programming languages. The use of these operators allow for the creation of &lt;em&gt;derived relation values&lt;/em&gt;, relations that are calculated from other relation values in the database--for example, we can create a relation value that demonstrates the number of people living in individual cities by making use of the project and restrict operators across the &lt;code&gt;People&lt;/code&gt; relation variable defined above.&lt;/p&gt;
&lt;p&gt;Already, it&apos;s fairly clear to see that there are distinct differences between how the relational world and object world view the &amp;quot;proper&amp;quot; design of a system, and more will become apparent as time progresses. It&apos;s important to note, however, that so long as programmers prefer to use object-oriented programming languages to access relational data stores, there will always be some kind of object-relational mapping taking place--the two models are simply too different to bridge silently. (Arguably, the same is true of object-oriented and procedural programming, but that&apos;s another argument for another day.)&lt;/p&gt;
&lt;p&gt;O/R mappings can take place in a variety of forms, the easiest of which to recognize is the automated O/R mapping tool, such as TopLink, Hibernate / NHibernate, or Gentle.NET. Another form of mapping is the hand-coded one, in which programmers use relational-oriented tools, such as JDBC or ADO.NET, to access relational data and extract it into a form more pleasing to object-minded developers &amp;quot;by hand&amp;quot;. A third is to simply accept the shape of the relational data as &amp;quot;the&amp;quot; model from which to operate, and slave the objects around it to this approach; this is also known in the patterns lexicon as Table Data Gateway [PEAA, 144] or Row Data Gateway [PEAA 152]; many data-access layers in both Java and .NET use this approach and combine it with code-generation to simplify the development of that layer. Sometimes we build objects around the relational/table model, put some additional behavior around it, and call it Active Record [PEAA, 160].&lt;/p&gt;
&lt;p&gt;In truth, this basic approach--to slave one model into the terms and approach of the other--has been the traditional answer to the impedance mismatch, effectively &amp;quot;solving&amp;quot; the problem by ignoring one half of it. Unfortunately, most development efforts, like the Kennedy Administration, aren&apos;t willing to see this through to its logical conclusion with a wholesale commitment to one approach over the other. For example, while most development teams would be happy to adopt an &amp;quot;objects-only&amp;quot; approach, doing so at the storage level implies the use of an Object Oriented DataBase Management System (OODBMS), a topic that frequently has no traction within upper management or the corporate data management team. The opposite approach--a &amp;quot;relational-only&amp;quot; approach--is almost nonsensical to consider, given the technology of the day at the time this was written[4].&lt;/p&gt;
&lt;p&gt;Given that it&apos;s impossible, then, to &amp;quot;unleash the objects to their fullest capabilities&amp;quot;, as General Westmoreland might call it, we&apos;re left with some kind of hybrid object-to-relational mapping approach, preferably one that&apos;s automated as much as possible, so that developers can focus on their Domain Model, rather than on the details of the object-to-table(s) mapping. And here, unfortunately, is where the potential quagmire begins.&lt;/p&gt;
&lt;h3&gt;The Object-to-Table Mapping Problem&lt;/h3&gt;
&lt;p&gt;One of the first and most easily-recognizable problems in using objects as a front-end to a relational data store is that of how to map classes to tables. At first, it seems a fairly straightforward exercise--tables map to types, columns to fields. Even the field types appear to line up directly against the relational column types, at least to a fairly isomorphic degree: VARCHARs to Strings, INTEGERs to ints, and so on. So it makes sense that for any given class defined in the system, a corresponding table--likely to be of the same or closely related name--is defined to go with it. Or, perhaps, if the object code is being written to an already existing schema, then the class maps to the table.&lt;/p&gt;
&lt;p&gt;But as time progresses, it&apos;s only natural that a well-trained object-oriented developer will seek to leverage inheritance in the object system, and seek ways to do the same in the relational model. Unfortunately, the relational model does not support any sort of polymorphism or IS-A kind of relation, and so developers eventually find themselves adopting one of three possible options to map inheritance into the relational world: table-per-class, table-per-concrete-class, or table-per-class-family. Each of them carries potentially significant drawbacks.&lt;/p&gt;
&lt;p&gt;The table-per-class approach is perhaps the most easily understood, for it seeks to minimize the &amp;quot;distance&amp;quot; between the object model and the relational model; each class in the inheritance hierarchy gets its own relational table, and objects of derived types are stitched together from relational JOINs across the various inheritance-based tables. So, for example, if an object model has the base class Person, with Student derived from Person and GraduateState derived from Student, then there will be three tables required to hold this model, PERSON, STUDENT, and GRADUATESTUDENT, each holding the fields corresponding to the class of the same name. Relating these tables together, however, requires each to have an independent primary key (one whose value is not actually stored in the object entity) so that each derived class can have a foreign key relation to its superclass&apos;s table. The reason for this is clear: a GraduateStudent object, by virtue of its IS-A relationship to Student and Person, is a collection of all three sets of state, and the distinction between the classes is largely removed by the time an object of this type is created--in both Java and .NET, for example, the object itself is a chunk of memory that holds the instance fields defined in all of its classes and superclasses, along with a pointer to the table of methods defined by that same hierarchy. This means that when querying for a particular instance at the relational level, at least three JOINs must be made in order to bring all of the object&apos;s state into the object program&apos;s working memory.&lt;/p&gt;
&lt;p&gt;Actually, it gets worse than that--if the object hierarchy continues to grow, say to include Professor, Staff, Undergrad (inherits from Student), and a whole hierarchy of AdjunctEmployees (inheriting from Staff), and the program wants to find all Persons whose last name is Smith, then JOINs must be done for every derived class in the system, since the semantics of &amp;quot;find all Persons&amp;quot; means that the query must seek data on the PERSON table, but then do an expensive set of JOINs to bring in the rest of the data from across the rest of the database, pulling in the PROFESSOR table to fetch the rest of the data, not to mention the UNDERGRAD, ADJUCTEMPLOYEE, STAFF, and other tables. Considering that JOINs are among the most expensive expressions in RDBMS queries, this is clearly not something to undertake lightly.&lt;/p&gt;
&lt;p&gt;As a result, developers typically adopt one of the other two approaches, more complex in outlook but more efficient when dealing with relational storage: they either create a table per concrete (most-derived) class, preferring to adopt denormalization and its costs, or else they create a single table for the entire hierarchy, often in either case creating a discriminator column to indicate to which class each row in the table belongs. (Various hybrids of these schemes are also possible, but typically don&apos;t create results that are significantly different from these two.) Unfortunately, the denormalization costs are often significant for a large volume of data, and/or the table(s) will contain significant amounts of empty columns, which will need NULLability constraints on all columns, eliminating the powerful integrity constraints offered by an RDBMS.&lt;/p&gt;
&lt;p&gt;Inheritance mapping isn&apos;t the end of it; associations between objects, the typical 1:n or m:n cardinality associations so commonly used in both SQL and/or UML, are handled entirely differently: in object systems, association is unidirectional, from the associator to the associatee (meaning the associated object(s) have no idea they are in fact associated unless an explicit bidirectional association is established), whereas in relational systems the association is actually reversed, from the associatee to the associator (via foreign key columns). This turns out to be surprisingly important, as it means that for m:n associations, a third table must be used to store the actual relationship between associator and associatee, and even for the simpler 1:n relationships the associator has no inherent knowledge of the relations to which it associates--discovering that data requires a JOIN against any or all associated tables at some point. (When to actually retrieve that data is a subject of some debate--see the Loading Paradox, below).&lt;/p&gt;
&lt;h3&gt;The Schema-Ownership Conflict&lt;/h3&gt;
&lt;p&gt;Discussions of inheritance-to-table and association mapping schemes also reveals a basic flaw: At heart, many object-relational mapping tools assume that the schema is something that can be defined according to schemes that help optimize the O/R-M&apos;s queries against the relational data. But this belies a basic problem, that often the database schema itself is not under the direct control of developers, but instead is owned by another group within the company, typically the database administration (DBA) group. To whom does responsibility for designing the database--and deciding when schema changes are permissible--belong?&lt;/p&gt;
&lt;p&gt;In many cases, developers begin a new project with a &amp;quot;clean slate&amp;quot;, an empty relational database whose schema is theirs to define as they see fit. But, soon after the project has shipped (sometimes even earlier than that, due to political and/or &amp;quot;turf war&amp;quot; issues), it becomes apparent that the developers&apos; ownership of the schema is temporary at best--various departments begin clamoring for reports against the database, DBAs are held accountable to the performance of the database thereby giving them cause to call for &amp;quot;refactoring&amp;quot; and denormalization of the data, and other development teams may start inquiring about how they might make use of the data stored therein. Before too long, the schema must be &amp;quot;frozen&amp;quot;, thereby potentially creating a barrier to object model refactoring (see The Coupling Concern, below). In addition, these other teams will expect to see a relational model defined in relational terms, not one which supports an entirely orthogonal form of persistence--for example, the &amp;quot;discriminator&amp;quot; column from the Inheritance-to-Table Mapping Problem will represent difficulties, and arguably be all but unusable, to relational report generators such as Crystal Reports. Unless developers are willing to write all reports (and their UIs, and their printing code, and their ad-hoc capabilities...) by hand, this is usually going to be an unacceptable state of affairs.&lt;/p&gt;
&lt;p&gt;(To be fair, this is not so much a technical problem as it is a political problem, but it still represents a serious problem regardless of its source--or solution. And as such, it still represents an impediment to an object/relational mapping solution.)&lt;/p&gt;
&lt;h3&gt;The Dual-Schema Problem&lt;/h3&gt;
&lt;p&gt;A related issue to the question of schema ownership is that in an O/R-M solution, the metadata to the system is held fundamentally in two different places: once in the database schema, and once in the object model (another schema, if you will, expressed in Java or C# instead of DDL). Updates or refactorings to one will likely require similar updates or refactorings to the other. Refactoring code to match database schema changes is widely considered to be the easier of the two--refactoring the database frequently requires some kind of migration and/or adaptation of data already within the database, where code has no such requirement. (Objects, at least in this discussion, are ephemeral in-memory instances that will disappear once the process holding them terminates. If the objects are stored in some kind of object form that can persist across process execution--such as serialized object instances stored to disk--then refactoring objects becomes equally problematic.)&lt;/p&gt;
&lt;p&gt;More importantly, while it&apos;s not uncommon for code to be deployed specifically to a single application, frequently database instances are used by more than one application, and it&apos;s frequently unacceptable to business to trigger a company-wide refactoring of code simply because a refactoring on one application requires a similar database-driven refactoring. As a result, as the system grows over time, there will be increasing pressure on the developers to &amp;quot;tie off&amp;quot; the object model from the database schema, such that schema changes won&apos;t require similar object model refactorings, and vice versa. In some cases, where the O/R-M doesn&apos;t permit such disconnection, an entirely private database instance may have to be deployed, with the exact schema the O/R-M-based solution was built against, creating yet another silo of data in an IT environment where pressure is building to &lt;em&gt;reduce&lt;/em&gt; such silos.&lt;/p&gt;
&lt;h3&gt;Entity Identity Issues&lt;/h3&gt;
&lt;p&gt;As if these problems weren&apos;t enough, we then walk into another problem, that of &lt;em&gt;identity&lt;/em&gt; of objects and relations. As noted above, object systems use an implicit sense of identity, typically based on the object&apos;s location in memory (the ubiquitous &lt;em&gt;this&lt;/em&gt; pointer); alternatively, this is sometimes referred to as an &lt;em&gt;OID&lt;/em&gt; (Object IDentifier), usually in systems which don&apos;t directly expose memory locations, such as the object database (where an in-memory pointer is pretty useless as an identifier outside of the database process). In a relational model, however, identity is implicit in the state itself--two rows with the exact same state are typically considered a relational data corruption, as the same fact asserted twice is redundant and counterproductive. To be fair, we should be a bit more explicit here; a relational system can, in fact, permit duplicate tuples (as described above), but this is often explicitly disallowed by explicit relational constraints, such as PRIMARY KEY constraints. In those situations where duplicate values are allowed, there is no way for a relational system to determine which of the two duplicate rows are being retrieved--there is no implicit sense of identity to the relation except that offered by its attributes. The same is not true of object systems, where two objects that contain precisely identical bit patterns in two different locations of memory are in fact separate objects. (This is the reason for the distinction between &amp;quot;==&amp;quot; and &amp;quot;.equals()&amp;quot; in Java or C#.) The implication here is simple: if the two systems are going to agree on the sense of identity, the relational system must offer some kind of unique identity concept (usually an auto-incrementing integer column) to match that of the notion of object identity.&lt;/p&gt;
&lt;p&gt;This causes some serious concerns regarding automated O/R systems, because the sense of identity is entirely different--if two separate user sessions interact with the same relation in storage, the relational database system&apos;s concurrency systems kick in and ensure some form of concurrent access, typically via the transactional metaphor (ACID). If an O/R system retrieves a relation out of storage (essentially forming a &amp;quot;view&amp;quot; over the data), we now have a second source of data identity, one in the database (protected by the aforementioned transactional scheme), and one in the in-memory object representation of that data, which has no consistent transactional support aside from that built into the language (such as the monitors concept in Java and .NET) or libraries (such as System.Transactions in .NET 2.0), either of which can be--and unfortuantely frequently are--easily ignored by developers. Managing isolation and concurrency is not an easy problem to solve, and unfortunately the languages and platforms commonly available to developers aren&apos;t yet as consistent or flexible as the database transaction metaphor.&lt;/p&gt;
&lt;p&gt;What complicates this problem further is that many O/R systems introduce significant caching support into the O/R layer (usually in an attempt to improve performance and avoid round-trips to the database), and this in turn presents some problems, particularly if the caching system is not a write-through cache: when does the actual &amp;quot;flush&amp;quot; to the database take place, and what does this say about transactional integrity if the application code believes the write to have occurred when in fact it hasn&apos;t? This problem in turn only compounds when the O/R system runs in multiple processes in front of the database engine, commonly found in clustered or farmed application server scenarios. Now the data identity is spread across &lt;em&gt;n+1&lt;/em&gt; locations, &lt;em&gt;n&lt;/em&gt; being the number of application server nodes, and &lt;em&gt;1&lt;/em&gt; being the database itself. Each node must somehow signal its intent to do an update to the other nodes in order to obtain some kind of concurrency construct to prevent simultaneous access (by another instance of the same session, or by an instance of a different session accessing the same data), which takes time, killing performance. Even in the case of a read-only cache, updates to the data store must somehow be signaled to the caches running in the application server nodes, requiring server-to-client communication originating from the database; support for this is not well-understood or documented in the current crop of modern relational databases.&lt;/p&gt;
&lt;h3&gt;The Data Retrieval Mechansim Concern&lt;/h3&gt;
&lt;p&gt;Once the entity is stored within the database, how exactly do we retrieve it? A purely object-oriented approach would make use of object approaches for retrieval, ideally using constructor-style syntax identifying the object(s) desired, but unfortunately constructor syntax isn&apos;t generic enough to allow for something that flexible; in particular, it lacks the ability to initialize a collection of objects, and queries frequently need to return a collection, rather than just a single entity. (Multiple trips to the database to fetch entities individually is generally considered too wasteful, in both latency and bandwidth, to consider credibly as an alternative--see the Load-Time Paradox, below, for more.) As a result, we typically end up with one of Query-By-Example (QBE), Query-By-API (QBA), or Query-By-Language (QBL) approaches.&lt;/p&gt;
&lt;p&gt;A QBE approach states that you fill out an object template of the type of object you&apos;re looking for, with fields in the object set to a particular value to use as part of the query-filtration process. So, for example, if you&apos;re querying the Person object/table for people with the last name of Smith, you set up the query like so:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;Person p = new Person(); // assumes all fields are set to null by default
p.LastName = &amp;quot;Smith&amp;quot;;
ObjectCollection oc = QueryExecutor.execute(p);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The problem with the QBE approach is obvious: while it&apos;s perfectly sufficient for simple queries, it&apos;s not nearly expressive enough to support the more complex style of query that frequently we need to execute--&amp;quot;find all Persons named Smith or Cromwell&amp;quot; and &amp;quot;find all Persons NOT named Smith&amp;quot; are two examples. While it&apos;s not impossible to build QBE approaches that handle this (and more complex scenarios), it definitely complicates the API significantly. More importantly, it also forces the domain objects into an uncomfortable position--they &lt;em&gt;must&lt;/em&gt; support nullable fields/properties, which may be a violation of the domain rules the object would otherwise seek to support--a Person without a name isn&apos;t a very useful object, in many scenarios, yet this is exactly what a QBE approach will demand of domain objects stored within it. (Practitioners of QBE will often argue that it&apos;s not unreasonable for an object&apos;s implementation to take this into account, but again this is neither easy nor frequently done.)&lt;/p&gt;
&lt;p&gt;As a result, usually the second step is to have the object system support a &amp;quot;Query-By-API&amp;quot; approach, in which queries are constructed by query objects, usually something of the form:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;Query q = new Query();
q.From(&amp;quot;PERSON&amp;quot;).Where(
  new EqualsCriteria(&amp;quot;PERSON.LAST_NAME&amp;quot;, &amp;quot;Smith&amp;quot;));
ObjectCollection oc = QueryExecutor.execute(q);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, the query is not based on an empty &amp;quot;template&amp;quot; of the object to be retrieved, but off of a set of &amp;quot;query objects&amp;quot; that are used together to define a Command-style object for executing against the database. Multiple criteria are connected using some kind of binomial construct, usually &amp;quot;And&amp;quot; and &amp;quot;Or&amp;quot; objects, each of which contain unique Criteria objects to test against. Additional filtration/manipulation objects can be tagged onto the end, usually by appending calls such as &amp;quot;OrderBy(&lt;em&gt;field-name&lt;/em&gt;)&amp;quot; or &amp;quot;GroupBy(&lt;em&gt;field-name&lt;/em&gt;)&amp;quot;. In some cases, these method calls are actually objects constructed by the programmer and strung together explicitly.&lt;/p&gt;
&lt;p&gt;Developers quickly note that the above approach is (generally) much more verbose than the traditional SQL approach, and certain styles of queries (particularly the more unconventional joins, such as outer joins) are much more difficult--if not impossible--to represent in the QBA approach.&lt;/p&gt;
&lt;p&gt;On top of this, we have a more subtle problem, that of the reliance on developers&apos; dicipline: both the table name (&lt;code&gt;&amp;quot;PERSON&amp;quot;&lt;/code&gt;) and the column name in the criteria (&lt;code&gt;&amp;quot;PERSON.LAST_NAME&amp;quot;&lt;/code&gt;) are standard strings, taken as-is and fed to the system at runtime with no sort of validity-checking until then. This presents a classic problem in programming, that of the &amp;quot;fat-finger&amp;quot; error, where a developer doesn&apos;t actually query the &amp;quot;PERSON&amp;quot; table, but the &amp;quot;PRESON&amp;quot; table instead. While a quick unit-test against a live database instance will reveal the error during unit-testing, this presumes two facts--that the developers are religious about adopting unit-testing, and that the unit-tests are run against database instances. While the former is slowly becoming more of a guarantee as more and more developers become &amp;quot;test-infected&amp;quot; (borrowing Gamma&apos;s and Beck&apos;s choice of terminology), the latter is still entirely open to discussion and interpretation, owing to the fact that setting-up and tearing-down the database instance appropriately for unit tests is still difficult to do in a database. (While there are a variety of ways to circumvent this problem, few of them seem to be in use.)&lt;/p&gt;
&lt;p&gt;We&apos;re also faced with the basic problem that greater awareness of the logical--or physical--data representation is required on the part of the developer--instead of simply focusing on how the objects are related to one another (through simple associations such as arrays or collection instances), the developer must now have greater awareness of the form in which the objects are stored, leaving the system somewhat vulnerable to database schema changes. This is sometimes obviated by a hybrid approach between the two, whereby the system will take responsibility for interpreting the associations, leaving the developer to write something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;Query q = new Query();
Field lastNameFieldFromPerson = Person.class.getDeclaredField(&amp;quot;lastName&amp;quot;);
q.From(Person.class).Where(new EqualsCriteria(lastNameFieldFromPerson, &amp;quot;Smith&amp;quot;));
ObjectCollection oc = QueryExecutor.execute(q);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which solves part of the schema-awareness problem and the &amp;quot;fat-fingering&amp;quot; problem but still leaves the developer vulnerable to the concerns over verbosity and still doesn&apos;t address the complexity of putting together a more complex query, such as a multi-table (or multi-class, if you will) query joined on several criteria in a variety of ways.&lt;/p&gt;
&lt;p&gt;So, then, the next task is to create a &amp;quot;Query-By-Language&amp;quot; approach, in which a new language, similar to SQL but &amp;quot;better&amp;quot; somehow, is written to support the kind of complex and powerful queries normally supported by SQL; OQL and HQL are two examples of this. The problem here is that frequently these languages are a subset of SQL and thus don&apos;t offer the full power of SQL. More importantly, the O/R layer has now lost an important &amp;quot;selling point&amp;quot;, that of the &amp;quot;objects and only objects&amp;quot; mantra that begat it in the first place; using a SQL-like language is almost just like using SQL itself, so how can it be more &amp;quot;objectish&amp;quot;? While developers may not need to be aware of the physical schema of the data model (the query language interpreter/executor can do the mapping discussed earlier), developers will need to be aware of how object associations and properties are represented within the language, and the subset of the object&apos;s capabilities within the query language--for example, is it possible to write something like this?&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;SELECT Person p1, Person p2 
FROM Person 
WHERE p1.getSpouse() == null 
  AND p2.getSpouse() == null 
  AND p1.isThisAnAcceptableSpouse(p2) 
  AND p2.isThisAnAcceptableSpouse(p1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In other words, scan through the database and find all single people who find each other acceptable. While the &amp;quot;isThisAnAcceptableSpouse&amp;quot; method is clearly a method that belongs on the Person class (each Person instance may have its own criteria by which to judge the acceptability of another single--are they blonde, brunette, or redhead, are they making more than $100,000 a year, and so on), it&apos;s not clear if executing this method is possible in the query language, nor is it clear if it should be. Even for the most trivial implementations, a serious performance hit will be likely, particularly if the O/R layer must turn the relational column data into objects in order to execute the query. In addition, we have no guarantees that the developer wrote this method to be at all efficient, and no ways to enforce any sort of performance-aware implementation.&lt;/p&gt;
&lt;p&gt;(Critics will argue that this is a workable problem, proposing two possible solutions. One is to encode the preference data in a separate table and make that part of the query; this will result in a hideously complicated query that will take several pages in length and likely require a SQL expert to untangle later when new preferential criteria want to be added. The other is to encode this &amp;quot;acceptability&amp;quot; implementation in a stored procedure within the database, which now removes code entirely from the object model and leaves us without an &amp;quot;object&amp;quot;-based solution whatsoever--acceptable, but only if you accept the premise that not all implementation can rest inside the object model itself, which rejects the &amp;quot;objects and nothing but objects&amp;quot; premise with which many O/R advocates open their arguments.)&lt;/p&gt;
&lt;h3&gt;The Partial-Object Problem and the Load-Time Paradox&lt;/h3&gt;
&lt;p&gt;It has long been known that network traversal, such as that done when making a traditional SQL request, takes a significant amount of time to process. (Rough benchmarks have placed this value at anywhere from three to five orders of magnitude, compared against a simple method call on either the Java or .NET platform[5]; roughly analogous, if it takes you twenty minutes to drive to work in the morning, and we call that the time required to execute a local method call, four orders of magnitude to that is roughly the time it takes to travel to Pluto, or just shy of fourteen years, one way.) This cost is clearly non-trivial, so as a result, developers look for ways to minimize this cost by optimizing the number of round trips and data retrieved.&lt;/p&gt;
&lt;p&gt;In SQL, this optimization is achieved by carefully structuring the SQL request, making sure to retrieve only the columns and/or tables desired, rather than entire tables or sets of tables. For example, when constructing a traditional drill-down user interface, the developer presents a summary display of all the records from which the user can select one, and once selected, the developer then displays the complete set of data for that particular record. Given that we wish to do a drill-down of the Persons relational type described earlier, for example, the two queries to do so would be, in order (assuming the first one is selected):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;SELECT id, first_name, last_name FROM person;

SELECT * FROM person WHERE id = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In particular, take notice that only the data desired at each stage of the process is retrieved--in the first query, the necessary summary information and identifier (for the subsequent query, in case first and last name wouldn&apos;t be sufficient to identify the person directly), and in the second, the remainder of the data to display. In fact, most SQL experts will eschew the &amp;quot;*&amp;quot; wildcard column syntax, preferring instead to name each column in the query, both for performance and maintenance reasons--performance, since the database will better optimize the query, and maintenance, because there will be less chance of unnecessary columns being returned as DBAs or developers evolve and/or refactor the database table(s) involved. This notion of being able to return a part of a table (though still in relational form, which is important for reasons of closure, described above) is fundamental to the ability to optimize these queries this way--most queries will, in fact, only require a portion of the complete relation.&lt;/p&gt;
&lt;p&gt;This presents a problem for most, if not all, object/relational mapping layers: the goal of any O/R is to enable the developer to see &amp;quot;nothing but objects&amp;quot;, and yet the O/R layer cannot tell, from one request to another, how the objects returned by the query will be used. For example, it is entirely feasible that most developers will want to write something along the lines of:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;Person[] all = QueryManager.execute(...);
Person selected = DisplayPersonsForSelection(all);
DisplayPersonData(selected);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Meaning, in other words, that once the Person to be displayed has been chosen from the array of Persons, no further retrieval action is necessary--after all, you have your object, what more should be necessary?&lt;/p&gt;
&lt;p&gt;The problem here is that the data to be displayed in the first Display...() call is &lt;em&gt;not&lt;/em&gt; the complete Person, but a subset of that data; here we face our first problem, in that an object-oriented system like C# or Java cannot return just &amp;quot;parts&amp;quot; of an object--an object is an object, and if the Person object consists of 12 fields, then all 12 fields will be present in every Person returned. This means that the system faces one of three uncomfortable choices: one, require that Person objects must be able to accomodate &amp;quot;nullable&amp;quot; fields, regardless of the domain restrictions against that; two, return the Person completely filled out with all the data comprising a Person object; or three, provide some kind of on-demand load that will obtain those fields if and when the developer accesses those fields, even indirectly, perhaps through a method call.&lt;/p&gt;
&lt;p&gt;(Note that some object-based languages, such as ECMAScript, view objects differently than class-based languages, such as Java or C# or C++, and as a result, it is entirely possible to return objects which contain varying numbers of fields. That said, however, few languages possess such an approach, not even everybody&apos;s favorite dynamic-language poster child, Ruby, and until such languages become widespread, such discussion remains outside the realm of this essay.)&lt;/p&gt;
&lt;p&gt;For most O/R layers, this means that objects and/or fields of objects must be retrieved in a lazy-loaded manner, obtaining the field data on demand, because retrieving all of the fields of all of the Person objects/relations would &amp;quot;clearly&amp;quot; be a huge waste of bandwidth for this particular scenario. Typically, the object&apos;s entire set of fields will be retrieved when any field not-yet-returned is accessed. (This approach is preferred to a field-by-field approach because there&apos;s less chance of the &amp;quot;N+1 query problem&amp;quot;, in which retrieving all the data from an object requires 1 query to retrieve the primary key + N queries to retrieve each field from the table as necessary. This minimizes the bandwidth consumed to retrieve data--no unaccessed field will have its data retrieved--but clearly fails to minimize network round trips.)&lt;/p&gt;
&lt;p&gt;Unfortunately, fields within the object are only part of the problem--the other problem we face is that objects are frequently associated with other objects, in various cardinalities (one-to-one, one-to-many, many-to-one, many-to-many), and an O/R mapping has to make some up-front decisions about when to retrieve these associated objects, and despite the best efforts of the O/R-M&apos;s developers, there will always be common use-cases where the decision made will be exactly the wrong thing to do. Most O/R-M&apos;s offer some kind of developer-driven decision-making support, usually some kind of configuration or mapping file, to identify exactly what kind of retrieval policy will be, but this setting is global to the class, and as such can&apos;t be changed on a situational basis.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;Given, then, that objects-to-relational mapping is a necessity in a modern enterprise system, how can anyone proclaim it a quagmire from which there is no escape? Again, Vietnam serves as a useful analogy here--while the situation in South Indochina required a response from the Americans, there were a variety of responses available to the Kennedy and Johson Administrations, including the same kind of response that the recent fall of Suharto in Malaysia generated from the US, which is to say, none at all. (Remember, Eisenhower and Dulles didn&apos;t consider South Indochina to be a part of the Domino Theory in the first place; they were far more concerned about Japan and Europe.)&lt;br /&gt;
Several possible solutions present themselves to the O/R-M problem, some requiring some kind of &amp;quot;global&amp;quot; action by the community as a whole, some more approachable to development teams &amp;quot;in the trenches&amp;quot;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Abandonment.&lt;/strong&gt; Developers simply give up on objects entirely, and return to a programming model that doesn&apos;t create the object/relational impedance mismatch. While distasteful, in certain scenarios an object-oriented approach creates more overhead than it saves, and the ROI simply isn&apos;t there to justify the cost of creating a rich domain model. ([Fowler] talks about this to some depth.) This eliminates the problem quite neatly, because if there are no objects, there is no impedance mismatch.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Wholehearted acceptance.&lt;/strong&gt; Developers simply give up on relational storage entirely, and use a storage model that fits the way their languages of choice look at the world. Object-storage systems, such as the &lt;a href=&quot;http://www.db4objects.com&quot;&gt;db4o project&lt;/a&gt; (which, alas, as of 2021 is essentially a defunct project), solve the problem neatly by storing objects directly to disk, eliminating many (but not all) of the aforementioned issues; there is no &amp;quot;second schema&amp;quot;, for example, because the only schema used is that of the object definitions themselves. While many DBAs will faint dead away at the thought, in an increasingly service-oriented world, which eschews the idea of direct data access but instead requires all access go through the service gateway thus encapsulating the storage mechanism away from prying eyes, it becomes entirely feasible to imagine developers storing data in a form that&apos;s much easier for them to use, rather than DBAs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Manual mapping.&lt;/strong&gt; Developers simply accept that it&apos;s not such a hard problem to solve manually after all, and write straight relational-access code to return relations to the language, access the tuples, and populate objects as necessary. In many cases, this code might even be automatically generated by a tool examining database metadata, eliminating some of the principal criticism of this approach (that being, &amp;quot;It&apos;s too much code to write and maintain&amp;quot;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Acceptance of O/R-M limitations.&lt;/strong&gt; Developers simply accept that there is no way to efficiently and easily close the loop on the O/R mismatch, and use an O/R-M to solve 80% (or 50% or 95%, or whatever percentage seems appropriate) of the problem and make use of SQL and relational-based access (such as &amp;quot;raw&amp;quot; JDBC or ADO.NET) to carry them past those areas where an O/R-M would create problems. Doing so carries its own fair share of risks, however, as developers using an O/R-M must be aware of any caching the O/R-M solution does within it, because the &amp;quot;raw&amp;quot; relational access will clearly not be able to take advantage of that caching layer.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Integration of relational concepts into the languages.&lt;/strong&gt; Developers simply accept that this is a problem that should be solved by the language, not by a library or framework. For the last decade or more, the emphasis on solutions to the O/R problem have focused on trying to bring objects closer to the database, so that developers can focus exclusively on programming in a single paradigm (that paradigm being, of course, objects). Over the last several years, however, interest in &amp;quot;scripting&amp;quot; languages with far stronger set and list support, like Ruby, has sparked the idea that perhaps another solution is appropriate: bring relational concepts (which, at heart, are set-based) into mainstream programming languages, making it easier to bridge the gap between &amp;quot;sets&amp;quot; and &amp;quot;objects&amp;quot;. Work in this space has thus far been limited, constrained mostly to research projects and/or &amp;quot;fringe&amp;quot; languages, but several interesting efforts are gaining visibility within the community, such as functional/object hybrid languages like Scala or F#, as well as direct integration into traditional O-O languages, such as the LINQ project from Microsoft for C# and Visual Basic. One such effort that failed, unfortunately, was the SQL/J strategy; even there, the approach was limited, not seeking to incorporate sets into Java, but simply allow for embedded SQL calls to be preprocessed and translated into JDBC code by a translator.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Integration of relational concepts into frameworks.&lt;/strong&gt; Developers simply accept that this problem is solvable, but only with a change of perspective. Instead of relying on language or library designers to solve this problem, developers take a different view of &amp;quot;objects&amp;quot; that is more relational in nature, building domain frameworks that are more directly built around relational constructs. For example, instead of creating a Person class that holds its instance data directly in fields inside the object, developers create a Person class that holds its instance data in a RowSet (Java) or DataSet (C#) instance, which can be assembled with other RowSets/DataSets into an easy-to-ship block of data for update against the database, or unpacked from the database into the individual objects.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that this list is not presented in any particular order; while some are more attractive to others, which are &amp;quot;better&amp;quot; is a value judgment that every developer and development team must make for themselves.&lt;/p&gt;
&lt;p&gt;Just as it&apos;s conceivable that the US could have achieved some measure of &amp;quot;success&amp;quot; in Vietnam had it kept to a clear strategy and understood a more clear relationship between commitment and results (ROI, if you will), it&apos;s conceivable that the object/relational problem can be &amp;quot;won&amp;quot; through careful and judicious application of a strategy that is celarly aware of its own limitations. Developers must be willing to take the &amp;quot;wins&amp;quot; where they can get them, and not fall into the trap of the Slippery Slope by looking to create solutions that increasingly cost more and yield less. Unfortunately, as the history of the Vietnam War shows, even an awareness of the dangers of the Slippery Slope is often not enough to avoid getting bogged down in a quagmire. Worse, it is a quagmire that is simply too attractive to pass up, a Siren song that continues to draw development teams from all sizes of corporations (including those at Microsoft, IBM, Oracle, and Sun, to name a few) against the rocks, with spectacular results. Lash yourself to the mast if you wish to hear the song, but let the sailors row.&lt;/p&gt;
&lt;h2&gt;Endnotes&lt;/h2&gt;
&lt;p&gt;[1] Later analysis by the principals involved--including then-Secretary of Defense Robert McNamara--concluded that half of the attack never even took place.&lt;/p&gt;
&lt;p&gt;[2] It is perhaps the greatest irony of the war, that the man Fate selected to lead during America&apos;s largest foreign entanglement was a leader whose principal focus was entirely aimed within his own shores. Had circumstances not conspired otherwise, the hippies chanting &amp;quot;Hey, hey LBJ, how many boys did you kill today&amp;quot; outside the Oval Office could very well have been Johnson&apos;s staunchest supporters.&lt;/p&gt;
&lt;p&gt;[3] Ironically, encapsulation, for purposes of maintenance simplicity, turns out to be a major motivation for almost all of the major innovations in Linguistic Computer Science--procedural, functional, object, aspect, even relational technologies ([Date02]) and other languages all cite &amp;quot;encapsulation&amp;quot; as major driving factors.&lt;/p&gt;
&lt;p&gt;[4] We could, perhaps, consider stored procedure languages like T-SQL or PL/SQL to be &amp;quot;relational&amp;quot; programming languages, but even then, it&apos;s extremely difficult to build a UI in PL/SQL.&lt;/p&gt;
&lt;p&gt;[5] In this case, I was measuring Java RMI method calls against local method calls. Similar results are pretty easily obtainable for SQL-based data access by measuring out-of-process calls against in-process calls using a database product that supports both, such as Cloudscape/Derby or HSQL (Hypersonic SQL).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (18 May 2021)&lt;/strong&gt;: Since I was in here to convert the original HTML into Markdown (for easier processing by my blog engine), I took a moment to do a little reformatting and few clarifying remarks.&lt;/p&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;[Fussell]&lt;/strong&gt;: &lt;em&gt;Foundations of Object Relational Mapping&lt;/em&gt;, by Mark L. Fussell, v0.2 (mlf-970703)&lt;br /&gt;
&lt;strong&gt;[Fowler]&lt;/strong&gt; &lt;em&gt;Patterns of Enterprise Application Architecture&lt;/em&gt;, by Martin Fowler&lt;br /&gt;
&lt;strong&gt;[Date04]&lt;/strong&gt;: &lt;em&gt;Introduction to Database Systems&lt;/em&gt;, 8th Edition, by Chris Date.&lt;br /&gt;
&lt;strong&gt;[Neward04]&lt;/strong&gt;: &lt;em&gt;Effective Enterprise Java&lt;/em&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Can the CLR &quot;go dynamic&quot;? Absolutely... and arguably, already is</title>
      <link>http://blogs.newardassociates.com/blog/2006/can-the-clr-go-dynamic-absolutely-and-arguably-already-is.html</link>
      <pubDate>Sat, 6 May 2006 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2006/can-the-clr-go-dynamic-absolutely-and-arguably-already-is.html</guid>
      	<description>
	&lt;!--more--&gt;
&lt;p&gt;&lt;a href=&quot;http://www.knowing.net&quot;&gt;Larry O&apos;Brien&lt;/a&gt; asks&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Are you confident that continuations can be even semi-efficiently implemented on the CLR? I&apos;m not.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;and in turn &lt;a href=&quot;http://www.knowing.net/PermaLink,guid,785f41a5-3acf-47d5-b26a-580c46e8a117.aspx&quot;&gt;references his blog&lt;/a&gt;, where he points out a quote from Patrick Logan that says &amp;quot;If Microsoft really looks at Ruby as competition then Microsoft has already lost the war&amp;quot; and offers this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;If Microsoft thinks Ruby is important, they&apos;re ignoring the threat to them posed by X (where, I suspect, X = LISP), or&lt;/li&gt;
&lt;li&gt;If Microsoft thinks Ruby is competition, they will not implement it and therefore be doomed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Not long ago, Microsoft posted a job opening for a developer &amp;quot;first task will be to drive the exploration of other dynamic languages such as Ruby and JavaScript on the CLR&amp;quot;, so my feeling is that if Microsoft could get a Ruby on the CLR, they&apos;d be thrilled.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;First of all, said job has already been filled--Jim Hugunin, of Jython fame, joined Microsoft some months ago on the CLR team and has since pushed a 1.0 beta of his IronPython implementation (which, according to Python benchmarks, is already faster than the corresponding native C Python implementation), available from Microsoft. Second of all, I won&apos;t suggest that I know what Mr. Logan was thinking when he made his comment, but I suspect he&apos;s thinking more about development process than technological issues. What&apos;s more, I don&apos;t agree with the comment at all: I think Microsoft needs to pursue high-level &amp;quot;scripting&amp;quot; languages on the CLR, if only because they ARE more productive than statically-typed languages like C#/Java/C++; this is the lesson we forgot, and inadvertently abandoned, from VB. Which leads me to suggest that &lt;em&gt;Ruby is the VB of the next decade&lt;/em&gt;. Or, if not Ruby, then something like it.&lt;/p&gt;
&lt;p&gt;Larry goes on to say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ruby is not easy to implement on the CLR, at least in part because a complete Ruby implementation requires continuations, which are not modeled within the CLR. This isn&apos;t just laziness on the part of langauge implementors. The CLR presents a machine architecture different than the wide-open architecture in which most compiler experience has been gathered. The CLR architecture is safer, but more restrictive, when it comes to manipulating the stack, which is central to continuations.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ruby actually requires more in the way of support than just continuations, but it&apos;s not necessarily impossible to implement on the CLR; it&apos;s just hard to implement on the CLR &lt;em&gt;in a high-performing manner&lt;/em&gt; using &lt;em&gt;today&apos;s CLR&lt;/em&gt;. That&apos;s part of what Jim is there to do, evolve the CLR to better support languages with Ruby&apos;s interesting featureset (like open classes and the &amp;quot;missing_method&amp;quot; method) in such a way that it doesn&apos;t tear down perf.&lt;/p&gt;
&lt;p&gt;Continuations are not impossible to support, however they are currently more or less impossible to support given the current lack of access to the underlying stack frames in the managed environment--you&apos;d need some support from the runtimes (either the JVM or the CLR) to make it work. Such runtime support would not be too difficult to add, however, as both environments already have rich and powerful stack-walking mechanisms (because both environments use the thread stack as bookkeeping tools, among other things, and need to be able to crawl through those stack markers for a variety of reasons, such as security checks), and it would not be hard to create a runtime-level mechanism that allowed code to &amp;quot;take a snapshot&amp;quot; of the stack--and its related object graph--from a certain point to a certain point, and save off that state to some arbitrary location. In many respects, it would be similar to serializing an object, I believe. In fact, we could imagine something along the lines of:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// All this is totally C#-like pseudocode. Imagine 
// something similar for Java if you like. 
// 
public int ContinuationedMethod() { 
  SnapshotMarker sm = new SnapshotMarker(); 
    // in other words, the StackSnapshot will only crawl 
    // back to the SnapshotMarker referenced when we 
    // take the thread&apos;s snapshot; this way we don&apos;t crawl 
    // all the way back to the Thread&apos;s starting point (unless 
    // you really wanted to). 
  int x = 1; 
  for (int i=0; i&amp;lt;10; i++) { 
    x = x * i; 
    if (i == 5) { 
      StackSnapshot ss = Thread.Current.TakeSnapshot(sm); 
        // At this point, the managed stack is walked, heap-referenced 
        // objects are captured, the instruction label that we&apos;re on is 
        // saved, and a StackSnapshot is allocated and returned. 
        // However, when ss is later rehydrated--using, say, ss.Resume(), 
        // we need some way of knowing that. So, following the lead of the 
        // old Unix fork() call, I presume that a &amp;quot;null&amp;quot; return value from 
        // TakeSnapshot is our way of knowing that we are resuming. 
        // 
      if (ss == null) 
        continue; 
      else 
      {
        // store ss someplace for later retrieval and return, either by 
        // throwing an exception if you like or just plain-old-&amp;quot;return 0&amp;quot;
        // or something
        //
      }
    } 
  } 
  return x; 
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the API that I cooked up in all of thirty seconds, but hopefully you get the idea--it would be difficult to do from outside the runtime, as the many exception-trace stack-frame approaches suggest.&lt;/p&gt;
&lt;p&gt;In the end, continuations are not, I believe, nearly as hard to implement--on either the JVM or the CLR--as some might suggest. Had I the money, I would go off and build the necessary Ruby-esque features we&apos;d want into the CLR (through Rotor) or the JVM (through... uh... the JCL source, I guess, though the licensing there bothers me) for use. Anybody got some cash laying around to cover my mortgage while I do this? :-)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Sample programmers&apos; quiz</title>
      <link>http://blogs.newardassociates.com/blog/2006/sample-programmers-quiz.html</link>
      <pubDate>Sat, 11 Mar 2006 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2006/sample-programmers-quiz.html</guid>
      	<description>
	&lt;p&gt;While training last week, the group I was training asked for some help in interviewing candidates for some openings. I came up with the following, and thought I&apos;d post it in the interests of giving teams looking to hire some new folks. This was created specifically to find candidates with 2-3 years&apos; experience with some familiarity with web applications.&lt;/p&gt;
&lt;!--more--&gt;
&lt;ul&gt;
&lt;li&gt;What was the most interesting computer/technical book you read last year? Why?&lt;/li&gt;
&lt;li&gt;What was the last new programming language you learned?&lt;/li&gt;
&lt;li&gt;How do you convince a customer that what they want is wrong?&lt;/li&gt;
&lt;li&gt;Describe the last elegant hack you wrote. Why, where, how, when, ...?&lt;/li&gt;
&lt;li&gt;Write a servlet that prints all parameters and HTTP headers to the browser. Build an Ant script that compiles, and creates the appropriate .war file for deployment into Tomcat.&lt;/li&gt;
&lt;li&gt;Name all of the verbs in the HTTP/1.1 specification.&lt;/li&gt;
&lt;li&gt;Given a tag library, &amp;quot;utilitytags.jar&amp;quot; which is described by the tag library descriptor file &amp;quot;utilitytags.tld&amp;quot;, please write a JSP that uses the &amp;quot;foobar&amp;quot; tag from that library.&lt;/li&gt;
&lt;li&gt;What keyword in Java do we use to grant package-level access to class members?&lt;/li&gt;
&lt;li&gt;When do you think you should use an abstract base class as opposed to using an interface?&lt;/li&gt;
&lt;li&gt;How do I protect code in a multithreaded environment from being executed by more than one thread at a time?&lt;/li&gt;
&lt;li&gt;Please fill in the necessary code to return the contents of the &amp;quot;last name&amp;quot; column using the following SQL statement; make all necessary changes so that this code will compile:
&lt;pre&gt;&lt;code&gt;public void printUsers(Connection conn)
{
  String sql = &amp;quot;SELECT last_name FROM users WHERE first_name = &apos;Sean&apos;&amp;quot;;
  ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;What is a design pattern? Please describe three patterns that you have used and why you used them and what the consequences of using them were, both good and bad. &lt;/LI&gt;&lt;/UL&gt;More suggestions, questions, and comments welcome. Note that some of the questions are deliberate traps, some of them are deliberately open-ended in order to encourage discussion and opportunities to flesh out what&apos;s on the resume, and some of them are intended not to hear the answers but to watch the candidates&apos; reaction. (Yeah, I&apos;m a hard interviewer. :-) )&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; A couple of commenters have pointed out that a few of the questions are answered by simply looking up stuff (in the HTTP specification, for example). Two answers come to mind why I want people to know this without having to look it up--one, sometimes I want to pitch a slowball just to see how they&apos;ll react and answer, and two, if they can answer the question without having to look it up, it means they &lt;em&gt;know&lt;/em&gt; the spec, which is a far, far different thing than being able to look something up.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>My kingdom for a good macro language!</title>
      <link>http://blogs.newardassociates.com/blog/2006/my-kingdom-for-a-good-macro-language.html</link>
      <pubDate>Sat, 11 Mar 2006 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2006/my-kingdom-for-a-good-macro-language.html</guid>
      	<description>
	&lt;p&gt;Much of the power, it seems, of languages like Ruby or Nemerle or LISP derives from the ability to create chunks of code that operate in turn on the code itself; a long-standing meme of the LISP world is that &amp;quot;code is data&amp;quot;, meaning it can be manipulated and twisted and tweaked in structural ways before being executed. And this isn&apos;t the first time we&apos;ve experimented with this idea: CLOS, Common List Object System, was where Gregor Kiczales, of AspectJ fame, cut his teeth on the AOP concepts, largely because it seemed to him that having a completely open meta-object protocol was too dangerous--but that&apos;s another story.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;So given that everybody&apos;s going ga-ga over Ruby&apos;s MOP/metaprogramming facilities, it occurs to me, is what we&apos;re really after an MOP for Java? Because such things exist already in the academic world--see OpenJava, for example. Is that what Java would need to do to evolve and take back the productivity label? Is the lack of productivity in Java (the chief complaint of Java today, according to Bruce Tate) due directly to its statically-typed nature, or is it simply the inability to twist the language in ways that are closer to what the programming staff really needs and wants? After all, if you take away some of the MOP features that Ruby uses &lt;a href=&quot;http://blogs.tedneward.com/2006/03/02/Scala+Pt+2+Brevity.aspx&quot; target=&quot;_blank&quot;&gt;to make the Person class pretty brief&lt;/a&gt;, such as the attr_reader and attr_writer manipulators, then a lot of Ruby&apos;s terseness goes away, too.&lt;/p&gt;
&lt;p&gt;Not that functional languages aren&apos;t still a good way to go--and I will continue the discussion of Scala, largely because there&apos;s some nifty stuff there we haven&apos;t touched yet--but I&apos;m becoming more and more convinced that the problem with Java isn&apos;t in its statically-typed nature, but in the language we use to generate bytecode for the platform. (.NET may have some better answers here, given Microsoft&apos;s greater friendliness to languages on their platform, but it&apos;s just another platform similar to the JVM in a lot of ways, and as such has the same drawbacks and benefits as Java does in this regard.)&lt;/p&gt;
&lt;p&gt;So where are all the good macro-friendly tools/languages for Java? (And that means, &amp;quot;macros as from LISP&amp;quot;, not &amp;quot;macros as from C&amp;quot;. Frankly, C++ could use a good MOP, too, but that&apos;s another story for another day...)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Scala reactions, pt3: Everything&apos;s an object</title>
      <link>http://blogs.newardassociates.com/blog/2006/scala-pt-3-everythings-an-object.html</link>
      <pubDate>Sat, 4 Mar 2006 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2006/scala-pt-3-everythings-an-object.html</guid>
      	<description>
	&lt;p&gt;In the Scala documentation, they make a point of calling out the idea that &amp;quot;everything&apos;s an object&amp;quot;, including numbers and (most importantly) functions. Smalltalk had this same perception/assumption in its design, and Scala, as a result, sometimes feels very Smalltalk-ish.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;For example, when Scala sees this expression:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;2 + 4 * 7
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Scala actually translates that into a sequence of method calls as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;2.+(4.*(7))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yes, in Scala, there is operator overloading, but the rules are slightly different than what you might expect from C++ or C#. In Scala, there really is no predetermined set of symbols that are defined as &amp;quot;operators&amp;quot;, per se. Instead, Scala simply sees any collection of tokens (within reason) as methods to be invoked. (I should point out here that the case of integer constants being used as parameters to methods on integer constants is a special case that the Scala compiler recognizes and generates more efficient bytecode around, so the overhead of a method call isn&apos;t present. It&apos;s an obvious optimization, when you think about it.) This means that Scala can make use of some &amp;quot;operators&amp;quot; that traditionally C# and Java have eschewed:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;val nums = 1 :: 2 :: 3 :: 4 :: Nil;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, nums will be List (specifically, a List[T], where &amp;quot;T&amp;quot; is of type Integer), and the &amp;quot;::&amp;quot; operator is used to concatenate an element from the right and return a new List; &amp;quot;Nil&amp;quot; is, like &amp;quot;true&amp;quot; and &amp;quot;false&amp;quot;, a special constant signifying the empty list. So, written out, the above turns into:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;val nums = 1.::(2.::(3.::(4.::(Nil))));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since the Scala compiler recognizes both &amp;quot;::&amp;quot; and &amp;quot;.::&amp;quot; as being equivalent, and has no predetermined since of operators, this means that any given method definition can be used in either its &amp;quot;dot&amp;quot; form, or its &amp;quot;operator&amp;quot; form; this means that in cases where the method expects a single operand, we can write the method without the &amp;quot;dot&amp;quot; notation as well. So, for example...&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;&amp;gt; val msg = &amp;quot;Hello World&amp;quot;
val msg: java.lang.String(&amp;quot;Hello World&amp;quot;) = Hello World
&amp;gt; msg equals &amp;quot;Hello World&amp;quot;
true: scala.Boolean
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that here I&apos;m using the Scala interpreter instead of the traditional class; Scala is equally at home as either compiled code or interpreted, and running the interpreter to test certain snippets is just a delight, compared to having to cruft up class scaffolding just to test a simple language concept.&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;Thus far, this concept of everything being an object may not seem all that powerful; in fact, arguably, the above section should probably have been mentioned in the previous post than this one, since the ability to recognize new operators is itself an extension of the idea of expressing exactly what you want, nothing more. In fact, in the &amp;quot;Scala by Example&amp;quot; document that comes with the Scala download, they show a traditional Java (but which could easily be written to read in C++ or C#) quicksort implementation:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;def sort(xs: Array[int]): unit = {
  def swap(i: int, j: int): unit = {
    val t = xs(i); xs(i) = xs(j); xs(j) = t;
  }
  def sort1(l: int, r: int): unit = {
    val pivot = xs((l + r) / 2);
    var i = l, j = r;
    while (i &amp;lt;= j) {
      while (xs(i) &amp;lt; pivot) { i = i + 1 }
      while (xs(j) &amp;gt; pivot) { j = j - 1 }
      if (i &amp;lt;= j) {
        swap(i, j);
        i = i + 1;
        j = j - 1;
      }
    }
    if (l &amp;lt; j) sort1(l, j);
    if (j &amp;lt; r) sort1(i, r);
  }
  sort1(0, xs.length - 1);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and then show a later version of the exact same implementation, but written more &amp;quot;Scala-ish&amp;quot;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;def sort(xs: List[int]): List[int] =
  if (xs.length &amp;lt;= 1) xs
  else {
    val pivot = xs(xs.length / 2);
    sort(xs.filter(x =&amp;gt; x &amp;lt; pivot))
    ::: xs.filter(x =&amp;gt; x == pivot)
    ::: sort(xs.filter(x =&amp;gt; x &amp;gt; pivot))
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which is clearly more terse and defined. (Note that the second example uses lists instead of arrays, and that in Scala, List[int] is Scala&apos;s syntax for a generic type, in this case List, parameterized on &amp;quot;int&amp;quot;. In other words, Scala uses &amp;quot;[T]&amp;quot; notation instead of Java/C++/C#&apos;s angle-bracket notation. Takes some getting used to, but it&apos;s easier to adjust to than you might think.) The last example really demonstrates what I&apos;m about to discuss next: the use of functions as first-class citizens in the language, because the above implementation makes use of three anonymous functions passed in to the List&apos;s filter method. So, translating the second example into pseudocode for a second (again, taken from the Scala By Example document):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the list is empty or consists of a single element, it is already sorted, so return it immediately.&lt;/li&gt;
&lt;li&gt;If the list is not empty, pick an an element in the middle of it as a pivot.&lt;/li&gt;
&lt;li&gt;Partition the lists into two sub-lists containing elements that are less than, respectively greater than the pivot element, and a third list which contains elements equal to pivot.&lt;/li&gt;
&lt;li&gt;Sort the first two sub-lists by a recursive invocation of the sort function.&lt;/li&gt;
&lt;li&gt;The result is obtained by appending the three sub-lists together.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is only possible because we can pass in the anonymous functions &amp;quot;x &amp;lt; pivot&amp;quot;, &amp;quot;x == pivot&amp;quot; and &amp;quot;x &amp;gt; pivot&amp;quot; into the &amp;quot;filter&amp;quot; function on List.&lt;/p&gt;
&lt;p&gt;As hinted, functions are full objects in of their own right, and are just as easily accessible as parameters as any other object passed into a method. So, for example, consider the above sort implementation again. The only thing that really &amp;quot;ties&amp;quot; it to sorting lists of integers is the comparison that goes on to determine if the item inside the list is less-than, equal-to, or greater-than other elements in the list. If we could somehow genericize that decision-making, we could make the quicksort be entirely generic and applicable to lists-of-anything. (As it turns out, it&apos;s sometimes easier to do this by simply having any types that wish to be sorted implement the &amp;lt;, == and &amp;gt; methods in Scala, and this is possible to enforce via interfaces and mixins and such, but bear with me on this example.)&lt;/p&gt;
&lt;p&gt;We&apos;ll start by making sort generic:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;def sort(xs: List[T]): List[T] =
  if (xs.length &amp;lt;= 1) xs
  else {
    // ...
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first part of the test is entirely generic already--if we&apos;re at the point where the list is 1 or 0 elements long, just return the list as it is. Now we examine the else block:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;def sort(xs: List[T]): List[T] =
  if (xs.length &amp;lt;= 1) xs
  else {
    val pivot = xs(xs.length / 2);
    sort(xs.filter(x =&amp;gt; &amp;lt;i&amp;gt;(x less-than pivot)&amp;lt;/i&amp;gt; )
    ::: xs.filter(x =&amp;gt; &amp;lt;i&amp;gt;(x equal-to pivot)&amp;lt;/i&amp;gt; )
    ::: sort(xs.filter(x =&amp;gt; &amp;lt;i&amp;gt;(x greather-than pivot)&amp;lt;/i&amp;gt; )
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So in other words, we just need syntax to allow a caller to pass in the implementations for less-than, equal-to, and greater-than. Turns out we can do that by specifiying the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;def sort[T](xs: List[T], lt: (T, T) =&amp;gt; boolean, 
            eq: (T, T) =&amp;gt; boolean, gt: (T, T) =&amp;gt; boolean) : List[T] =
  if (xs.length &amp;lt;= 1) xs
  else {
    val pivot = xs(xs.length / 2);
    sort(xs.filter(x =&amp;gt; lt(x, pivot)), lt, eq, gt)
      ::: xs.filter(x =&amp;gt; eq(x, pivot))
      ::: sort(xs.filter(x =&amp;gt; gt(x, pivot)), lt, eq, gt)
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice the signature for &amp;quot;lt&amp;quot;, &amp;quot;eq&amp;quot; and &amp;quot;gt&amp;quot;--this says lt should be a function that takes two arguments (of the generic type T) and returns a boolean. &amp;quot;eq&amp;quot; and &amp;quot;gt&amp;quot; are defined similarly. This, then, means we can use it thusly:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;object App with Application {

  def lessThan(lhs: int, rhs: int) : boolean =
    if (lhs &amp;lt; rhs) true else false;

  def equalTo(lhs: int, rhs: int) : boolean =
    if (lhs == rhs) true else false;

  def greaterThan(lhs: int, rhs: int) : boolean =
    if (lhs &amp;gt; rhs) true else false;

  val nums : List[int] = 1 :: 4 :: 3 :: 2 :: Nil;
  val sorted = Test.sort(nums, lessThan, equalTo, greaterThan);
  System.out.println(sorted);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unfortunately, looking at this particular implementation, it&apos;s not really convincing that this is any better than the first approach--we have to define three functions that return less-than, equal, and greater-than for each type T that we want to sort. Ugh.&lt;/p&gt;
&lt;p&gt;This is where the notion of an anonymous function becomes important, however. Instead of defining those three functions outright and referencing them by name in the sort call, we can instead define them &quot;on the fly&quot; in the call itself:
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;object App with Application {
  val nums : List[int] = 1 :: 4 :: 3 :: 2 :: Nil;
  val sorted = Test.sort(nums, (lhs:int, rhs:int) =&amp;gt; if (lhs &amp;lt; rhs) true else false, 
                               (lhs:int, rhs:int) =&amp;gt; if (lhs == rhs) true else false,
                               (lhs:int, rhs:int) =&amp;gt; if (lhs &amp;gt; rhs) true else false );
  System.out.println(sorted);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, the notation is a bit complicated, but once you get used to it, it&apos;s fairly straightforward. The &amp;quot;=&amp;gt;&amp;quot; indicates that we&apos;re defining a function inline. The parentheses before it contain the expected parameters to the function, and the statement that follows defines the body of the function. Note that we don&apos;t have to explicitly offer a return type, because Scala&apos;s type inference capabilities can deduce that the function returns &amp;quot;boolean&amp;quot;. Which, as it turns out, is exactly what the sort function was expecting in the first place: a function that takes two T&apos;s (int&apos;s, since this is a List[int]) and returns a boolean. Boo-yah!&lt;/p&gt;
&lt;p&gt;Er... maybe.&lt;/p&gt;
&lt;p&gt;If you&apos;re like a lot of developers, you&apos;re looking at the above and you&apos;re not necessarily won over. There&apos;s a couple of things that could be red-flagging at the back of your head:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;I thought that the Don&apos;t-Repeat-Yourself principle says it&apos;s better to collect this stuff into one place, for easier maintenance?&amp;quot; True. But consider this: how often have you written a method in a class because you HAD to, not because it satisfied the DRY principle? Java&apos;s use of nested inner classes (and C++&apos;s inability to allow you to define functions in-line) forces the use of methods, even in those situations where you know, without a doubt, that you will never execute or reference this code more than once.&lt;/li&gt;
&lt;li&gt;&amp;quot;Shouldn&apos;t this be making the sort &lt;i&gt;shorter&lt;/i&gt; to use?&amp;quot; False. Anytime you genericize something, you run a (strong) risk that you&apos;re actually making it more complicated, and therefore more difficult to use. If we really wanted to make sort easier, I&apos;d ask for a function parameter &amp;quot;compare&amp;quot; that does the traditional C-style comparison (return -1 for less-than, 0 for equal, 1 for greater-than), and write the necessary code inline in the sort() to use that method to determine if something fit the less-than, equal, or greater-than filters. That&apos;s not really the point, though... so I didn&apos;t.&lt;/li&gt;
&lt;li&gt;&amp;quot;That syntax is just ugly.&amp;quot; True. To a Java, C++ or C# programmer. To a LISP programmer, though, there&apos;s clearly some parentheses missing. :-) Seriously, the syntax isn&apos;t what you&apos;re used to, perhaps, but like most syntactic decisions, it has deeper meaning and rules around it that makes it look that way. The same is true of Java, C++ (remember the &amp;quot;&amp;gt;&amp;gt;&amp;quot; rule in multiple template usage?) and C#, and will remain so for as long as computers are what&apos;s interpreting our source code.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The thing is, the use of functions-as-objects is just the tip of the iceberg. Turns out there&apos;s some more interesting tidbits that we can make use of when using functions as objects, one of which is called &amp;quot;currying&amp;quot;.&lt;/p&gt;
&lt;p&gt;One frequently useful idiom in functional languages is to return a function, rather than the results of applying that function. This means that we can delay actually executing the function until later--this is what we&apos;re doing (sort of in reverse, passing it in rather than returning it) in the sort example above. We pass in the comparator function into the filter routine, who then executes it. Returning a function is of the same mindset--hand back a function to be executed by the caller (either implicitly or explicitly) that produces the results desired.&lt;/p&gt;
&lt;p&gt;In some situations, however, the full inputs of the function aren&apos;t known at the time the function is returned. Or, as is often the case, some of the inputs are known, but others aren&apos;t. So the compiler, when handed a partially-called function, defers execution and uses parameters found in the caller&apos;s scope (wherever that may be) to fill out the remainder of the necessary functional inputs and carry out execution. Make sense?&lt;/p&gt;
&lt;p&gt;Probably not; currying takes a while to ingest. At least it did for me. An example may serve to help cement this down.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;def sum(f: int =&amp;gt; int) = {
  def sumF(a: int, b: int): int =
    if (a &amp;gt; b) 0 else f(a) + sumF(a + 1, b);
  sumF
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we see a function &amp;quot;sum&amp;quot;, which takes a function &amp;quot;f&amp;quot; that takes an int and returns an int. It in turn uses a nested function, &amp;quot;sumF&amp;quot;, that takes two integer arguments &amp;quot;a&amp;quot; and &amp;quot;b&amp;quot; and applies the function &amp;quot;f&amp;quot; to them so long as &amp;quot;a &amp;gt; b&amp;quot;. Notice, however, that sum neither takes the parameters &amp;quot;a&amp;quot; and &amp;quot;b&amp;quot;, nor does it manufacture them from someplace in order to pass them in; in fact, it noticeably excludes them when it returns, without decoration, the function &amp;quot;sumF&amp;quot; as the return value of the &amp;quot;sum&amp;quot; function. (Notice again how we don&apos;t need to specify the return value of &amp;quot;sum&amp;quot;, because Scala&apos;s type inference can figure it out without additional help from the programmer.)&lt;/p&gt;
&lt;p&gt;So how does one use the sum function? By applying both parameters--the function to apply to each argument, and a pair of ints to supply bounds to be summed up:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;sum(x =&amp;gt; x * x)(1, 10)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which, in this case, summarizes the expression 1^1 + 2^2 + 3^3 + ... + 10^10. (Readers with a background in mathematics will recognize it as a sequence, the &amp;quot;big E&amp;quot; notation, as I used to call it back in sophomore Advanced Algebra. Probably has a more formal name than that, but my background isn&apos;t in math.) To understand where the currying takes place, look at how the compiler sees this expression:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;(sum(x =&amp;gt; x * s))(1,10)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which means, of course, pass the function &amp;quot;x * x&amp;quot; into sum, which then returns the sumF function with f(a) replaced by &amp;quot;a * a&amp;quot;. sumF still expects two integer parameters, however, so the compiler takes the next expression &amp;quot;(1, 10)&amp;quot; and applies those as &amp;quot;a&amp;quot; and &amp;quot;b&amp;quot;, respectively. From there, it&apos;s a simple exercise in recursion to arrive at the answer.&lt;/p&gt;
&lt;p&gt;The power of currying becomes more apparent when you see that because the compiler is willing to accept partially-evaluated functions as first-order types, we can partially-define functions in terms of other functions, as in:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;def sumInts = sum(x =&amp;gt; x);
def sumSquares = sum(x =&amp;gt; x * x);
def sumPowersOfTwo = sum(powerOfTwo);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and then use them as top-level functions without any special syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;&amp;gt; sumSquares(1, 10) + sumPowersOfTwo(10, 20)
267632001: scala.Int
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, if for some reason the definition of sum() needed to change, it would ripple throughout this tiny framework by making one change in one place. (Don&apos;t know why sum() would need to change, mind you, but that&apos;s the problem with simple examples--it&apos;s sometimes hard to see the really positive benefits unless you get more complicated, but more complicated examples are harder to use to present the concept.) And I&apos;d be lying to you if I said that I &amp;quot;get&amp;quot; how to use this in code more practical than summations yet--I still have a lot of internalizing to do. But I can see the outskirts of where it might be useful, and if I can get working samples of how and where it would, believe me, they&apos;re going up here. :-)&lt;/p&gt;
&lt;p&gt;In the meantime, next is traits and mixins, which are both features that are definitely easier to see applicability.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Scala reactions, pt2: Brevity</title>
      <link>http://blogs.newardassociates.com/blog/2006/scala-pt-2-brevity.html</link>
      <pubDate>Fri, 3 Mar 2006 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2006/scala-pt-2-brevity.html</guid>
      	<description>
	&lt;p&gt;While speaking at a conference in the .NET space (the patterns &amp;amp; practices Summit, to be precise), Rocky Lhotka once offered an interesting benchmark for language productivity, a variation on the kLOC metric, what I would suggest is the &amp;quot;CLOC&amp;quot; idea: how many lines of code required to express a concept. (Or, since we could argue over formatting and style until the cows come home, how many &lt;I&gt;keystrokes&lt;/I&gt; rather than lines of code.)&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Let&apos;s start with a simple comparison. The basic concept we want to express is that of a domain object type, my favorite example, that of a Person type. In domain lingo,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A Person has a first name, a last name, and a spouse. Persons always have a first and last name, but may not have a spouse. Persons know how to say hi, by introducing themselves and their spouse.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;which, as domain logic goes, is pretty simple and lame, but serves to highlight the metric pretty effectively.&lt;/p&gt;
&lt;p&gt;In Java, we express this class like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    private String lastName;
    private String firstName;
    private Person spouse;
    
    public Person(String fn, String ln, Person s)
    {
        lastName = ln; firstName = fn; spouse = s;
    }
    public Person(String fn, String ln)
    {
        this(fn, ln, null);
    }
    
    public String getFirstName()
    { 
        return firstName;
    }
    
    public String getLastName()
    { 
        return lastName;
    }
    
    public Person getSpouse()
    { 
        return spouse;
    }
    public void setSpouse(Person p) 
    { 
        spouse = p;
            // We ignore sticky questions of reflexivity and
            // changing last names in this method for simplicity
    }
    
    public String introduction()
    {
        return &amp;quot;Hi, my name is &amp;quot; + firstName + &amp;quot; &amp;quot; + lastName +
            (spouse != null ? 
            &amp;quot; and this is my spouse, &amp;quot; + spouse.firstName + &amp;quot; &amp;quot; + spouse.lastName + &amp;quot;.&amp;quot; :
            &amp;quot;.&amp;quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Relatively verbose, and while I&apos;m certain people will stand up and argue that any modern IDE can code-generate some of this basic scaffolding for you, the fact is that the language itself requires this much degree of verbosity in order to express the concept. And this is a fairly basic concept; consider a much more complex domain object that has dozens of attributes associated with it. Code-generation and templates can mitigate some of the pain, but it can&apos;t remove it entirely, unfortunately.&lt;/p&gt;
&lt;p&gt;This isn&apos;t just a Java problem; the C# version of this type isn&apos;t much better:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    private string lastName;
    private string firstName;
    private Person spouse;
    
    public Person(string fn, string ln, Person s)
    {
        lastName = ln; firstName = fn; spouse = s;
    }
    public Person(string fn, string ln)
        : this(fn, ln, null)
    {
    }
    
    public string FirstName
    {
        get { return firstName; }
        set { firstName = value; }
    }
    
    public string LastName
    {
        get { return lastName; }
    }
    
    public Person Spouse
    {
        get { return spouse; }
        set { spouse = value; }
    }
    
    public string Introduction()
    {
        return &amp;quot;Hi, my name is &amp;quot; + firstName + &amp;quot; &amp;quot; + lastName +
            (spouse != null ? 
            &amp;quot; and this is my spouse, &amp;quot; + spouse.firstName + &amp;quot; &amp;quot; + spouse.lastName + &amp;quot;.&amp;quot; :
            &amp;quot;.&amp;quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and the Visual Basic version arguably gets even worse since VB prefers to use keywords to symbols:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Class Person
  Dim _FirstName As String
  Dim _LastName As String
  Dim _Spouse As Person

  Public Sub New(ByVal FirstName As String, ByVal LastName As String, ByVal Spouse As Person)
    Me._LastName = LastName
    Me._FirstName = FirstName
    Me._Spouse = Spouse
  End Sub

  Public Sub New(ByVal FirstName As String, ByVal LastName As String)
    Me.New(FirstName, LastName, Nothing)
  End Sub

  Public ReadOnly Property LastName() As String
    Get
      Return _LastName
    End Get
  End Property

  Public Property FirstName() As String
    Get
      Return _FirstName
    End Get
    Set (ByVal Value As String)
      Me._FirstName = Value
    End Set
  End Property

  Public Property Spouse() As String
    Get
      Return _Spouse
    End Get
    Set (ByVal Value As Person)
      Me._Spouse = Value
    End Set
  End Property

  Public Function Introduction As String
    Dim temp As String
    temp = &amp;quot;Hi, my name is &amp;quot; &amp;amp;amp; _FirstName &amp;amp;amp; &amp;quot; &amp;quot; &amp;amp;amp; _LastName
    If _Spouse &amp;amp;lt;&amp;amp;gt; Nothing Then
      temp = temp &amp;amp;amp; &amp;quot; and this is my spouse, &amp;quot; &amp;amp;amp; _Spouse.FirstName() &amp;amp;amp; &amp;quot; &amp;quot; &amp;amp;amp; _Spouse.LastName() &amp;amp;amp; &amp;quot;.&amp;quot;
    Else
      temp = temp &amp;amp;amp; &amp;quot;.&amp;quot;
    End If
    Return temp
  End Function
End Class
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A lot of what makes Ruby interesting to people is the fact that Ruby makes this a lot simpler (and I&apos;ll bet my Ruby here isn&apos;t the most terse it could be):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Person
  def initialize(firstname, lastname, spouse = null)
    @firstname = firstname
    @lastname = lastname
    @spouse = spouse
  end

  attr_reader :lastName
  attr_writer :firstName, :spouse
  
  def introduction
    if spouse == nil
      &amp;quot;Hello, my name is #{firstName} #{lastName}&amp;quot;
    else
      &amp;quot;Hello, my name is #{firstName} #{lastName} and this is my spouse, #{spouse.firstName} #{spouse.lastName}&amp;quot;
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Scala, similarly, simplifies the definition of the type. Take a look:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Person(ln : String, fn : String, s : Person)
{
    def lastName = ln;
    def firstName = fn;
    def spouse = s;
    
    def this(ln : String, fn : String) = { this(ln, fn, null); }

    def introduction() : String = 
        return &amp;quot;Hi, my name is &amp;quot; + firstName + &amp;quot; &amp;quot; + lastName +
            (if (spouse != null) &amp;quot; and this is my spouse, &amp;quot; + spouse.firstName + &amp;quot; &amp;quot; + spouse.lastName + &amp;quot;.&amp;quot; 
             else &amp;quot;.&amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There&apos;s a couple of things to notice here. First off, like Ruby, Scala defines the backing store for a field and simple accessor around those fields; note that since this is a functional language, Scala assumes immutable objects by default, so there are no mutators. (It turns out to be fairly trivial to write a mutator method to set the state of those attributes, but that starts to wander away from the intent of functional languages; this is clearly a difference between Scala and a more traditional O-O language like Java or C#.) You may be curious to know where the three-argument constructor went; as it turns out, it&apos;s considered the &amp;quot;primary constructor&amp;quot;, and is defined in the same line as the class declaration itself. The only reason we need the &amp;quot;this&amp;quot; method (another constructor) is because of the domain rule that says we can have a Person with no spouse.&lt;/p&gt;
&lt;p&gt;This is hardly an exhaustive comparison of the languages, but it does give you a little taste of Scala&apos;s object flavor. Ruby&apos;s syntax is arguably of the same length as Scala&apos;s (and frankly, to my mind, they&apos;re too close to call... or care), but clearly Scala&apos;s length is much much smaller than that of the equivalent C#, Java, Visual Basic or C++ class. (C++ could make things interesting with judicious use of templates to handle backing store, accessor and mutator, but that&apos;s considered too advanced by many C++ devs, and therefore too obscure to use in common practice, rightly or wrongly.)&lt;/p&gt;
&lt;p&gt;When next we look at this, we&apos;ll look at what Scala means when they say &amp;quot;everything&apos;s an object&amp;quot;... and how that, in many ways, this means that Scala is more object-oriented than Java itself.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Glenn Vanderburg pointed out that my Ruby wasn&apos;t quite correct, and also suggested a bit more &amp;quot;Rubification&amp;quot;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Person
  def initialize(firstname, lastname, spouse = null)
    @firstname, @lastname, @spouse = firstname, lastname, spouse
  end

  attr_reader :lastName
  attr_accessor :firstName, :spouse  # attr_writer *just* makes a writer.  You really want this.

  # I would typically use the more explicit &amp;quot;if&amp;quot; that you used here, but for terseness I&apos;ve
  # put this in the form you used with the Scala version:
  def introduction
    &amp;quot;Hello, my name is #{firstName} #{lastName}&amp;quot; + (spouse ? &amp;quot; and this is my spouse, #{spouse.firstName} #{spouse.lastName}&amp;quot; : &amp;quot;&amp;quot;)
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Thanks, Glenn. Again, I&apos;m struck by how Ruby&apos;s strength lies not in the core language itself, but the various &amp;quot;macros&amp;quot; that they&apos;ve defined (such as attr_reader and attr_accessor or attr_writer). This notion of &amp;quot;core language with user-defined extensions&amp;quot; is a powerful one, and I hope to show how Scala does much the same in its language definition.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Scala reactions</title>
      <link>http://blogs.newardassociates.com/blog/2006/scala-reactions.html</link>
      <pubDate>Thu, 2 Mar 2006 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2006/scala-reactions.html</guid>
      	<description>
	&lt;p&gt;Apparently, I touched a nerve; predictably, people started counting the keystrokes and missing my point.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;For example, Mark Blomsma wrote:&lt;/p&gt;
&lt;blockquote&gt;
Looks to me like you&apos;re comparing apples and pears. C# does not force you to use accessors. The following is already a lot closer to Scala.
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;public class Person
{
	public string firstName; public string lastName; public Person spouse;

	public Person(string fn, string ln, Person s)
	{
		firstName = fn; lastName = ln; spouse = s;&amp;lt;br&amp;gt;
	}

	public Person(string fn, string ln) : this(gn, ln, null) { }

	public string Introduction()
	{
		return &amp;quot;Hi, my name is &amp;quot; + firstName + &amp;quot; &amp;quot; + lastName + (spouse != null ?
			&amp;quot; and this is my spouse, &amp;quot; + spouse.firstName + &amp;quot; &amp;quot; + spouse.lastName + &amp;quot;.&amp;quot; : &amp;quot;.&amp;quot;);
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is only 356 keystrokes, compared to 287 for Scala. Now in Scala the default accessor for classes and members seems to be public, if this were not the case then you&apos;d need 323 keystrokes in Scala. Only a very minor difference. And definately not enough to make a case that Scala is more efficient for a developer.&lt;/p&gt;
&lt;p&gt;Another consideration if you start talking keystrokes is that the tooling suddenly becomes a factor. With C# and VS2005 I only type &apos;prop,tab,tab&apos; and then the type and name info. Skipping quite some keystrokes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Mark, with all due respect, I gotta admit to believing that you&apos;re doing the apples-to-pears comparison here, at least with your definition of the Person class in C#. The Scala implementation does NOT define a public field, but accessor methods, thus preserving encapsulation in the same way that the property methods do in C# and Java and C++. The thing is, Scala just realizes that 80% of those methods are always coded the same way, so it assumes a default implementation when it sees that syntax. (Ruby does the same thing.)&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;All that sort of misses the point, though: the purpose of the comparison was not to count keystrokes, per se, but to look at the &lt;i&gt;expressiveness&lt;/i&gt; of the language and how concisely the language can express a concept without requiring a great deal of scaffolding. C, for example, could always be used to build object-oriented systems... but you had a lot of work to do on your own to do it. As a result, a huge amount of complexity was spent in manaing the relationships between &amp;quot;classes&amp;quot; by hand (by tracking pointer relationships and so on). C++ solved a lot of that by baking those concepts in as a first-class concept, thus reducing the surface area requirment in the programmer&apos;s mind devoted to &amp;quot;plumbing&amp;quot;, and making room for more business-level complexity. Java did the same to C++ by introducing GC and other VM-level support, and so on. Scala and Ruby (and other hybrid and/or dynamic languages) are now seeking to do the same to Java and .NET.&lt;/p&gt;
&lt;p&gt;The question of tooling is an interesting one, though: is a language just the language by itself, or the language plus the tools that support it? Is Lisp still Lisp if you take Emacs out of the equation? Or is Smalltalk interesting without the Smalltalk environment and/or browser? Can we separate the two? Should we? That&apos;s a question to which I don&apos;t have an easy answer.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>2006 Tech Predictions</title>
      <link>http://blogs.newardassociates.com/blog/2006/2006-tech-predictions.html</link>
      <pubDate>Sun, 1 Jan 2006 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2006/2006-tech-predictions.html</guid>
      	<description>
	&lt;p&gt;Here we go: a set of new ones for the new year.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;I&apos;m suggesting the following will take place for 2006:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The hype surrounding Ajax will slowly fade, as people come to realize that there&apos;s really nothing new here, just that DHTML is cool again. As &lt;a href=&quot;http://www.almaer.com/blog/archives/001122.html&quot; target=&quot;_blank&quot;&gt;Dion points out&lt;/a&gt;, Ajax will become a toolbox that you use in web development without thinking that &amp;quot;I am doing Ajax&amp;quot;. Just as we don&apos;t think about &amp;quot;doing HTML&amp;quot; vs &amp;quot;doing DOM&amp;quot;.&lt;/li&gt;
&lt;li&gt;The release of EJB 3 may actually start people thinking about EJB again, but hopefully this time in a more pragmatic and less hype-driven fashion. (Yes, EJB does have its place in the world, folks--it&apos;s just a much smaller place than most of the EJB vendors and book authors wanted it to be.)&lt;/li&gt;
&lt;li&gt;Vista will be slipped to 2007, despite Microsoft&apos;s best efforts. In the meantime, however, WinFX (which is effectively .NET 3.0) will ship, and people will discover that Workflow (WWF) is by far the more interesting of the WPF/WCF/WWF triplet. Notice that I don&apos;t say &amp;quot;powerful&amp;quot; or &amp;quot;important&amp;quot;, but &amp;quot;interesting&amp;quot;.&lt;/li&gt;
&lt;li&gt;Scripting languages will hit their peak interest period in 2006; Ruby conversions will be at its apogee, and its likely that somewhere in the latter half of 2006 we&apos;ll hear about the first major Ruby project failure, most likely from a large consulting firm that tries to duplicate the success of Ruby&apos;s evangelists (Dave Thomas, David Geary, and the other Rubyists I know of from the NFJS tour) by throwing Ruby at a project without really understanding it. In other words, same story, different technology, same result. By 2007 the Ruby Backlash will have begun.&lt;/li&gt;
&lt;li&gt;Interest in building languages that somehow bridge the gap between static and dynamic languages will start to grow, most likely beginning with E4X, the variant of ECMAScript (Javascript to those of you unfamiliar with the standards) that integrates XML into the language.&lt;/li&gt;
&lt;li&gt;Java developers will start gaining interest in building rich Java apps again. (Freely admit, this is a long shot, but the work being done by the Swing researchers at Sun, not least of which is Romain Guy, will by the middle of 2006 probably be ready for prime-time consumption, and there&apos;s some seriously interesting sh*t in there.)&lt;/li&gt;
&lt;li&gt;Somebody at Microsoft starts seriously hammering on the CLR team to support continuations. Talk emerges about supporting it in the 4.0 (post-WinFX) release.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Effective Java&lt;/em&gt; (2nd Edition) will ship. (Hardly a difficult prediction to make--Josh said as much in the Javapolis interview I did with him and Neal Gafter.)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Effective .NET&lt;/em&gt; will ship.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Pragmatic XML Services&lt;/em&gt; will ship.&lt;/li&gt;
&lt;li&gt;JDK 6 will ship, and a good chunk of the Java community self-proclaimed experts and cognoscente will claim it sucks.&lt;/li&gt;
&lt;li&gt;Java developers will seriously begin to talk about what changes we want/need to Java for JDK 7 (&amp;quot;Dolphin&amp;quot;). Lots of ideas will be put forth. Hopefully most will be shot down. With any luck, Joshua Bloch and Neal Gafter will still be involved in the process, and will keep tight rein on the more... aggressive... ideas and turn them into useful things that won&apos;t break the spirit of the platform.&lt;/li&gt;
&lt;li&gt;My long-shot hope, rather than prediction, for 2006: Sun comes to realize that the Java platform isn&apos;t about the &lt;em&gt;language&lt;/em&gt;, but the &lt;em&gt;platform&lt;/em&gt;, and begin to give serious credence and hope behind a multi-linguistic JVM ecosystem.&lt;/li&gt;
&lt;li&gt;My long-shot dream: JBoss goes out of business, the JBoss source code goes back to being maintained by developers whose principal interest is in maintaining open-source projects rather than making money, and it all gets folded together with what the Geronimo folks are doing. In other words, the open-source community stops the infighting and starts pulling oars in the same direction at the same time. For once.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Flame away....&lt;/p&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Nullable Type correction/bugfix</title>
      <link>http://blogs.newardassociates.com/blog/2005/nullable-type-correctionbugfix.html</link>
      <pubDate>Tue, 8 Nov 2005 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2005/nullable-type-correctionbugfix.html</guid>
      	<description>
	&lt;p&gt;This is a bit of old news, but the discussion came up during the Seattle Code Camp, so I thought I&apos;d go through the problem, and use it as an example of the issues that can come up when trying to map language concepts on top of a platform that doesn&apos;t support the idea natively. Hopefully, this will cause developers looking to build DSLs or other languages on top of the .NET (or JVM) platform to see some of the edge cases a bit more clearly and a bit sooner. :-)&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;To lay down the background first: dealing with NULLs has always been somewhat problematic; the most obvious example of this is the mapping between relational databases, where even an INTEGER column can either have a value, or be empty, or be NULL, each of those being separate and distinct states. Trying to map NULL integer column values to integer values in the language has always been difficult in Java. C++, and C#, since primitive types / value types generally don&apos;t support null values, and Anders (among others) decided that it was time to try and integrate nullability more deeply into the language. The .NET team saw an opportunity to support nullability by creating a generic/templatized type to represent the possibility of nullability, and the C# language team took it further to try and make nullability feel &amp;quot;more at home&amp;quot; within the language. It was a bold, if at first seemingly-trivial, step.&lt;/p&gt;
&lt;p&gt;Initially, the Nullable&lt;T&gt; type was pretty simple: it captured an instance of T internally, and if T was null it tripped an internal flag such that the IsNull property would return true. So, using a nullable int would work something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Nullable&amp;lt;int&amp;gt; ni = new Nullable&amp;lt;int&amp;gt;(null);
if (ni.IsNull)
  Console.WriteLine(&amp;quot;It&apos;s null!&amp;quot;);
else
  Console.WriteLine(ni.Value);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By doing this, it seemed fairly straightforward, and then the C# team took it one step further and decided to integrate this more deeply into the language itself, by creating a native syntax for nullability:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int? ni = null;
if (ni == null)
  Console.WriteLine(&amp;quot;It&apos;s null!&amp;quot;);
else
  Console.WriteLine((int)ni);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In other words, any &lt;i&gt;type?&lt;/i&gt; designation was an alias for &lt;i&gt;Nullable&lt;type&gt;&lt;/i&gt;, and appropriate properties would be consulted when looking to evaluate the nullable type instance. Conversion rules (from the nullable type into the type) had to be written, because it&apos;s not necessarily a silent and unambigious conversion to it&apos;s original type; for example, in the case where you wrote:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int? ni = null;
int i = (int)ni;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;what should the expected behavior of the conversion of ni to i be? Some would argue that it should silently seek to &amp;quot;best&amp;quot; convert the null value of ni to an acceptable integer value of i, but that gets us back to the original problem, figuring out what that mapping is. (Ask any C++ programmer versed in the lore, and they&apos;ll be the first to tell you that &amp;quot;0 is NOT the same thing as NULL&amp;quot;.) So here, asking to make that conversion will trigger a NullReferenceException.&lt;/p&gt;
&lt;p&gt;OK, so far, so good. The problem is, however, that people were going to ask these nullable types to do things that subtly were different from what they&apos;d ask of Nullable&lt;T&gt; instances. For example, the following snippet of code wouldn&apos;t behave as expected:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int? ni = null;
object o = ni; // What should this conversion be?
if (o == null) {
  // Should we be in this block?
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What the conversion from int? to object should be was the subject of some debate, but what the C# team ended up with was the idea that the conversion followed basic CLR rules: that because int? was, internally, an &lt;i&gt;instance&lt;/i&gt; of the type Nullable&lt;int&gt;, the conversion was to obtain an object reference to the Nullable&lt;int&gt; instance. In other words, a &lt;i&gt;boxing&lt;/i&gt; operation took place, and since the Nullable&lt;int&gt; instance was always present (it&apos;s never null, even though it&apos;s &lt;i&gt;value&lt;/i&gt; might be null), the &amp;quot;if&amp;quot; block above would never evaluate as &amp;quot;true&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blogs.msdn.com/somasegar/archive/2005/08/11/450640.aspx&quot; target=&quot;_blank&quot;&gt;Somasegar&apos;s weblog&lt;/a&gt; describes what happened next in some detail:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Clearly this had to change. We had a solution in Visual Studio 2005 Beta2 that gave users static methods that could determine the correct null-ness for nullable types in these more or less untyped scenarios. However, these methods were costly to call and difficult to remember to use. The feedback you gave us was that you expected it to simply work right by default.&lt;br /&gt;
So we went back to the drawing board. After looking at several different workarounds and options, it became clear to all that no amount of tweaking of the languages or framework code was ever going to get this type to work as expected.&lt;br /&gt;
The only viable solution was one that needed the runtime to change.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In other words, the runtime had to take a special interest in the Nullable type, treating it with special-cased logic to handle those conversions between Nullable instances and their non-Nullable equivalents. As Soma points out, &amp;quot;A Nullable int now boxes to become not a boxed Nullable int but a boxed int (or a null reference as the null state may indicate).&amp;quot; More importantly, this permeates throughout the entire runtime, so that&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int? x = 10;
object y = x;
int? z = (int?)y; // unbox into a Nullable&amp;lt;int&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;works as intended, where under the old rules it would have failed conversion because the boxed Nullable reference wouldn&apos;t be the same type as the Nullable type it was being converted into. (In other words, boxed(Nullable(T)) != T.)&lt;/p&gt;
&lt;p&gt;The lessons here? When building languages to run on top of another platform or runtime, the decisions that runtime makes often put some serious constraints around what you can do within your language. For example, looking to support first-class functors on a JVM or CLR will run into the fact that functions &lt;i&gt;aren&apos;t&lt;/i&gt; first-class in the runtime, but instead have to be handled with object wrappers around the functions. Hiding those differences in language semantics can only get you so far, and that sometimes you need to involve the runtime team a bit more deeply if you want to close all those edge cases. (Hint to Sun: you really need to start thinking about revising and extending the JVM, instead of this current policy that essentially describes the JVM as perfect as-is. The changes made to support annotations were minor, but a good first step; it&apos;s time to open that Pandora&apos;s box wider if you want to keep up with the CLR, to be blunt about it.)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Anonymous generic methods making things &quot;just work&quot;</title>
      <link>http://blogs.newardassociates.com/blog/2005/anonymous-generic-methods-making-things-just-work.html</link>
      <pubDate>Tue, 8 Nov 2005 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2005/anonymous-generic-methods-making-things-just-work.html</guid>
      	<description>
	&lt;p&gt;A good friend of mine and I are looking at taking on a new project together, and as part of the discussion we were exploring some of the differences of taking a relational perspective against an object perspective, and one of the comments she made was that in a relational model, you can always &amp;quot;filter&amp;quot; the data you want based on some predicate. &amp;quot;Ha!&amp;quot;, I said, &amp;quot;If that&apos;s what you want, I can give you that over objects, too!&amp;quot;&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;What&apos;s more, thanks to generics, I can do this for any collection type in the system without having to introduce it on some kind of base class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;static class SetUtils
{
    public static List&amp;lt;T&amp;gt; Project&amp;lt;T&amp;gt;(List&amp;lt;T&amp;gt; list, Predicate&amp;lt;T&amp;gt; pred)
    {
        List&amp;lt;T&amp;gt; results = new List&amp;lt;T&amp;gt;();

        foreach (T p in list)
            if (pred(p))
                results.Add(p);

        return results;
    }

    // Not too hard to imagine the other relational operators here, too
}

// Usage:
class Person
{
    private string firstName;
    private string lastName;

    public Person(string fn, string ln, int age) {
        this.firstName = fn;
        this.lastName = ln;
    }

    public string FirstName {
        get { return firstName; }
        set { firstName = value; }
    }
    public string LastName {
        get { return lastName; }
        set { lastName = value; }
    }
    public override string ToString() {
        return &amp;quot;[Person [&amp;quot; + firstName + &amp;quot;]&amp;quot; + &amp;quot; &amp;quot; + &amp;quot;[&amp;quot; + lastName + &amp;quot;]&amp;quot; + &amp;quot;]&amp;quot;;
    }
}

class Program {
    static void Main(string[] args) {
        Person cg = new Person(&amp;quot;Cathi&amp;quot;, &amp;quot;Gero&amp;quot;, 35);
        Person tn = new Person(&amp;quot;Ted&amp;quot;, &amp;quot;Neward&amp;quot;, 35);
        Person sg = new Person(&amp;quot;Stephanie&amp;quot;, &amp;quot;Gero&amp;quot;, 12);
        Person mn = new Person(&amp;quot;Michael&amp;quot;, &amp;quot;Neward&amp;quot;, 12);

        List&amp;lt;Person&amp;gt; list = new List&amp;lt;Person&amp;gt;();
        list.Add(cg);
        list.Add(tn);
        list.Add(sg);
        list.Add(mn);

        List&amp;lt;Person&amp;gt; newards = 
            SetUtils.Project&amp;lt;Person&amp;gt;(list, 
                delegate (Person p) { if (p.LastName == &amp;quot;Neward&amp;quot;) return true; else return false; } );
        foreach (Person p in newards)
            Console.WriteLine(p);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Any more questions? (This is why having (1) a system that supports managed function pointers directly and (2) a generics system that doesn&apos;t rely on type erasure is so powerful. Hint, Hint, Sun guys....)&lt;/p&gt;
&lt;p&gt;Now if I could just figure out how C# 3.0 manages to differentiate/overload between delegate instances and Expression objects in LINQ/DLinq, I might be able to backport that to C# 2.0, too, and be able to pass these Predicate instances across the wire for execution on other machines.&lt;/p&gt;
&lt;p&gt;In a lot of ways, the Predicate delegate type is an example of using C#&apos;s anonymous methods as a form of closure or lambda expression. (It&apos;s been argued that anonymous methods-as-delegates aren&apos;t &amp;quot;true&amp;quot; closures, since the local variables referenced in a closure will only be references to the objects, not complete copies, but to my mind that&apos;s exactly as it should be, as any time you pass a reference to an object, you&apos;re passing just that--a reference to an object, not a complete copy of the object. To do otherwise in anonymous methods would violate the Principle of Least Surprise, IMHO.) The Ruby syntax arguably isn&apos;t any more elegant or terse, and I suspect similar things could be done in C++ using templates; probably something along these lines already exists in Boost. But alas, I see no way to do this in Java given the current state of the JVM, namely the aforementioned lack of &amp;quot;managed functors&amp;quot; and type-preserving generics. If any out there in Java-land know otherwise, please holler, because I would &lt;i&gt;really&lt;/i&gt; love to know how to do this as elegantly.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Concurrent Languages</title>
      <link>http://blogs.newardassociates.com/blog/2005/concurrent-languages.html</link>
      <pubDate>Fri, 28 Oct 2005 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2005/concurrent-languages.html</guid>
      	<description>
	&lt;p&gt;Ever since the Seattle Code Camp, where I hosted a discussion (hardly can call it a lecture--I didn&apos;t do most of the talking this time, as it turned out) on language innovations, one of the topics that came up was the notion of concurrency, and of course Herb Sutter&apos;s &amp;quot;No More Free Lunch&amp;quot; article from DDJ from some months ago.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;That put a bug in my ear: what sort of languages out there support concurrency in some form, baked into the language? I&apos;ve started to compile a list, but any other suggestions/references would be welcome; I&apos;d like to keep it to &amp;quot;active&amp;quot; languages (as opposed to languages no longer under active development), but if there&apos;s a particular concurrent language that had some kind of major influence on a branch of thinking, I&apos;d love to see it listed. And by &amp;quot;language&amp;quot; here I&apos;m willing to be flexible--extensions to preexisting languages (a la OpenMP) are interesting in their own right. But, I&apos;d like to keep it to &lt;em&gt;language&lt;/em&gt;-level constructs, not &lt;em&gt;library&lt;/em&gt;-level constructs--so C-with-POSIX, C++-with-BOOST or Java-with-java.util.concurrent aren&apos;t going to make the list, since they mostly support concurrency through the low-level mechanism of &amp;quot;start yer own thread&amp;quot;. I&apos;m interested in languages that do more than that. :-)&lt;/p&gt;
&lt;p&gt;So far, what I&apos;ve come up with includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;A href=&quot;http://research.microsoft.com/research/downloads/default.aspx&quot; target=_blank&gt;Cw (aka C-omega)&lt;/A&gt;: a combination of X#/Xen and Polyphonic C#, Cw provides an interesting concept called &amp;quot;chords&amp;quot; that suggests that methods of classes &amp;quot;work together&amp;quot; in pairs to handle concurrent access.&lt;/li&gt;
&lt;li&gt;&lt;A href=&quot;http://www.openmp.org&quot; target=_blank&gt;OpenMP&lt;/A&gt;: an extension to FORTRAN and C++, OpenMP uses #pragmas (in C++) to declare regions of code where an OpenMP compiler can spawn off threads and provide concurrent execution. What makes this interesting is its intersection to the mainstream: Visual Studio 2005 is an OpenMP compiler, and works for both unmanaged and C++/CLI code, meaning that this may be an interesting approach to handling concurrency inside of .NET apps. I know there&apos;s more out there--fire away! Regardless of whether they compile for .NET, JVM, or unmanaged code, I&apos;m interested in seeing what others have been exploring and/or playing around with. Academic links particularly wanted--they have a tendency to push the edge of the envelope (and some would say sanity) when it comes to areas like this.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;(&lt;strong&gt;UPDATE 2021:&lt;/strong&gt; Check out my &lt;a href=&quot;http://research.tedneward.com/tags/concurrent.html&quot;&gt;research garden&lt;/a&gt; for more concurrent languages)&lt;/em&gt;&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Dynamic languages, type systems, and self-modifying systems</title>
      <link>http://blogs.newardassociates.com/blog/2005/dynamic-languages-type-systems-and-self-modifying-systems.html</link>
      <pubDate>Tue, 18 Oct 2005 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2005/dynamic-languages-type-systems-and-self-modifying-systems.html</guid>
      	<description>
	&lt;p&gt;Stu Halloway &lt;a href=&quot;http://www.relevancellc.com/blogs/?p=69&quot;&gt;has responded&lt;/a&gt; to &lt;a href=&quot;http://blogs.tedneward.com/2005/10/05/More+On+The+Dynamic+Language+Wave+But+Leave+The+Poor+Vendors+Alone.aspx&quot;&gt;my earlier post&lt;/a&gt; about dynamic languages, and Stu refines his argument. Still wrong, but at least now it&apos;s refined. :-)&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Stu writes that we&apos;re &amp;quot;talking past one another&amp;quot;, and in particular notes that...&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The criticial point is that these abstractions are implemented in the language itself. Developers can (and do!) modify these core abstractions to work in different ways.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;... where &amp;quot;these abstractions&amp;quot; are referring to &amp;quot;inheritance, encapsulation, delegation&amp;quot;, etc, from my post.&lt;/p&gt;
&lt;p&gt;Where Stu, I think, is being fallacious with this is that he presumes a bit much with respect to at least a few of these languages; in particular Ruby has &lt;EM&gt;some&lt;/EM&gt; facility for self-modification and language evolution, but still relies on a core set of principles that are implemented in native code inside the Ruby interpreter. Ditto for Smalltalk, ditto for Python, and even for Lisp, the poster child for dynamic languages. (In all fairness, Stu does admit this--in a backhanded sort of way--when he notes that &amp;quot;The rules for adding new methods to existing classes aren’t (for the most part) in the core of ruby — they are implemented in Ruby source code.&amp;quot;)&lt;/p&gt;
&lt;p&gt;What Stu&apos;s point &lt;em&gt;does&lt;/em&gt; raise, however, is still the valid point that languages offer a continuum of self-modification and/or evolution, and that languages like Ruby, Smalltalk, Python or Lisp clearly come in on the &amp;quot;more&amp;quot; end of that continuum as opposed to languages like C# or Java or C++. And this plays into his later comment when he states, &amp;quot;It’s all about control. With a vendor-oriented language like C#, core abstractions are much more firmly controlled by the language vendor. Conversely, developer-oriented langauges like Python leave more of these choices to the developer (although they tend to provide reasonable defaults). So, again, who do you trust?&amp;quot;&lt;/p&gt;
&lt;p&gt;There&apos;s two points I want to raise here. One is technical, the other political/cultural.&lt;/p&gt;
&lt;p&gt;First, the technical: dynamic languages may choose to expose &lt;EM&gt;more&lt;/EM&gt; meta-control over the language, but there&apos;s nothing inherent in the dynamic language that requires it, nor is there anything in a static language that prevents it. Languages/tools like Shigeru Chiba&apos;s &lt;A href=&quot;http://www.csg.is.titech.ac.jp/~chiba/openc++.html&quot;&gt;OpenC++&lt;/A&gt; or &lt;A href=&quot;http://www.csg.is.titech.ac.jp/~chiba/javassist/&quot;&gt;Javassist&lt;/A&gt;, or &lt;A href=&quot;http://www.csg.is.titech.ac.jp/openjava/&quot;&gt;Michiaki Tatsubori&apos;s OpenJava&lt;/A&gt; clearly demonstrates that we can have a great deal of flexibility in how the language looks without losing the benefits of statically-typed environments. So to attribute this meta-linguistic capability exclusively to dynamic languages is a fallacy.&lt;/p&gt;
&lt;p&gt;Secondly is the cultural issue: is the idea of granting meta-linguistic power (known as meta-object protocol, or MOP) to a language a good thing? Stu asserts that it is: &amp;quot;My concern is who controls the abstractions. Developer-oriented languages (like Scheme) give a lot of control (and responsibility) to developers. Vendor-oriented languages (like Java) leave that control more firmly in the hands of the vendor.&amp;quot; So in whose hands are these abilities to change the language best placed?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;deep breath&lt;/em&gt; I don&apos;t trust developers. There, I&apos;ve said it.&lt;/p&gt;
&lt;p&gt;I say this not because I think developers are all 5-year-olds who need to be carefully watched and monitored and chastised gently when they actually run with scissors, but because in some cases, we don&apos;t necessarily know what we&apos;re doing when we start adopting certain features or ideas. Here&apos;s an example of what I mean: about eight years ago, when servlets were new and Reflection was still a Brand New Topic amongst developers, I read an article on building a servlet-based system that was touted as &amp;quot;dynamic&amp;quot; and &amp;quot;powerful&amp;quot;: in essence, the servlet would look for a query parameter in the request URL and Reflect for that method name on the servlet and/or alternate class, and execute it.&lt;/p&gt;
&lt;p&gt;This is a Good Thing?!? Incredibly dynamic, granted, but given the overhead and performance implications (not to mention security concerns), I can&apos;t see this as a great way to build scalable, dynamic systems.&lt;/p&gt;
&lt;p&gt;Gregor Kiczales, the inventor of AspectJ and long-time CLOS wonk--so you know he has experience on both sides of this fence--told me once that one of the greatest flaws of CLOS (I don&apos;t know if he used the word &amp;quot;flaw&amp;quot;, per se, but that was my takeaway) was that it allowed developers too much power. Developers writing CLOS systems apparently had this tendency to do too many wild-and-crazy things that ultimately (in his view) led to a number of write-only CLOS codebases. AspectJ was deliberately constrained to prevent these sorts of things, and whether or not he&apos;s succeeded in that remains to be seen--many long-time O-O advocates still see AspectJ as &amp;quot;an evil hacking language&amp;quot;, despite those constraints.&lt;/p&gt;
&lt;p&gt;I see the same concern every time a developer starts talking about doing bytecode manipulation at load-time--just because you &lt;em&gt;can&lt;/em&gt; doesn&apos;t mean you &lt;em&gt;should&lt;/em&gt;. In this respect, I trust the guys who&apos;ve been down this road before much more so than developers who are just coming to this and are starting to flex their new-found freedom and will (undoubtedly) start building systems that exercise this power.&lt;/p&gt;
&lt;p&gt;In the end, Stu&apos;s right, in that he and I share a lot of common ground--&lt;A href=&quot;http://www.develop.com&quot;&gt;working together&lt;/A&gt; for four years has a tendency to do that to you. And I won&apos;t even suggest that he&apos;s &amp;quot;wrong&amp;quot; so much as that he and I simply disagree on how much meta-control should be baked into a language, dynamic or otherwise.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Partners, old and new</title>
      <link>http://blogs.newardassociates.com/blog/2005/partners-old-and-new.html</link>
      <pubDate>Thu, 6 Oct 2005 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2005/partners-old-and-new.html</guid>
      	<description>
	&lt;p&gt;For many developers, it&apos;s been a while since they got together with their current programming environment. They&apos;ve hit the 7-year-itch mark with their current language/platform partner. They find themselves in a rut. Coding is mundane. Routine. Boring, even. It&apos;s the same old roll-over, perfunctory foreplay about which frameworks to use, same decisions and scripts every time, same results, same good-night kiss and back-to-sleep as the last project, and the project before that and the project before that and the project before that...&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Ruby is new. Exciting. It makes you feel alive again. You feel appreciated. You feel loved. Like the language was made &lt;em&gt;just for you&lt;/em&gt;. It caresses your desires, gives you new ideas, molds itself to what you want it to be. It makes your jaw drop and say, &amp;quot;I didn&apos;t know you could &lt;em&gt;do&lt;/em&gt; that!&amp;quot;. It leaps to your will, and does so much more than you thought a partner could do. You wonder what you ever &lt;em&gt;saw&lt;/em&gt; in that language you left behind.&lt;/p&gt;
&lt;p&gt;At least at first.&lt;/p&gt;
&lt;p&gt;Over time, though, the infatuation ends as most affairs do--in time, you discover a certain comfort in your language of choice. Sure, it&apos;s not perfect, but you know it well, you can get the job done, and what&apos;s more, everybody&apos;s content. Not ecstatically happy, sure, but &amp;quot;good enough&amp;quot;, and besides, it&apos;s &lt;em&gt;hard work&lt;/em&gt; trying to learn the nuances of a new partner. Nobody likes to admit it, but sometimes comfortable is better than exciting.&lt;/p&gt;
&lt;p&gt;You never forget those heady days, feeling the wind in your hair and reliving your younger days as a programmer. It reinvigorates you, reenergizes you, makes you feel &lt;em&gt;alive&lt;/em&gt;. It gives you something you didn&apos;t know you needed, but in the end, fires you up to go back to what you know best, brimming with fresh ideas and energy, ready to spice up your partnership so that you can remain happy for the next five, ten, even twenty years.&lt;/p&gt;
&lt;p&gt;Ruby is a love affair.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Book Review: Rootkits</title>
      <link>http://blogs.newardassociates.com/blog/2005/book-review-rootkits-by-hoglundbutler.html</link>
      <pubDate>Wed, 14 Sep 2005 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2005/book-review-rootkits-by-hoglundbutler.html</guid>
      	<description>
	&lt;p&gt;The title is a bit scary, but &amp;quot;Rootkits&amp;quot;, by Hoglund and Butler, really is anything but. Oh, I&apos;ll admit, their talk of how rootkits--programs that hackers install onto your system that patch into kernel space and thus are undetectable by any user-mode program--is scary, but then they walk you through the process of developing your own rootkit, thereby giving you some awareness of what a rootkit looks like, acts like, and therefore can be discovered and killed.&lt;/p&gt;
&lt;p&gt;Well, in theory, anyway.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;To put it bluntly, I&apos;m &lt;em&gt;loving&lt;/em&gt; this book, if only because it&apos;s the first book I&apos;ve run into that really sits down and explains how to write a device driver, not to mention how to communicate with it from user mode. I&apos;ve been fascinated with that very idea for many years now, but all the DDK-based material I&apos;ve found--books, articles, etc--all assumed that you wanted to write some variation on the SCSI driver or something, implying that you care more about device-level details than you do in writing kernel-mode code. Rootkits, of course, are nothing like real device drivers, but a lot more like what I&apos;m interested in exploring and displaying (that is, getting at program information from within the kernel--very useful for debugging scenarios, for example).&lt;/p&gt;
&lt;p&gt;By page 30, you&apos;ve already written and compiled a basic kernel driver, and by page 39 they&apos;ve discussed how you can have your driver expose itself as a special file handle for communication with user-mode code. Pages 40-43 talk about loading the driver from code, and 43-46, how to extract your driver from a user-mode program as a resource, suitable for loading (because, of course, rootkits need to piggyback on top of other code to install themselves, stealthy-like). Pages 46-47 talk about how to make your rootkit survive reboot, and that concludes Chapter Two.&lt;/p&gt;
&lt;p&gt;Wow. I&apos;m in love.&lt;/p&gt;
&lt;p&gt;It&apos;s not the be-all-end-all book on drivers, nor is it going to necessarily turn you into a l33t hax0r, but if you ever wanted to get started understanding how rootkits work (so as to start looking for them on your own system in order to remove them) or just use that knowledge for more benign purposes (such as trying to figure out NT internals so you can more efficiently--and automatedly--debug services or server-style programs), this book rocks. Easily a classic, and one I&apos;m probably going to carry around with me as much as I do Hoglund&apos;s other book (with Gary McGraw, one of my favorite security authors), &amp;quot;Exploiting Software&amp;quot;.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Adopting Rails... or Ruby... or anything else</title>
      <link>http://blogs.newardassociates.com/blog/2005/adopting-rails-or-ruby-or-anything-else-for-that-matter.html</link>
      <pubDate>Thu, 25 Aug 2005 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2005/adopting-rails-or-ruby-or-anything-else-for-that-matter.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://codesnipers.com/&quot;&gt;Duane Gran&lt;/a&gt; emailed me with his thoughts on adopting Ruby-and-Rails into his shop, only his thoughts on the matter are a bit different from the usual rant; he&apos;s looking at it from the management perspective, and has some good ideas on when and why to adopt... or not to adopt... &lt;a href=&quot;http://codesnipers.com/?q=node/30&quot;&gt;a new programming language&lt;/a&gt;.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Specifically, he spells out:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The decision to change programming languages, databases and operating systems shouldn&apos;t be taken lightly, but when the issue comes up the approach should be analytic. Be wary of resume-driven development initiatives, architectural advice from vendors, marketing hype and buzzword compliance. That your development team is more productive with the new technology is all that matters. ... I suggest changing architectures only when the following factors align:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The technology is proven in your development environment&lt;/li&gt;
&lt;li&gt;The installed user base is small for your application&lt;/li&gt;
&lt;li&gt;You are still in a development or prototype stage that won&apos;t endanger a production system&lt;/li&gt;
&lt;li&gt;Your developers want to learn the technology for the right reasons and they have a firm grasp of the code base&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Follow this model and you will avoid untold frustrations that lie in wait. Transitioning to Ruby on Rails worked fantastically for our group and it may well do so for yours as well, but proceed analytically and demonstrate value from the transition before making a full leap.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I like that list. I could probably add to it, with concerns whether the technology will be somehow integratable/interoperable from your legacy platforms, but I think that these issues are probably the first hurdle to pass--and, frankly, I think will be the hardest hurdle to pass, particularly given his caution against &amp;quot;resume-driven development initiatives&amp;quot;. (I like that phrasology, Duane--don&apos;t be too surprised if you hear it on an $NFJS panel sometime. :-)&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>There is no such thing as &quot;Best Practices&quot;: Context Matters</title>
      <link>http://blogs.newardassociates.com/blog/2005/there-is-no-such-thing-as-best-practices-context-matters.html</link>
      <pubDate>Thu, 25 Aug 2005 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2005/there-is-no-such-thing-as-best-practices-context-matters.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://blackbox.cs.fit.edu/blog/james&quot;&gt;James Bach&lt;/a&gt; recently &lt;a href=&quot;http://blackbox.cs.fit.edu/blog/james/archives/000187.html&quot;&gt;blogged about something I&apos;ve been saying&lt;/a&gt; in conversations with friends and conference attendees: &lt;em&gt;there ain&apos;t no such thing as a &amp;quot;best practice&amp;quot;&lt;/em&gt;.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;He lays out his points in a letter to his blog readers, and I want to comment on a few of them.&lt;/p&gt;
&lt;p&gt;First, &amp;quot;There are no best practices. By this I mean there is no practice that is better than all other possible practices, regardless of the context. In other words, no matter what the practice and how valuable it may be in one context, I can destroy it by altering things about the situation surrounding the practice.&amp;quot; James hits the nail on the head with this one: any practice, taken out of context, can easily be turned from &amp;quot;best practice&amp;quot; to a &amp;quot;worst practice&amp;quot; without too much difficulty. The patterns guys had it down: A Pattern, or let&apos;s call it practice, so that we can talk more about concrete things, is a Solution to a Problem within a given Context that yields certain Consequences. You cannot avoid this basic relationship. (The patterns guys then wanted to take practices, examine them across domains, and find the commonality and elevate it so that we could apply them in a domain-independent manner; hence the reasoning behind the Rule of Three, which so many pattern &amp;quot;writers&amp;quot; seem to miss.) It makes sense, even on an intuitive level: I walk into a doctor&apos;s office, and say, &amp;quot;I have a cough&amp;quot;. What&apos;s the Best Practice here? Meds? Diet and exercise? Immediate surgery? It clearly depends on the context--other symptoms, the pervasiveness of the cough, the reasons behind the cough, and so on. Doctors who fail to establish the Context before offering a Solution are often called Quacks... or sued for malpractice.&lt;/p&gt;
&lt;p&gt;He goes on to say, &amp;quot;Although some things that don&apos;t exist can be useful as rhetorical signposts, &amp;quot;best practice&amp;quot; is not one of them. There is nothing honorable you get from pretending that a practice is best that you can&apos;t also get from suggesting that a practice may be good in a specified context, and making a case for that. Sure, there are dishonorable things you can get from &amp;quot;best practice&amp;quot; rhetoric-- say, causing a dull-witted client to give you money. If that has tempted you in the past, I urge you to reform.&amp;quot; Unfortunately, the temptation is too strong, particularly for those who are pushing a new platform upon the world. Java got tremendous success from pushing patterns rather than canned solutions (and I think we pushed too many patterns, not enough practices, to be honest), and so now it seems a requirement for any new platform that in addition to the platform, you need to have an established set of practices with it to help guide the newbies to the platform. After all, how comforting does it sound when somebody seeking to sell you on a new platform, when asked &amp;quot;So how do I use this thing best?&amp;quot; turns to you and says, &amp;quot;We really don&apos;t know yet since there&apos;s not a critical mass of people using it yet&amp;quot;?&lt;/p&gt;
&lt;p&gt;&amp;quot;It has a chilling effect on our progress as an intellectual craft when people pretend that a best practice exists. Best practice blather becomes a substitute for the more difficult, less glamorous, but ultimately more powerful idea of learning how to do your job. By &amp;quot;learning&amp;quot; I mean practicing the skills of identifying and solving patterns of problems we encounter as testers. Of course, that will involve patterns of behavior that we call &amp;quot;practices&amp;quot;. I&apos;m not against the idea of practices, I&apos;m against pretense. Only through pretense can a practice that is interesting in a particular context becomes a &amp;quot;best practice&amp;quot; to which we all must bow down.&amp;quot; Again, I&apos;m fond of the patterns terminology here, because it clearly highlights the problem he&apos;s stating here: if we think we have a &amp;quot;Best Practice&amp;quot; to a particular problem, in other words, making it a two-part tuple, it becomes a deceptively simple list: we only need state all the Problems, and the Solutions will be apparent, since when would you choose not to use a &amp;quot;Best Practice&amp;quot;? When you list it out as a four-part tuple: Problem, Context, Solution and Consequences, it becomes more clear that a particular Problem doesn&apos;t have one &amp;quot;Best Practice&amp;quot;, but depends entirely on Context and desired Consequences.&lt;/p&gt;
&lt;p&gt;I would challenge anyone to name a &amp;quot;best practice&amp;quot; for which there is no situation which makes the &amp;quot;best practice&amp;quot; a &amp;quot;worst practice&amp;quot;. To use James&apos; example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;A doctor who prescribes a drug without examining the patient is committing malpractice. Isn&apos;t that obvious? Would you respect such a doctor? Why should we respect people who prescribe practices without regard for the problems faced in a project? The answer comes back, &amp;quot;What if the doctor tells you to eat right and exercise?&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Easy--if the patient is in imminent danger of a heart attack, eating right and exercise is not going to prevent the heart attack; worse yet, the exercise could even &lt;em&gt;trigger&lt;/em&gt; the attack. Such a doctor could easily be hoisted up on malpractice charges. My father suffered a massive coronary a few years back, and the doctor warned him very clearly that strenuous exercise was out until he&apos;d recovered to a sufficient degree that his heart could take the strain. He&apos;s fine now--by that I mean no side effects, aside from 90-something percent scarring across his heart--but has to very carefully monitor his lifestyle. Which brings up a good point, as well: if you ignore the Context when discussing the Problem, how can you tell when the Context has changed (as they frequently do over time)?&lt;/p&gt;
&lt;p&gt;People often cite EJB as a terrible technology. Bullsh*t. People who do that are missing the point. (Even &lt;a href=&quot;http://www.springframework.org&quot;&gt;Rod Johnson&lt;/a&gt; agrees with this point, or at least he did in a private conversation at The ServerSide Symposium in 2004.) The problem with EJB was that it was highly oversold: another case of &amp;quot;best practices&amp;quot; gone awry--most projects don&apos;t need EJB, despite the advice from EJB vendors. (Hmm....) EJB offers a much simpler programming model when dealing with two-phase commit programming against transactional resource managers, particularly given the context of seeking something industry-standard (for fears of new programmers having to burn all kinds of ramp-up time when they&apos;re hired). That&apos;s not really the problem space that Spring seeks to solve. (Leaving the reader to perhaps realize that maybe there&apos;s a place for both Spring and EJB in the world?)&lt;/p&gt;
&lt;p&gt;Why the frenzy to use the term, if it has so many things wrong with it? Easy: &amp;quot;Best Practices&amp;quot; are easy to sell. Who wouldn&apos;t want to hire somebody who practices only &amp;quot;Best Practices&amp;quot;? Who would want to hire somebody who doesn&apos;t? It&apos;s an easy term for managers and HR practitioners to latch onto, and this is why most of the time you see unsophisticated speakers and tech leaders climbing all over themselves to use the term. Come on, admit it, which title sounds better and more &amp;quot;bang for your buck&amp;quot; at a conference? &amp;quot;J2EE Best Practices&amp;quot; or &amp;quot;Patterns of J2EE&amp;quot;? Most developers will pick the first, every time. And, worse yet, not realize they&apos;re being sold a bill of goods.&lt;/p&gt;
&lt;p&gt;If you find yourself tempted to use the term, stop and examine your rationale for doing so. Are you really asking somebody what the best way to use something is, without regard to context? Or are you implicitly seeking to push your own agenda? As a speaker, I routinely get questions like, &amp;quot;Is it a best practice to ... ?&amp;quot; that are followed up by, &amp;quot;But what about when ....?&amp;quot;, in essence seeking to know if I change my advice when the Context is different than what they think I&apos;m thinking about. And usually, yes, it does. :-)&lt;/p&gt;
&lt;p&gt;Challenge to the reader: the next time you see somebody use the term, &amp;quot;Best Practice&amp;quot;, ask yourself (or them) if you can come up with a situation (a Context) where it would be a &amp;quot;Worst Practice&amp;quot; instead. If you can&apos;t, or if they can&apos;t, it&apos;s probably indicative that you--or they--don&apos;t quite &amp;quot;get it&amp;quot; yet. Or, more likely, that they&apos;ve just never seen a situation where it wouldn&apos;t be applicable... which then makes me question exactly how much this particular practice has been used. Think it&apos;s a silly exercise? Almost all of the great technology books in our industry have either explicitly or implicitly brought this point to the forefront of the book, even to the point where the contradict themselves sometimes. Still not convinced? Then how about this: after you can begin to see the separation between Problem, Solution, Context, and Consequences, &lt;a href=&quot;http://www.amatecon.com/fish.html&quot;&gt;you may be able to stop listening to &amp;quot;experts&amp;quot; and start making up your own mind.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Context matters.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Book Review: Pragmatic Project Automation</title>
      <link>http://blogs.newardassociates.com/blog/2005/book-review-pragmatic-project-automation.html</link>
      <pubDate>Mon, 22 Aug 2005 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2005/book-review-pragmatic-project-automation.html</guid>
      	<description>
	&lt;p&gt;A bit late, but I realized after I posted the Recommended Reading List that I forgot to add Mike Clark&apos;s &lt;em&gt;Pragmatic Project Automation&lt;/em&gt;, a great resource for ideas on how to automate various parts of your build cycle... and, more importantly, why this is such a necessary step. Although nominally a Java book, there&apos;s really nothing in here that couldn&apos;t also be adopted to a .NET environment, particularly now that NAnt and MSBuild are prevalent in .NET development shops all over the planet.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Most importantly, Mike indirectly points out a great lesson when he uses Groovy to script Ant builds: that you don&apos;t have to stick with just the tools that are given to you. Automation can take place in a variety of ways, and scripting languages (like Groovy, or Ruby, or Python...) are a great way to drive lower-level tools like Ant. &lt;a href=&quot;http://www.relevancellc.com/blogs&quot; target=&quot;_blank&quot;&gt;Stu Halloway&lt;/a&gt; has begun talking about the same concept when he discusses &amp;quot;Unit Testing with Jython&amp;quot; at the NFJS shows. Coming from the .NET space? Then think about IronPython, or even the JScript implementation that comes out of the box with Visual Studio.&lt;/p&gt;
&lt;p&gt;All in all, a highly-recommended read.&lt;/p&gt;

	</description>
    </item>
    <item>
      <title>Recommended Reading List</title>
      <link>http://blogs.newardassociates.com/blog/2005/recommended-reading-list.html</link>
      <pubDate>Sun, 21 Aug 2005 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">blog/2005/recommended-reading-list.html</guid>
      	<description>
	&lt;p&gt;I&apos;ve been asked on several occasions (from students, from blog readers, and from a few friends who happen to be in the business) what my recommended reading list is. I&apos;ve never really put one together formally, instead just sort of relying on impromptu answers that cover some of my absolute favorites and a few that just leap to mind at the time.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;&lt;em&gt;(Note that this is a reprint, so to speak, of &lt;A href=&quot;http://www.neward.net/ted/weblog/index.jsp?date=20030205#1044497180661&quot;&gt;the same entry&lt;/A&gt; on the old weblog, but I wanted to kick the Reading category off with a reprise of what I&apos;d written before.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(&lt;strong&gt;UPDATE 2021&lt;/strong&gt;: I&apos;m updating this as time goes by. Come back here periodically for new titles and updates.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Enough is enough. It&apos;s time for me to post my recommended reading list, broken out for both Java and .NET programmers. (If you&apos;re of one camp, it&apos;s still worth reading books on the other camp&apos;s list, since the two environments really are Evil Twin Brothers.) And I&apos;ve left my own books off the list, because I think it&apos;s rather forward of me to recommend them as recommended reading--naturally, I think they&apos;re all good, but whether or not they make the cut of &amp;quot;recommended reading&amp;quot; is for others to weigh in on, not me (at least not here). (&lt;strong&gt;Update&lt;/strong&gt;: several commenters on the old blog suggested it was not out of line to recommend my own books if I thought they were worth recommending, so I added them.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Java Recommended Reading list&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Effective Java&lt;/em&gt; by Bloch.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Java Puzzlers&lt;/em&gt; by Bloch and Gafter. You think you know the Java language? Try it. (Makes for great interview question fodder, and for that reason alone practicing Java programmers should have a copy on their shelf.)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Effective Enterprise Java&lt;/em&gt; by Neward. (Had to do it. :-) )&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Concurrent Programming in Java (2nd Ed)&lt;/em&gt; by Lea.&lt;/li&gt;
&lt;li&gt;Either &lt;em&gt;Inside Java2 Platform Security&lt;/em&gt; by Gong or &lt;em&gt;Java Security (2nd Ed)&lt;/em&gt; by Oaks.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Component Development for the Java Platform&lt;/em&gt; by Halloway.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Inside the Java2 Virtual Machine&lt;/em&gt; by Venners.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Java Development with Ant&lt;/em&gt; by Hatcher and Loughran.&lt;/li&gt;
&lt;li&gt;Either &lt;em&gt;Java RMI&lt;/em&gt; by Grosso or &lt;em&gt;java.rmi&lt;/em&gt; by McNiff and Pitt.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Server-Based Java Programming&lt;/em&gt; by Neward. For obvious reasons. :-) Actually, I still think this book is applicable if you want to understand the reasons why an app server makes some of the restrictions that it does, but I freely admit that I don&apos;t think I did a great job of &amp;quot;closing the loop&amp;quot; on that and finishing the book with a good summary that ties everything together. Ah, retrospect....&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Servlets and Java Server Pages&lt;/em&gt; by Jones and Falkner, possibly &lt;em&gt;Java Servlet Programming (2nd Ed)&lt;/em&gt; by Hunter, if you aren&apos;t planning to use JSP. (Jason&apos;s legendary bias against JSP, right or wrong, puts him somewhat out of tune with what a majority of Java web-client shops are doing. That said, it&apos;s a great servlets resource.)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;AspectJ in Action&lt;/em&gt; by Laddad. AspectJ represents the best of the AOP solutions, IMHO, and this book represents the best of the AspectJ books available.&lt;/LI&gt;&lt;/UL&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;.NET Recommended Reading list&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;C# In a Nutshell (2nd Ed)&lt;/em&gt; by Drayton, Albahari, and Neward. For obvious reasons. :-)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Advanced .NET Remoting&lt;/em&gt; by Rammer.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Essential ADO.NET&lt;/em&gt; by Beauchemin.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Inside Microsoft .NET IL Assembler&lt;/em&gt; by Lidin.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;SSCLI Essentials&lt;/em&gt; by Stutz, Neward and Shilling. For obvious reasons. :-)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Debugging Applications&lt;/em&gt; by Robbins.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Inside Windows 2000&lt;/em&gt; by Russinovich and Solomon.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Essential COM&lt;/em&gt; by Box. &lt;em&gt;(Yes, I mean Essential COM and not his more recent Essential .NET book. The first chapter of Essential COM is probably the best well-written technical prose I&apos;ve ever read in my life, and everybody who ever wanted to write reusable components in C++ needs to read it to understand why C++ failed so miserably at that goal. Once you&apos;ve seen that, you&apos;re ready to understand why components are so powerful and so necessary.)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Essential ASP.NET&lt;/em&gt; by Onion.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Expert C# Business Objects&lt;/em&gt; or &lt;em&gt;Expert VB Business Objects&lt;/em&gt;, by Lhotka. Not an intro to business objects, per se, but a great read on how to build a framework. Pay close attention to how Rocky handles distribution; he avoids the canonical problems of &amp;quot;distributed objects&amp;quot; by not distributing objects, but instead making them &lt;em&gt;mobile objects&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;The Common Language Infrastructure Annotated Standard&lt;/em&gt; by Miller&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Programming in the .NET Environment&lt;/em&gt; by Watkins et al.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;C++ Recommended Reading list&lt;/strong&gt;:&lt;br /&gt;
&lt;em&gt;(For the twelve people left in the world still writing C++ code, anyway.)&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;The C++ Programming Language (3rd Ed)&lt;/em&gt; by Stroustrup.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Effective C++ (1st, 2nd &lt;em&gt;or&lt;/em&gt; 3rd Ed)&lt;/em&gt; by Meyers.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;More Effective C++&lt;/em&gt; by Meyers.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Effective STL&lt;/em&gt; by Meyers.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Inside the C++ Object Model&lt;/em&gt; by Lippmann. You don&apos;t know how C++ works until you&apos;ve read this cover to cover. Twice. And peeked at everything under the hood with a debugger, just to make sure Stan&apos;s right. Seriously.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Database/Relational Storage Recommended Reading list:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Introduction to Database Systems&lt;/em&gt; &lt;em&gt;(8th Ed)&lt;/em&gt; by Date. Heavy on theory, and for that reason alone should be read at least once by any practicing programmer who thinks they understand SQL and the relational world.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;SQL for Smarties (3rd Ed)&lt;/em&gt; by Celko. Actually, you need to own just about everything by Celko.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Principles of Transaction Processing&lt;/em&gt; by Bernstein and Newcomer.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Transaction Processing: Concepts and Techniques&lt;/em&gt; by Gray and Reuter. What to read when you&apos;re done with the Bernstein and Newcomer book and still want to know more about the Zen of Transactional Processing.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Security-related Recommended Reading list&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Rootkits&lt;/em&gt; by McGraw.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Secrets and Lies&lt;/em&gt; by Schneier.&lt;/li&gt;
&lt;li&gt;Either &lt;em&gt;Cryptography Decrypted&lt;/em&gt; by (can&apos;t remember the name offhand), &lt;em&gt;Practical Cryptography&lt;/em&gt; by Schneier and Ferguson, or &lt;em&gt;Applied Cryptography (2nd Ed)&lt;/em&gt; by Schneier. The first is a lightweight introduction to the subject, the second is a more detailed introspection, the third required reading for anybody who wants to be a security wonk.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;The Code Book&lt;/em&gt; by Singh.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Hacking Exposed (5th Ed)&lt;/em&gt;, by McClure, et al.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Exploting Software&lt;/em&gt;, by Hogland and McGraw. The most fun book in the list, if you ask me.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Reversing&lt;/em&gt; by Eilam. Who says unmanaged code is &amp;quot;safe from reverse-engineering&amp;quot;?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;The Art of Deception&lt;/em&gt;, by Mitnick.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Operating System/Platform Reading list&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Windows Internals&lt;/em&gt; (4th Ed) by Russinovich and Solomon. Actually, any of the last three editions (2nd, 3rd, 4th) is awesome, so look for 3rd Ed in a bargain bin and pick up a great bargain.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Operating Systems&lt;/em&gt; (2nd Ed) by Tanenbaum. The original &amp;quot;Minix&amp;quot; book. Taught me the basics of how an O/S works, and the basic concepts are still applicable to this day.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Platform-agnostic Recommended Reading list&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Design and Evolution of C++&lt;/em&gt; by Stroustrup. It&apos;s fascinating hearing how a language develops over time, and what was behind some of the decisions in the features of the language. For example, why did multiple inheritance come before templates or RTTI? Not because it was more important, but because Stroustrup wanted to tackle MI first because he wasn&apos;t sure if or how he could do it. He describes that as a great regret, that he didn&apos;t do templates first.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Component Software (2nd Ed)&lt;/em&gt; by Szyperski.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Rapid Development&lt;/em&gt; by McConnell. Read this before you read any of the Extreme Programming books, because this book describes a whole taxonomy of what I think a lot of people are reaching for in agile and other methodologies.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;The Inmates Are Running the Asylum&lt;/em&gt; by Cooper.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;The Invisible Computer&lt;/em&gt; by Norman.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Refactoring&lt;/em&gt; by Fowler.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Design Patterns&lt;/em&gt; by Gamma, Helm, Johnson and Vlissides.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Pattern Oriented Software Architecture, Vol 1&lt;/em&gt; by Stal et al.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Pattern Oriented Software Architecture, Vol 2&lt;/em&gt; by Schmidt et al.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Patterns of Enterprise Application Architecture&lt;/em&gt; by Fowler.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Enterprise Integration Patterns&lt;/em&gt; by Hohpe and Woolf. Excellent discussion of message-based architecture. I personally think the title is something of a misnomer, but it&apos;s understandable since message-oriented communication is the easiest means by which to integrate heterogeneous systems.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that this list will undergo revision and change as I continue, so I&apos;m putting a link to this item in the links column in the sidepanel to the left for easy reference. For now, I&apos;m just listing them out as they come to mind. Later, if I have time, I&apos;ll put paragraphs of detail behind them so you can know why I recommend them. (Updated on 13 Feb 2002) (Moved to this weblog 21 Aug 2005) (Updated 5 Oct 2005)&lt;/p&gt;
&lt;p&gt;Look for more book reviews and recommended reading via the &amp;quot;Reading&amp;quot; category on the RSS feeds. There&apos;s undoubtedly titles that I&apos;m forgetting, and I&apos;m hoping I&apos;ll get around to blogging more about the books I&apos;m reading now, including Ruby (the Pickaxe book and the Rails book), some other titles in the Pragmatic series, as well as some WS-*-related stuff and (of course) the staple C# and Java stuff. And of course I&apos;m always open to suggestions of new and interesting technical titles to peruse....&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Update: &lt;A href=&quot;http://www.stevenrockarts.com/blog/PermaLink,guid,e054ed79-8291-4e83-adf1-cfc1fb1f72dc.aspx&quot;&gt;Steven Rockarts&lt;/A&gt; pointed out that Rocky&apos;s &amp;quot;Objects&amp;quot; books are missing, as is Fritz&apos;s Essential ASP.NET. Added. (He also lists Object Thinking, by West, but I don&apos;t care for that book--too Zen, I think, for most readers.)&lt;/p&gt;

	</description>
    </item>

  </channel> 
</rss>
