James Simone is a lead software engineer here at Salesforce. James works under the helm of the agile organization, where his team helps build tools for all of the engineering teams to measure their productivity and happiness. James’ team is making it possible to move fast without breaking anything at Salesforce.

In this episode, we talk about many philosophical concepts of software engineering. This includes agile and pure programming, mob programming, recursion and refactoring, and more. We also go into creating a future-proofed framework and even bring in the movie Midnight in Paris.

Listen in to learn how to move fast without breaking things in software engineering.

Show Highlights:

  • The tools involved in tracking agile
  • What James finds interesting about the Ruby ecosystem
  • Timing and efficiency versus safety
  • Where YAGNI comes into play
  • What makes for a good unit test

Links:

Episode Transcript

James Simone:
What are the abstractions that I can introduce that introduce syntax sugar with the minimum amount of cognitive overhead?

Josh Birk:
That’s James Simone, a lead software engineer here at Salesforce. I’m Josh Birk, your host with the Salesforce Developer Podcast. Here on the podcast, you’ll hear stories and insights from developers for developers.
Today, we sit down and talk with James about a wide variety of philosophical concepts of software engineering. We’re going to talk about how we can try to move fast but not break things. We’re going to get into things like Agile and peer programming and mob programming and recursion and refactoring and all sorts of fun stuff. But before we do, let’s level set and ask James what his job exactly is here at Salesforce.

James Simone:
My current job at Salesforce is under the helm of our Agile organization. My team helps build tools for all of the engineering teams in Salesforce to measure their productivity and happiness.

Josh Birk:
Nice. I like that you’re measuring both productivity and happiness. What kind of tools are you using to track happiness?

James Simone:
Happiness is obviously a proxy, so there are things that we do, like surveying engineers on a weekly or biweekly basis. It’s opt-in, so they can choose to take the survey, for example. As frequently or as infrequently as they’d like.

Josh Birk:
Got it.

James Simone:
But then, there are also some other interesting proxy measurements that we’ve introduced. Not all of which, of course, we can get into, but they are interesting. I think that it’s also fun to think about how those two things can be, and data shows, are related to each other.

Josh Birk:
Exactly. I have a feeling we’re probably going to get back into some of that kind of stuff. But first, I want to give a shout out to The Changelog Podcast, because that’s an episode which brought us this conversation. There are long formats, so we’re just going to talk to some highlights. What about this episode talking about the Ruby ecosystem caught your eye?

James Simone:
Well, I think it’s an interesting one. Because the story … I guess we’ll link it out in the show notes. The podcast that happened recently with Justin Searls, who’s a big member of the Ruby community. The Ruby community as a whole is about twice as large as our own. I find that interesting. Primarily, because I think it speaks to how large we as a group of developers are. The Ruby ecosystem is massive and it stands to reason that half of massive is still pretty big.

Josh Birk:
Right.

James Simone:
We’re at a size where you can’t just go off and dismiss us as a couple of people working on a niche proprietary language anymore. There’s a lot of people globally using Apex, using Lightning Web Components. I think that’s really important. The thing that’s interesting hearing from somebody in the Ruby mindset is them talking about the language having more of an appreciation in different parts of the world. A burgeoning global interest, while sort of a more passive Western reaction to Ruby. Right?

Josh Birk:
Right.

James Simone:
Like it’s old hat or something. That’s totally fine. But at the same time, I think it’s important for us to continue to be excited about the work that we are doing, and especially realize that so much of modern software and the automations that multinational corporations to your small nonprofits are running on are these rock solid foundations that languages like Ruby and Apex, JavaScript provide to people.

Josh Birk:
Well, and I thought there was an interesting undertone. Because they were talking about the stability and growth of the Ruby ecosystem, even though you don’t read about it in the news every other day like you do with JavaScript. I feel like there’s a huge parallel to that.
Like you’re saying, we still have a pretty massive ecosystem, but it’s not like Apex hits Hacker News an awful lot. But I think there’s another corollary. Because I kind of got one of the beats from them was like, “This is because Ruby just works.” There’s nothing really controversial to talk about. It doesn’t make many headlines because it just works. I feel like you could say that about our platform as well.

