Category Archives: software

How to write a tech book, or how I stopped worrying and learned to love writing

I just sent in the last chapter of Learning Spring Boot 2nd Edition’s 1st draft. And my brain has collapsed. I’ve been working for several months on this 10-chapter book that embraces Spring Boot 2.0 and reactive programming. There are several books out there on reactive programming, but I believe this will be the first to hit the market about Project Reactor.

I’m not done, not by a long shot. I told my publisher that we’d need at least one big round to make updates to ALL the code, because I started writing when not everything was in place. And it’s still true. But editing, polishing, and updating an existing repository of code and manuscript is easier than creating one out of thin air.

I wanted to write just a little bit about how I approaching writing something like this. Maybe you have been thinking about writing a book yourself, and your curious what goes on. This isn’t the only, but it’s the way that works for me.

Tools

Laptop on a work table with DIY and construction tools all around top view hobby and crafts concept

To write a book, you need a mechanism to capture prose and code. For fiction, I use Scrivener, but when it comes to technical writing, where the code, screenshots, and text are tightly integrated, I use Asciidoctor. With Asciidoctor, the overhead of a word processor is removed, and instead I can focus on pure content.

Also, using Asciidoctor lets me pull in the code to generate the manuscript sent in to my publisher. This way, I have Sublime Text in one window viewing the source prose and IntelliJ open in another viewing the source code. To top it off, I have a Ruby guardfile configure to constantly regenerate an HTML proof of the chapter I’m writing with it refreshing via LiveReload in my browser.

This combination gives me a quick feedback loop as I write.

What to write

This may be the biggest hurdle to some. When you’ve picked the technology, setup your tools, and finally have the editor opened up, what do you type in that black, blank screen?

Waiting for magical words to arrive? Or perhaps you hope elves will scurry in and leave something? Nope. This is where the rubber hits the proverbial road and you have to push yourself to start typing.

What do I do? I actually start earlier than that. From time to time, I have a crazy idea about something I want to show to an audience at a conference. Some demo I want to give with a few pieces of the Spring portfolio. I began to noodle out code to make that happen. Once, I asked “can I snap a picture of the audience and upload it from my phone to a webpage the audience is watching on the overhead?” Thus was born my Spring-a-Gram demo.

That demo has morphed many times to the point that I have built a full blown, cloud native, microservice-based system. And guess what. It’s the system we get to explore in Learning Spring Boot 2nd Edition.

So when I sit down to write a chapter, I first start writing the code I want to walk through. Once it’s humming inside my IDE, I start to typeset it in Asciidoctor. And pages of code fragments, I began to tell a story.

Weaving a story

When writing technical articles, getting started guides, and books, everything is still a story. Even if this isn’t a novel, it’s still a story. People that grant you the honor of reading your work want to be entertained. When it comes to tech work, they want the ooh’s and ahh’s. They want to walk away saying, “That was cool. I could use that right now.”

At least, that’s how I read things. So my goal when I write is to make it fun for me. If it’s fun for me, I trust it will be fun for others.

If I sift through a chapter, and it’s just a boring dump of code, then it’s sad. And that’s not what I want. I can’t promise that all my writing has upheld this lofty goal. But it’s my goal nonetheless.

So oftentimes, I will typeset the code, hand some descriptive details around the code, then read it again, top to bottom, and add extra stuff. Paragraphs talking about why we’re doing this. Mentioning tradeoffs. Issues that maybe exist today and where we have to make a choice. Ultimately, understand not just what the code does but why it does it this way. And what other options are out there.

Letting go

At some point, after all the writing and polishing and fine tuning, you have to turn in your work. I don’t know if there is ever a time where I’m 100% satisfied. I’m kind of picky. But the truth is – you’ll never find every typo, every bug.

My code fidelity is much higher ever since I started using Asciidoctor. But stuff happens. And you have to be happy turning in your work.

You see, if you’ve acquired enough skill to sit down a write a book without someone leaning over your shoulder and coaching you, you might have a lot of good value other developers seek. Eager coders will be able to read what you wrote, look past small mistakes, and most importantly, grok the points you make. That’s what is key.

And one thing is for certain – writing makes you better. I have found that any gaps in my own understanding of certain parts of code lead me to chase down and grasp those bits. And then I want to share them with others. Which is what writing books is all about.