James Simone:
Absolutely. I think you’re not going to see, “Apex introduces switch statement into syntax support,” on Hacker News back in 2018. You’re not going to see the same thing today, “Apex introduces query with bind support. Now, you can access your query variables in a much easier and sustainable format.” That’s just not the kind of thing that is going to get massive amounts of up votes. But these are actually really exciting improvements on the existing language.

Josh Birk:
I think it’s wonderful that Apex has gotten to a level of maturity that it can get nerdier. We’re not even really necessarily fixing old stuff. We’re just actually improving it on a base level kind of thing. Because once again, the guts of all of it, they just work.

James Simone:
Absolutely, and there’s a lot to be said for that.

Josh Birk:
And so, to segue into that. There’s a saying in tech, “Go fast and break things.” Usually, saying that even if you fail, that’s not a bad thing, because you can learn from your failings and move on to the next iteration.
I have had product managers come on the show and say that Salesforce’s philosophy is more of, “Go fast, but don’t break anything.” Because we not want to break anything in our current version that we spent all that hard work putting out in the last version. What do you think of those phrases? What do you think about the, “Focus on time and efficiency,” versus safety?

James Simone:
My friends and I have this joke, “Got to go fast,” as though it’s a license to operate recklessly and to break things.

Josh Birk:
Right.

James Simone:
I think that when we look at the influence that Agile methodologies have had on software development and software development life cycles in general, there is this idea of duality that’s been introduced. Safety versus speed. We’ve been sold this idea that you can either have one or the other.
I think that, to your point, something that we’ve really tried to shore up in our own release cycles, that we’ve consistently tried to do with introducing new functionality without breaking existing functionality, is this idea that … Actually, maybe this is more of the tortoise versus the hare. Slow and steady is the thing that wins the race.
And that’s the thing that I have specialized in and focused in over the last seven years embedded in various software development teams, watching as our internal velocity grows and grows. It does so by doing things that are, again, not going to hit the front page of Hacker News. It’s like, “Software team chooses to focus on technical debt. Manages to hit all of their goals.” I wish that that was the thing that was trending, but it’s just not that exciting to talk about. “Yes. We went back and fixed a to-do that we wrote five months ago.”

Josh Birk:
It does cut back to the classic … We’re like train engineers. Nobody complains as long as the train keeps coming and showing up on time. It’s when the train breaks down on the tracks. That’s when it actually makes the headlines.

James Simone:
That I think is one of those things where, when you think about what the statistic of a 99% uptime really means, it is funny to break it down and be like, “Well, actually this looks like three days a year we’re going to have a problem.” Of course, the thing that you’re going to notice is those three days a year. Not the 362.

Josh Birk:
It’s those three days a year. You have 362.

James Simone:
Exactly.

Josh Birk:
Totally. Now, in my notes, you’re referring to something you’d like to call the Midnight in Paris Effect. I’m going to be honest, I had totally forgotten about that movie. Avoiding spoilers, what did you mean by that?

James Simone:
This is my favorite. You don’t have to have seen the movie. I think I rewatched it recently. Maybe that’s how I got to thinking about it as I was listening to this ChangeLog podcast.

Josh Birk:
Got you.

James Simone:
They were talking about how progress is more of a helix than it is some kind of linear line that you’re drawing. And so, you have these situations, where you’re continually going back to the same thing. You’re reimplementing the same thing. You’re doing a new project, new package, new class. Whatever it may be. Some of those things end up being the same.
I think that when we’re in the process of reinventing that wheel over and over again, it’s easy to say, “This is old hat.” Or, “It was better the last time that I did it.” Or, “Maybe it was better the first time that I did it.” Or, “I’m looking back on these things on GitHub from mid-2015, 2016. That’s the time period in which it would’ve been exciting to be doing this work.”
If you’re always looking back and thinking that that was the best time period to have been doing this stuff, you tend to miss out on the present. I think that you could just as equally say that this is the golden age of Salesforce development. Actually, there’s a lot of really exciting things that are new to the platform that are improving the DX of working on the platform all the time. Like the use of DataWeave to do things like parse XML responses. That would’ve been a nightmare before 2023. It’s not a nightmare anymore. It’s actually quite simple and it’s performing. These are things that I get excited about and I think about a lot.