Happy writing!

Layering in new behavior with React

I’ve talked in the past how I like the approach React leads me to when it comes to building apps. How does such grandiose talk play out when it’s time to add a new, unexpected feature? Let’s check it out. I’ve been building an installation app for Spinnaker, and one of our top notch developer advocates gave it a spin.

Results? Not good. Too many presumptions were built into the UI meaning he had no clue where to go. Message to me? Fix the flow so it’s obvious what must be done and what’s optional.

So I started coding in a feature to flag certain fields REQUIRED and not allow the user to reach the installation screen without filling them out. Sounds easy enough in concept. But how do you do that?

With React, what we’re describing is an enhancement to the state model. Essentially, keep filling out fields, but earmark certain fields as required, and adjust the layout of things to show that, while barring other aspects of the interface in the event those same fields aren’t populated.

So I started with a little bit of code to gather a list of these so-called required fields, and it looked like this:

If you have done any React programming, assigning something via this.state[…] = foo should set off bells in your head. You always, always, ALWAYS used this.setState(…). So what’s up?

Rules are rules until they aren’t. This is a situation that defies the concept. I don’t WANT to set the state such that it triggers a ripple through the DOM. Instead, this code happens right after the initial state model is initialized. And I’m setting it using values populated in the previous line, because you can’t initialize required, pointing at this.state.api in the same call the initializes this.state.api itself!

With this list of required fields setup, we can start marking up the fields on the UI to alert the user. I have a handful of React components that encapsulate different HTML inputs. One of them is dedicate to plain old text inputs. Using the newly minted required list, I can adjust the rendering like this:

Notice the little clause where it checks this.props.settings.requires.includes(this.props.name)? That is a JavaScript ternary operation that if true, returns the label with extra, highlighted text. Otherwise, just render the same label as always.

By applying this same tactic to the other React components I have for rendering each selection on the UI, I don’t have to go to each component and slap on some new property. Instead, the designation for what’s required and what’s not it kept up top in the state model, making it easier to maintain and reason about.

At the top of the screen is a tab the user clicks on to actually install things and track their progress. To ensure no one clicks on that until all required fields are populated, I updated that tab like this:

A little function that detects whether or not all required fields have been filled out is checked, and if so, renders the HTML LI with its onClick property filled out with the handler. If NOT, then it renders the same component, but NO SUCH onClick property is present, meaning it just won’t respond.

This is the nature of React. Instead of dynamically adjusting the DOM model, you declare variant layouts based on the state of the model. This keeps pushing you to put all such changes up into the model, and writing ancillary functions to check the state. In this case, let’s peek at requiredFieldsFilledOut:

This tiny function checks this.state.required, counts how many are “truthy”, and if the count matches the size of this.state.required itself, we’re good to go.

In case you didn’t know it, React encourages you to keep moving state-based functions up, closer to the state model itself. It’s super simple to pass along a handle to the function to lower level components, so they can still be invoked at lower levels. But anytime one component is trying to invoke another one in a separate part of the hierarchy, that’s a React-smell hinting that the functions should be higher up, where they can meet. And that results can trickle down to lower level components.

I encountered such a function stuffed down below in a lower level component. The need to trigger it sooner based on a change in the state had me move it up there. Now, when the Installation tab is clicked, that function is run, instead of waiting for the user to click some button down below.

Suffice it to say, I rehabbed the UI quite nicely. The thing is, with React it’s not hard to effect such change in a couple days, compared to the days or weeks of effort combined with testing it might have taken with classic manipulated-the-DOM apps, where you have to hunt down gobs of wired event handlers and find every little nuanced operation you coded to make things operate correctly.

Check out my @SpringData and @SpinnakerIO talks from SpringOne Platform @S1P

Recently, my latest conference presentations have been released. You are free to check them out:

In the Introduction to Spring Data talk, I live code a project from scratch, using start.spring.io, Spring Data, and other handle Spring tools.

In the Spinnaker: Land of a 1000 Builds talk, I present the CI/CD (continuous integration/continuous delivery) multi-cloud tool Spinnaker:

Enjoy!

Tuning Reactor Flows

I previously wrote a post about Reactively talking to Cloud Foundry with Groovy. In this post, I want to discuss something of keen interest: tuning reactor flows.