Josh Birk:
Having watched the platform over time, I think you’re right. It’s easy to underappreciate just the number of tools that work so incredibly well. Back in my workshop days, I used to wax whimsical whenever I was showing anybody the by distance filter.
Because this was the first thing I did in Visualforce and JavaScript, was trying to figure out how many accounts were in a five-mile radius of a building. Back then, we didn’t have sine and cosine in Apex. If you want to do geometric math without sine and cosine? Congratulations. You can’t.

James Simone:
I loved that episode with you and David reminiscing about that. What was the decision? It was like, “Well, maybe we could just use a square instead?”

Josh Birk:
Just use a square.

James Simone:
Wouldn’t that be easy? That’s the kind of thing that I’m talking about. Instead of trying to hyperfixate on, “We absolutely need to hit this and this is exactly how we’re going to do it …” Not over-solutioning like that and being able to innovate right on the spot is such an important part of the things that make software development awesome.

Josh Birk:
This is going to be a classic segue, because yes, that was the decision. I spent a day researching whether or not I, me, myself, could replicate JavaScript’s geometric functions in Apex. That was the moment that I talked myself off the cliff. I was just like, “Okay. Before you do that, which somebody at Salesforce is going to get paid to do anyway, what else could we do?”
I’m like, “Is the client really going to care if it’s a square or radius?” The answer was that they did not. Instead of writing three new Apex libraries, I basically wrote seven lines of code. Which brings me to my next question. What does YAGNI mean?

James Simone:
That’s the classic, “You aren’t gonna need it.” This is something that I think a lot about in terms of the different companies that I’ve worked at. I am always reminiscing about going into an interface and looking for usages of this interface and finding a single implementation. That’s the kind of gold plating that we should be trying to avoid.
I think that there is a time and a place for abstraction. Absolutely. But when you’re doing things just for the sake of having heard that you should do them like, “I need to introduce an abstraction, because we might need something to operate in the same way but differently in the future.” Why not just do that in the future when you have the use case for it?

Josh Birk:
And so, to dovetail into that … Some of the stuff you’ve talked about is building with intent. Building in the safety, while you’re trying to move fast. From an Agile perspective, how do you know when to take the time to try to build out a framework like that so you’ve got some future-proofing versus not? Is there a tipping point?

James Simone:
We as a team have arrived at the usage of the quote, unquote, “Spike,” which I say with my air quotes. Because in case you’re not familiar with that terminology, it’s time that we are agreeing to set aside that we have specifically timeboxed to say, “What can we do? What’s possible? Also, what’s reasonable?”
An example of that that I can give from recent work that we’ve done is a GraphQL endpoint that we were working with. There are some really interesting Apex libraries for working with GraphQL. I think that they are really hyper focused on something that we weren’t necessarily interested in. When we were looking at what it would look like to introduce that kind of library and continue to use it … It didn’t really make sense.
“We’re going to import 20 classes that we’ve gotten from this GitHub repository just in order to interact with this endpoint.” That’s the kind of cost that is probably too high. Whereas we could, in the scope of maybe an hour max, come up with something that, “It’s just capable of interacting with this endpoint in a way that’s meaningful to us.” And if we need to further abstract it out later, we can do so.

Josh Birk:
It reminds me of … I think I was one of the longest-holding adherence to jQuery on the planet. I would get people asking, “Well, why don’t you just build this out in React?” Because I’m not building what you’re building. I’m building a single-page demo.
I just needed to flip a few divs around and make the button go all flashy. Yes, if you’re writing an enterprise web application that you’re going to have to maintain for the next five years, by all means. Go find a good app framework and do that. But sometimes, a little bit of code is actually going to go a long way.

James Simone:
Well, and this is another recent Changelog podcast episode, where they were reviewing the state of JS at the end of 2022. I think jQuery is still up there, Josh. You’re not alone.

Josh Birk:
Is it really?

James Simone:
You’re not operating in a room by yourself, my friend. There are a lot of people still using that dollar sign.

Josh Birk:
Gosh. That’s actually a little disturbing. Just only because the DOM handling in native JavaScript has gotten so good.

James Simone:
It has.

Josh Birk:
It has collapsed the old school browser wars sort of things. I think that’s actually … My usage of jQuery stopped after. I didn’t need its middle ground stuff like how to do a modal window and stuff like that. It’s almost like I keep scaling back because, well, I almost don’t code anymore. But what I was coding was mostly just exemplary stuff. Not stuff that was actually going to have to pass an engineering group here or anything like that.

James Simone:
But it’s that intense usage of and adoption of something that so clearly helps to move ground that ends up spurring the inclusion of that stuff in the base language. It’s gotten better because of jQuery. Because if jQuery didn’t exist, I don’t think that we would be seeing things like, “Get elements by class name,” just being accessible.

Josh Birk:
No. Exactly. Exactly. It’s the history and evolution of the web. Go back to the episode with Greg Whitworth. They’re talking about, “It’s basically just a bunch of shims.” People figure out how to write a library that does this thing that the browser doesn’t do, until the browser could later figure it out.
I don’t know if that evolution’s ever going to stop. I think the shims and the libraries and the standards committees are always going to be like, “Well, if we want to try something new, we have to bolt something on, until we can bring it in,” sort of thing.

James Simone:
I think that actually dovetails nicely back into the safety versus speed debate. Because what I’m really advocating for and what I feel like I’ve been talking a lot about recently is no abstraction has zero cost. That’s exactly why I told the story about the GraphQL stuff.

Josh Birk:
Got you.

James Simone:
When you’re introducing things, it has that cognitive overhead associated with it. Something that I’ve been really hyper focused on over the last year is, “What are the abstractions that I can introduce that introduce syntax sugar with the minimum amount of cognitive overhead?”
I want to keep things as close to the platform as I can, while still giving people a clear and definitive reason for, “Here’s why you should use this over what already exists, so that you are not just continually reinventing the wheel.” But even if you are, you’re getting faster at doing it.

Josh Birk:
By making smaller wheels, it sounds like.

James Simone:
Well, I don’t think … In this analogy, you probably aren’t stacking the wheels. I feel like maybe there’s somewhere in here that falls down. Exactly, Josh. Exactly.

Josh Birk:
Tell me a little bit about where the developer lifecycle, especially from an Agile point of view, what it looks like … Let me rephrase this, actually. When it comes to things like unit testing to help measure where your application is on this scale of safety, so to speak, what makes for a good unit test? And then, what makes for a bad unit test?

James Simone:
Obviously, I have some bias, which we’ve previously discussed. Just to bring it back into the open … We operate with test-driven development, so we’re writing the test first.

Josh Birk:
Got you.

James Simone:
Even with that bias being there, something that makes a good unit test is it runs fast, it has a minimum of ceremony associated with it, which is typically set up or DML. Or things that you are needing to do that aren’t actually necessary to exercise the code that you’re looking to exercise. It’s necessary because of some weird side effect that happens as part of that code. A good test gets straight to the point.
It tests. You provide input. You assert that the output for whatever that is, maybe it’s just manipulating the input that you’ve provided, matches your expectations. I think that when we either write tests first that do that, or model our tests off of the code that we’ve already written, you frequently find yourself getting into the mindset of, “But actually, there’s this other thing that I haven’t considered.”
And that’s another test. You start to self-document the edge cases to your product in a very organic and curiosity-driven way, which I think is a really powerful way to be applying our minds to programming problems.

Josh Birk:
It’s always been kind of a dividing line in the ecosystem. I don’t even know if, “Dividing lines,” is right. We put such a spotlight though on code coverage, because that’s the thing we force developers to do. You can’t deploy to production without 75% or above code coverage.

James Simone:
It’s a line that we’ve drawn in the sand.

Josh Birk:
Right. It’s like, “That’s great.” Because less than 75% code coverage, that’s a pretty good number. If you’re dipping into the 60%, your unit tests are probably not doing their job. But to your point, once you hit that code coverage, you might still have four unit tests to write. Because you might have three or four edge cases or personas or things that could go boom that your current unit test doesn’t cover.

James Simone:
This goes back to the legendary consultant i++ test method, where you’re just …

Josh Birk:
Our nemesis. Yes.