When you use Project Reactor to build an application, is the style a bit new? Just trying to keep your head above water? Perhaps you haven’t even thought about performance. Well at some point you will. Because something big will happen. Like a 20,000 req/hour rate limit getting dropped on your head.

Yup. My development system mysteriously stopped working two weeks ago. I spotted some message about “rate limit exceeded” and rang up one of my friends in the Ops department to discover my app was making 43,000 req/hour. Yikes!

As I poured over the code (big thanks to the Ops team giving me a spreadsheet showing the biggest-to-smallest calls), I started to spot patterns that seemed like things I had seen before.

Reactor tuning a lot like SQL tuning

Long long ago, I learned SQL. As the saying goes, SQL isn’t rocket science. But understanding what is REALLY happening is the difference between a query taking twenty minutes vs. sub-second time to run.

So let’s back up and refresh things. In SQL, when you join two tables, it produces a cartesian product. Essentially, a table with n rows + a table with m rows, will produce a table with n x m rows, combining every possible pair. From there, you slim it down based on either relationships or based on filtering the data. What DBMS engines have had decades is learning is how to read your query and figure out the BEST order to do all these operations. For example, many queries will apply filtering BEFORE building the cartesian product.

In Reactor, when you generate a flux of data and then flatmap it to another flux, you’re doing the same thing. My reactor flow, meant to cache up a list of apps for Spinnaker, would scan a list of eighty existing apps and then perform a domain lookup…eighty times! Funny thing is, they were looking up the same domain EIGHTY TIMES! (SQL engines have caching…Reactor doesn’t…yet).

So ringing up my most experienced Reactor geek, he told me that it’s more performant to simply fetch all the domains in one call, first, and THEN do the flatmap against this in memory data structure.

Indexing vs. full table scans

When I learned how to do EXPLAIN PLANs in SQL, I was ecstatic. That tool showed me exactly what was happening in what order. And I would be SHOCKED at how many of my queries performed full table scans. FYI: they’re expensive. Sometimes it’s the right thing to do, but often it isn’t. Usually, searching every book in the library is NOT as effective as looking in the card catalog.

So I yanked the code that did a flatmap way at the end of my flow. Instead, I looked up ALL domains in a CF space up front and passed along this little nugget of data hop-to-hop. Then when it came time to deploy this knowledge, I just flatmapped against this collection of in memory of data. Gone were all those individual calls to find each domain.

.then(apps ->
	apps.stream()
		.findFirst()
		.map(function((org, app, environments) -> Mono.when(
			Mono.just(apps),
			CloudFoundryJavaClientUtils.getAllDomains(client, org))))
		.orElse(Mono.when(Mono.just(apps), Mono.empty())))

This code block, done right after fetching application details, pauses to getAllDomains(). Since it should only be done once, we only need one instance from our passed along data structure. The collection is gathered, wrapped up in a nice Mono, and passed along with the original apps. Optionally, if there are no domains, an empty is passed along.

(NOTE: Pay it no mind that after all this tweaking, the Ops guy pointed out that routes were ALREADY included in the original application details call, hence eliminating the need for this. The lesson on fetching a whole collection up front can be useful.)

To filter or not to filter, that is the question

Filtering is an art form. Simply put, a filter is a function to reduce rows. Being a part of both Java 8’s Stream API as well as Reactor’s Flux API, it’s pretty well known.

The thing is to watch out for if the filter operation is expensive and if it’s inside a tight loop.

Loop? Reactor flows don’t use loops, right? Actually, that’s what flatmaps really are. When you flatmap something, you are embedding a loop to go over every incoming entry and possibly generating a totally different collection. If this internal operation inside the flapmap involves a filter that makes an expensive call, you might be repeating that call too many times.

I used to gather application details and THEN apply a filter to find out whether or not this was a Spinnaker application vs. someone else’s non-Spinnaker app in the same space. Turns out, finding all those details was expensive. So I moved the filter inward so that it would be applied BEFORE looking up the expensive details.

Look at the following code from getApplications(client, space, apps):

return requestApplications(cloudFoundryClient, apps, spaceId)
	.filter(applicationResource ->
		applicationResource.getEntity().getEnvironmentJsons() != null &&
		applicationResource.getEntity().getEnvironmentJsons().containsKey(CloudFoundryConstants.getLOAD_BALANCERS())
	)
	.map(resource -> Tuples.of(cloudFoundryClient, resource))
	.switchIfEmpty(t -> ExceptionUtils.illegalArgument("Applications %s do not exist", apps));

The code above is right AFTER fetching application information, but BEFORE going to related tables to find things such as usage, statistics, etc. That way, we only go for the ones we need.

Sometimes it’s better to fetch all the data, fetch all the potential filter criteria, and merge the two together. It requires a little more handling to gather this together, but again this is what we must do to tailor such flows.

Individual vs. collective fetching

Something I discovered was that several of the Cloud Foundry APIs have an “IN” clause. This means you can feed it a collection of values to look up. Up until that point, I was flatmapping my way into these queries, meaning that for each application name in my flux, it was making a separate REST call for one.

Peeking at the lower level APIs, I spotted where I could give it a list of application ids vs. a single one. To do that, I had to write my flow. Again. By putting together a collection of ids, by NOT flatmapping against them (which would unpack them), but instead using collectList, I was able to fetch the next hop of data in one REST call (not eight), shown below:

return PaginationUtils
	.requestClientV2Resources(page -> client.spaces()
		.listApplications(ListSpaceApplicationsRequest.builder()
			.names(applications)
			.spaceId(spaceId)
			.page(page)
			.build()))
	.map(OperationUtils.<ApplicationResource, AbstractApplicationResource>cast());

cf-java-client has an handy utility to wrap paged result sets, iterating and gathering the results…reactively. Wrapped inside is the gold: client.spaces().listApplications(). There is a higher level API, the operations API, but it’s focus is replicating the CF CLI experience. The CF CLI isn’t built to do bulk operations, but instead operate on one application at a time.

While nice, it doesn’t scale. At some point, it can a be a jump to move to the lower level APIs, but the payoff is HUGE. Anyhoo, by altering this invocation to pass in a list of application names, and following all the mods up the stack, I was able to collapse eighty calls into one. (Well, two, since the page size is fifty).

You reap what you sow

By spending about two weeks working on this, I was able to replace a polling cycle that perform over seven hundred REST calls with less than fifty. That’s basically a 95% reduction in network traffic, and nicely put my app in the safe zone for the newly imposed rate limit.

I remember the Ops guy peeking at the new state of things and commenting, “I’m having a hard time spotting a polling cycle” to which the lead for Cloud Foundry Java Client replied, “sounds like a good thing.”

Yes it was. A VERY good thing.

Reactively talking to Cloud Foundry with Groovy

I’ve been working on this Spinnaker thing for over a year. I’ve coded support so Spinnaker can make continuous deployments to Cloud Foundry. And the whole thing is written in Groovy. I recently upgraded to that I can now talk reactively to Cloud Foundry with Groovy.

And it’s been a nightmare.

Why?

Groovy is pretty darn wicked. Coding Spring Boot apps mixed with Spring MVC controllers in the terse language of Groovy is nothing short of gnarly. But it turns out there’s a couple things where Groovy actually gets in your way.

Reactor + Cloud Foundry

Want a taste? The code fragment below shows part of a flow used to look up Spinnaker-deployed apps in Cloud Foundry:

operations.applications()
  .list()
  .flatMap({ ApplicationSummary appSummary ->
    operations.applications()
      .getEnvironments(GetApplicationEnvironmentsRequest.builder()
        .name(appSummary.name)
        .build())
      .and(Mono.just(appSummary))
  })
  .log('mapAppToEnv')
  .filter(predicate({ ApplicationEnvironments environments, ApplicationSummary application ->
    environments?.userProvided?.containsKey(CloudFoundryConstants.LOAD_BALANCERS) ?: false
  } as Predicate2))
  .log('filterForLoadBalancers')
  .flatMap(function({ ApplicationEnvironments environments, ApplicationSummary application ->
    operations.applications()
      .get(GetApplicationRequest.builder()
        .name(application.name)
        .build())
      .and(Mono.just(environments))
  } as Function2))

This is the new and vastly improved Cloud Foundry Java SDK built on top of Project Reactor’s async, non-blocking constructs (Mono and Flux with their operations). Every function call is an async, non-blocking operation fed to the next function call when the results arrive.