James Simone:
You’re just boosting that test coverage with lines of code. I think about this in my open source work a lot, where I use codecov.io to measure code coverage. It is funny how a lot of the times I find that my code coverage is actually decreasing. Because I’m removing lines of code, which means that the unmeasured lines of code that I haven’t actually hit, for whatever reason, end up taking up a greater percentage of that class and of the program as a whole.
I always have to laugh at that. Because some of these diffs that I’m generating, I’m like, “Wow. I removed 60 lines of code today and I updated 200. I think that’s a really powerful ratio, because all of my tests are still passing.” I know at the very least I haven’t introduced a new bug that I already knew about.
That’s not to say that … There are a lot of bugs I don’t know about. I’m working on those as soon as I find them, but I have such a feeling of safety. And yet, when I look at my code coverage percentage, it’s going down. Am I improving? I think I’m improving, but my code coverage measurement is not improving. That’s where I think that disconnect occurs.

Josh Birk:
Totally agreed. I think it created a false idol in the sense of, “Always strive for 100% code coverage.” Like that is some noble goal to achieve. Having spent, back in my days as an actual developer, a good portion of a day trying to figure out why that one IF statement isn’t getting hit … Because maybe, there’s something on the platform that isn’t communicating it to write.
Ask yourself the question, “If you accomplish this, are you actually going to feel more confident in the application? Or are you just accomplishing this because you want get 1% code coverage back up?”

James Simone:
I think when you’re attuned to where it’s meaningful, you can definitely understand. It sounds like 75% is actually a really positive thing to pin to. We can definitely all aspire to hitting that metric. It makes sense. But really, once you’re at 90-something percent …

Josh Birk:
80-something.

James Simone:
Right. Maybe start the question, are you just doing this to boost this artificial metric? Or are you looking to exercise something meaningful?

Josh Birk:
Exactly. Let’s flip this over to the other side of Agile and TDD development. Where in the life cycle is the importance of code reviews and actually getting humans together to look at possibly what needs to be refactored?

James Simone:
We’ve spoken a little bit before about how my team works. We’re on a video call all day with one another. We swap out in 15-minute increments. We are swapping out continually. We’re practicing trying to describe to somebody what we would like to have done. We’re also practicing operating as an intelligent keyboard.
I’ve heard a lot of people who work in the pair programming or mob programming space saying, “Well, actually, this is death to the PULL request. We don’t need to review our code, because we’re continually reviewing our code.” I actually feel strongly opposite that, and I think that my team would say the same thing.
We laugh about it all of the time, as we’ve heard people being embedded in different teams saying, “Well, doesn’t this mean that you don’t need to do code reviews anymore?” We find so many bugs or lines that we forgot to update. Things that weren’t found with PMD or whatever, but are just so obvious when you switch from that mindset of authoring to reviewing. I would never want to give that up.
I think it’s actually a shame. And this isn’t something that’s specific to Salesforce. This is an industrywide hate almost for PULL requests. I know a lot of people who hate reviewing code. They view it as a chore. I love reviewing code and I am trying to impart this love to other people. To encourage them to look at it more as an opportunity, not only to grow their own skills, but to be able to communicate empathetically with people in a way that ends up helping them improve in the future too.

Josh Birk:
No. I love that. I think you hit spot-on with the difference between an author flow and an editorial flow. Back in college, you would write your essay, and at the end of it, you just need somebody else to read it. Because your brain’s just been stuck in this paragraph after paragraph mode. You can’t just instantly convert over to the other mindset of, “Did that actually work? Does it actually make sense?”

James Simone:
Right. Sometimes you almost are like, “I can’t actually look at this anymore.”

Josh Birk:
Exactly. Exactly. I remember writing that three minutes ago. Of course, it’s perfect.

James Simone:
I don’t need to look at it anymore.

Josh Birk:
I don’t need to look at it anymore. I am good. Any tips for the code review? If somebody wants to get that skill, do you have top of mind things to tell people?

James Simone:
I learned recently, and I’d like to congratulate you as well, that our episode last year on Open Source was the Most Listened to Podcast of 2022 for the Salesforce Developer Podcast.

Josh Birk:
Yes.