What does this code do? It looks up a list of Cloud Foundry apps. Iterating over the list, it weeds anything that doesn’t have a LOAD_BALANCER environment variable, a tell for Spinnaker-deployed apps. Finally it looks up the detailed record for each application.

The heart of the issue

What’s nestled inside several of these “hops” in this flow is a tuple structure. In functional flows like where each hop gets a single return, we often need to pass along more than one piece of data to the next hop. It’s the side effect of not using the imperative style of building up a set of variables, but instead passing along the bits in each subsequent funtion call.

cf-java-client has TupleUtils, a collection of functions meant to pack and unpack data, hop to hop. It’s elegant and nicely overloaded to support up to eight items passed between hops.

And that’s where Groovy falls flat. Groovy has this nice feature where it can coerce objects. However, with all the overloading, Groovy gets lost and can’t tell which TupleUtils function to target.

So we must help it by coercing it into the right structure. See those “as Function2”  and “as Predicate2” calls? That helps Groovy figure out the type of lambda expression to slide things into.

And it’s dragging me down!

The solution

So I finally threw in the towel and converted this one class into pure Java.

Yes, I ditched hip and cool Groovy in favor of the old warhorse Java.

You see, when something is so dependent on every character being in the right place, we need all the static support from the IDE we can get. Never fear; I’m not dropping Groovy everywhere. Just this one class.

And here is where Groovy’s interoperability with Java shines. Change the suffix of one file. Make the changes I need. And both the IDE and the compiler is happy, giving me an operational chunk of code.

I had to rewrite a handful of collections, but it wasn’t the worse thing in the world. In half a day, I had successfully moved the code. And now as I’m working on another flow, the pain of Groovy’s need for coercion specification is no longer wreaking havoc.

Cheers!

 

Have you crossed the midpoint in your career?

There is something that has snuck up on me. When I stopped to think about it, it became clear. There is a point in your career when you cross this “midpoint.” I remember Day One of my first job as a professional software engineer.

I had already written little scripts, apps, and other hobby projects. But this was the day I was building stuff for my livelihood. The day when I had to start steadfastly listening to others, and doing what I was told. Sounds scary, right? Well, not really. I guess I was too gung ho. And the people that hired me did a great job at hand holding. Nevertheless, what I know today and what I knew back then are starkly different.

What is the midpoint? I like to think of every person out there writing code on a spectrum. People on their first day start at the bottom. Then slowly, but surely your knowledge and experience causes you to rise. On your Day Two, there is someone else having their Day One. At a certain point, you cross the halfway mark, or the “midpoint.” Congratulations, you arguably know more than half of the other people in the your field.

This isn’t an article about arrogance, or how I’m better than you. No. This is recognizing that the things you learned in college have benefit, but we all gain new talents and experience every day. And your responsibilities change.

On Day One, your responsibility may be to test someone else’s code. (That was mine!) But at a certain point, perhaps after you’ve crossed the midpoint, your responsibility may be to help others. To teach, lead, form communities. Or to take the reins of a project where there is zero management and guidance. Those that are on Day One aren’t equipped to do that.

An honest recognition of where you “are” can make you realize that signing up to speak at a conference, hosting a JUG group, leading an open source project, or offering to run a project with little more than a single sentence for a high ranking manager in your company.

It’s also a keen time to visit places like Stack Overflow and answer questions. And remember to extend grace to those that are new and seeking to grow themselves. Some people call this giving back. I’ve never been a fan of this expression. I prefer to think of it as sharing what you have learned with others.

The magic of software development

People think I have a magical talent. It’s funny seeing the difference between what I know and what others think I know when it comes to debugging stuff.

Simply put, I know how to tinker. I have clues, hunches, and insights. But that stuff is useless to a developer not willing to roll up their sleeves and engage in ten solid hours of trial and error. Often times, that is what makes or breaks a demo or a customer feature.

clock-with-a-questionDid I mention ten hours? Sorry, I meant ten days! Or sometimes it takes ten weeks to push your way through a mountain of integration, setup, and labor. Whatever it takes. But it isn’t solved by “knowing the answer” when you sit down at the keyboard.

We software devs work in the strangest field. First, we pursue a degree in either Computer Science or Computer Engineering. Ever seen a scientist and an engineer talk? Polar opposites. So what is software development? A science or an engineering trade?

My buddy Russ Miles has likened this to R&D, since there is no real sense of “can you have that ready in a month?” Building a bridge between two fixed endpoints is much easier to estimate than “can we have this website operational by next year?”

Experiment: Find your most non-technical friend, and ask them if they have a clue what you do. Then try to clarify when they say “no.” And try, and try, and try.

Solving software problems can seem foreign to both science AND engineering. On many days, it’s just tinker, tinker, tinker. And yet, our world’s dependency on it is growing.

HamletSoftware is really just organizing a set of patterns to respond to information. We need certain behaviors triggered automatically, and software is a giant stack of rules meant to handle that. As we collect more information and link more things together, the need to manage this grows.

A good visual of what software really entails is a hologram. Remember that limited-response hologram from I, Robot? We are just tinkering to put together a set of rules to better manage everything around us.

This requires tinkering, not magic. Good ole elbow grease is sometimes the best tool.

The value of backwards compatibility

springI was listening to Episode 6 of the Nash Dev Cast as they spoke about bitrot, of how stuff degrades as the whole Internet upgrades around you. It really reminded me of the inestimable value of Spring’s approach to backwards compatibility.

Something that is almost unnoticeable is that the Spring Framework and its entire portfolio has backwards compatibility. Bumping up the version in your project when a new release comes out is a no-brainer. They just don’t break stuff. You may get alerted to deprecated features, but the JavaDocs will kindly direct you along the upgrade path. Moving from Spring 1.2.8 -> 2.5 -> 3.0 -> 4.0 has such little cost, that people are eager to jump to the latest.

junior-devAs a junior developer, this kind of thing doesn’t really resonate. And not because you are somehow bad. No. It’s simply because you don’t have as many war stories to share over upgrading other libraries, and having major breakage. Senior developers at conferences will share a beer and discuss some crazy upgrade that got started, and a breaking change they were forced into turned a 2-day upgrade into a 3-week effort.

Even as a senior developer who recognized this feature of the Spring portfolio, it wasn’t until I joined the team and proposed changes, that I learned of the technical challenges this team faces to enforce backwards compatibility. It really rose to the surface when I heard Juergen speak about Spring 4 being “Java 8 ready” but still working with Java 6. With scrunched eyebrows, I leaned closer as he spoke during the 2013 Birds of a Feather at SpringOne how the framework would certainly support Java 8 features, but still operate on Java 6.

That perplexed me. How could a framework take advantage of things like Optional yet blink “no problem” if you used Java 6? Digging in, I learned not only how to build a JAR file with Java 6 specs but neatly keep Java 8-based API calls inside Java 8-flagged classes that were only loaded when Java 8 was the loading engine. And I learned how hard this effort was.

I already respected the Spring team and the programming model they had developed. But this level of technical expertise combined with forward thinking plans to start ten years ago and maintain to this day, was quite impressive.

So, listening to podcasts about JavaScript open source modules, sifting through and evaluating products, and getting “left-padded” at times, made me snug and comfortable in my decision to bring onboard the Spring Framework years ago. Their decisions to invest so highly in the community have paid dividends I have no idea how to tabulate.

In defense of leftpad

Given the time I’ve had to think about the whole leftpad controversy, I have to come to the conclusion that leftpad was PERFECTLY FINE with its decision to build a module with only eleven lines. (As to the brooha over unpublishing and then being forcibly republished by npm, that is a different topic.)

leftpad wrote code anyone with half a brain should be able to write

laptop_chimpThat must be the biggest sentiment I’ve heard. Blogs, podcasts, and other forums have thrown out this strong criticism of leftpad’s code. It’s best summarized as “have people forgotten how to code?”

Gee, leftpad getting unpublished broke React.js, Babel.js, and how many other systems? If those impressive projects saw value in leftpad, sounds pretty big of me to judge them all for making such a foolish decision. After all, that’s what I’m doing, right? I’m ascribing judgment for using it.

Let me be clear: I haven’t actually READ leftpad’s code. I’m not defending the physical lines of code in that module. The market spoke and accepted leftpad. I am defending the choice others made because I myself haven’t invested the time to make a better choice.