James Simone:
I’m going to keep continually come back to this, Josh, and keep beating that over the head. Because I think especially if you’re looking to grow your reading skills, the best place that you can do it is by looking through PULL requests and open source repositories.
It doesn’t even have to be in the language that you’re writing in. I’m always looking for unidiomatic applications of code when I’m doing code reviews. I’m trying to see things that are unusual. When I get to something that’s unusual, I’m looking to see, again, did the author express their intent well? Are they explaining this mystery that I’m looking at?
Because there’s a lot of really obscure things that you can do, but if you communicate your intent well, it serves to tell the reader, “This person knows what they’re talking about. Or at least, they claim that they do.” You can form your own opinion about that. Of course. The judge is always out. The jury is for sure out.
But I think that that is the best way to improve your reading skills, and concomitantly, your PULL requesting skills as a reviewer. Go out there. Look at reviews that have been done on the big Salesforce open source repositories. Get a feel for what is idiomatic. Get a feel for things that somebody says, “Well, wait a second. This looks interesting, actually. Maybe that wasn’t meant to be in that specific method. Is that going to scale? Is that going to be a problem in some orgs where this feature isn’t available?”
You start to build up this mental model of, “These things are perfectly commonplace and ordinary.” Sometimes it’s okay to repeat yourself. You don’t have to die on that dry hill. Versus things where you’re like, “Query in a FOR loop? That’s going to be an immediate no.” Let’s talk about this.

Josh Birk:
Nice. Nice. Any other books, podcasts, blogs that you recommend people read? You can even give a shout out to your own, if you would like, that might help people get started with this kind of stuff.

James Simone:
I think that the Salesforce Developer Blog is an incredible resource. Of course, I have my own blog at the joysofapex.com. Just joysofapex.com. My good friend and colleague, Jonathan Gillespie, published today on that site, actually. An incredible article. Probably, everything that you’ve ever needed to know about caching in Apex, for example.

Josh Birk:
Cool.

James Simone:
We’re really trying to do deep dives on interesting parts of the platform that can be used by pretty much anybody. Looking through those concepts can really help to understand, “This is when I would use this particular kind of caching,” for example.

Josh Birk:
Got you. Nice. Give me a brief overview of the blog post you just put out on Combined Async Apex Framework. Did I get that right?

James Simone:
Close enough. You would know better than me at this point. I’m in the post-review mindset of, “I wrote it. It’s done.”

Josh Birk:
Right.

James Simone:
I think that this goes back to what we were talking about with operating as close to the metal as possible. I have tried to create an extremely low-cost abstraction that does all of the work for you, as far as figuring out what kind of async process needs to be launched in Apex. This thing will decide for you based on a set of records that you provide, or a query string, “Do I need to batch? Or can I run this as a chewable real fast?”

Josh Birk:
Got you.

James Simone:
I like this pattern a lot. I’m using it in several different open source applications with, I would like to say, great success. It’s something that has helped me to put that part of the application and that part of the Salesforce platform in a box that says, “I don’t want to worry about this anymore.” I want to focus on the actual functionality that I’m trying to achieve. So let’s put everything about asynchronicity into this box, and let it handle deciding what to do.

Josh Birk:
That’s our show. Now, before we go, since we have talked to James a few times on the show, I asked him about his other favorite non-technical hobby.

James Simone:
Sourdough bread baking. Sourdough pizza now too.

Josh Birk:
Nice.

James Simone:
My wife and I are big sourdough bread bakers. We have had a couple of starters now. In the sourdough community, I don’t know if you’re aware of this, but people like to talk about their Civil War starter. Like a starter that’s been handed down for generations.

Josh Birk:
Really?

James Simone:
We don’t have that. We’ve had to recreate the starter a couple of times over the course of various moves and all that good stuff. But I think that it’s one of those activities that really helps you to decompress. There’s really nothing like working with dough, but one of the other things that I also love about it is that it’s the kind of thing that you tend to every half-hour or every hour, let’s say, over the course of a day.
When we’re making bread, it might be an eight-hour long process of getting the dough ready, but it’s not a time-consuming process. It’s just not something you can rush.

Josh Birk:
Got it. Nice.

James Simone:
I think that that goes back to the safety versus speed thing again. You’re not making sourdough bread in an hour.

Josh Birk:
I want to thank James for the great conversation information, and as always, I want to thank you for listening. Now, if you want to learn more about this show, head on over to developer.salesforce.com/podcast where you can hear episodes, see those show notes, and have links to your favorite podcast service. Thanks again, everybody, and I’ll talk to you next week.

Get notified of new episodes with the new Salesforce Developers Slack app.