leftpad wasn’t REALLY used by React.js, etc. It was just a transitive dependency

2001This one doesn’t sit right. It’s kind of like saying, “React.js is good. The people writing it would never need something like leftpad. They just got caught by some intermediate dependency.” Can you smell the disdain?

If leftpad was used by an intermedia dependency, and that is what all the big weights used, then the transitive property applies. Not only has the market said leftpad met needs, but the intermediate dependencies are just as valuable. See what I did there? Transitive dependency, transitive value.

leftpad isn’t actually the best way to do what it did

Kaypro_in_Israel_1984Here is where it gets interesting. This is what I hear from those that have spotted the transitive link. Can’t criticize React.js, because they didn’t REALLY use leftpad. Let’s look elsewhere.

People have been singing the UNIX tune of “do one thing and do it well” as microservices arise. Defenders of leftpad point it out as a composable function, adhering to the UNIX philosophy. But if you can tear out “do it well”, then leftpad doesn’t qualify for this concept. Hence, leftpad was a badly written composable function.

Sorry, maties, but as software engineers, we seek out solutions on a daily basis. And in the land of open source, we constantly make “build or buy” decisions. Whenever someone asked me, “what is an engineer”, my answer has always been, “we find a good enough solution for the problem at hand.” We don’t seek perfect answers, because we don’t have an infinite budget.

For a LOT of people, leftpad was good enough. They could have written a better solution, but they could also have written a better solution for LOTS of other modules. Imagine the cost of perfecting every single thing you use. Or how about this: imagine the cost of tens of thousands of developers writing an equivalent to leftpad. Perhaps 15 minutes tops, but multiplied by 10,000 and your talking 2500 hours of effort. Doesn’t that defy the concept of open source?

What’s next?

imageI know people that don’t like certain tools out there. They have written their own version of things. At first glance, there’s underscore and lodash. These two libraries essentially do the same thing. But one project was not satisfied with the other project. Hence, they built a fork and whole community around it.

These are people I respect, because they took the time to evaluate the current state of affairs and write their own solution. When I go pick from one of these two solutions, I can find out the basis of one or the others. Has the bulk of the JavaScript community picked one of the other? Or is it a big split? These are factors in choosing.

I can spend all my time building everything from scratch and live under the haughty label “I know how to program. I’ll build it myself.” But we already have a term for developers like that: “Not Invented Here“. Some people will only touch code they themselves wrote.

If you actually spent the time to read leftpad’s code, then used it or decided otherwise, that’s fine. But don’t go around criticizing others for using leftpad. After all, you’re criticizing the choices of MANY others.

Good developers take breaks

Boring PresentationSomething that has become crystal clear since I joined the Spring team is how important it is to take a break. Good code happens when developers take breaks.

Of course there are times when I find myself working solid until 8:00 pm or later. But I try to make that the exception rather than the norm. Most of the time, I’m pulled away by my kids coming home from school. In fact, I’m often annoyed at stopping a minute early.

STTNG_pinballAnd yet I’m astonished at how many perplexing problems I’ve solved by simply stopping, doing something else, and **BAM**, the answer pops into my head. Sometimes within minutes, sometimes the next morning while putting shoes on one of my kids. Those are the moments when I remind myself that developers take breaks. I consider that payoff for having stopped early.

This phenomena is well know. In fact, you’ve probably heard of it. I also so it addressed keenly at a writer’s conference last year. Your subconscious is still working on the problem whether you are or not. Sometimes, when you aren’t actively trying to fix it, your noodle is freed up to look back at what you did, what you’ve read, and other things.

devnexusWhile chatting with a teammate of mine at DevNexus, he expressed that if he hadn’t taken various breaks, gone for walks and thought about the architecture he was designing, the project he was striving to build would never have happened.

HamletReflection is a critical component. My martial instructor often taught “visualize, visualize, visualize.” It’s a mechanism to put your mind on the subject, even when you’re not actively pursuing it.

The key thing is telling yourself to take that break. To pause. To stop and not burn the candle at both ends. If you work that hard, your subconscious will be on the ropes. Those extra ideas that can often succeed when you may have failed all day, may not come at all. It’s a big leap I know, but give it a try.