AI GoLand

Code like a PIRATE with Junie and GoLand

This is a guest post from John Arundel, a Go writer and teacher who runs a free email course for Go learners. His most recent book is The Deeper Love of Go.

Ahoy, maties! Cap’n Long John Arundel here with more tips on sailing the good ship GoLand. This time, we’ll lay aloft to the crow’s nest and turn our spyglass on Junie, the JetBrains AI coding agent.

If you’re new to Junie and AI tools, and aren’t sure where to start, think of this as your treasure map to the hidden gold of GoLand productivity. Arrr you ready to start coding like a pirate?

Flying the black flag

Your first voyage with AI development tools can be a perilous one, veering from calm seas of code to storms of syntax errors and test failures. So, will your AI agent be a trusty first mate, or just an unpredictable stochastic parrot squawking nonsense from your shoulder?

Junie is pretty smart, and she can tackle any task you choose, but she needs the guidance of a good cap’n. To help you stay on course, I’ve put together a handy six-step workflow I like to call “Code like a PIRATE”. Aye, ‘tis another o’ my made-up acronyms—but ye’ll find it easy to remember, me hearties [Are we doing the pirate thing for the whole article?—Anna]

“P” is for Plan

Every good voyage begins with a map. When you set Junie a task, tell her where the ship’s headed, so she’ll know which direction to steer. (I’m sure Junie won’t mind me calling her “she”; fun fact, lots of pirates were women—including quite a few of the men).

Ask Junie to draw up a quick chart for the voyage, but not to set sail until you’ve approved it:

Arr, Junie, me fine lass. I’m a swashbuckling pirate cap’n who needs a Go program to help me share out the booty from my latest captured Spanish galleon. Don’t code anything yet, but show me a brief plan of how the tool might work.

It’s important to get this stuff right before you even leave the dock, so don’t be afeared to spend a bit of time refining the plan. [I’m “afeared” we might be wearing out the salty sea-dog bit already—Anna]

“I” is for Iterate

Even the boldest captains don’t try to cross an ocean in a single leap. It’s more effective to island-hop, sailing a short distance at a time and checking you’re still on course. Give Junie one small task at a time, starting with the simplest possible program that could be useful:

Let’s start with a really simple prototype. I’d like to be able to run the ‘booty’ calculator and answer two questions: the number of crew, and the number of pieces of eight to be divided among them.

Assume everyone has an equal share. The tool should print out how much each crew member is due. Write just enough code to achieve this, and then we’ll think about the next stage.

With too vague a heading, Junie can end up going a bit adrift, like any of us: don’t hesitate to cry “Avast heaving there!” and interrupt her if that happens. Rowing back when the project has gone too far in the wrong direction will cost you a lot of time and doubloons [Seriously, clap a stopper on the pirate speak for now—Anna]. Sorry, I meant to say “tokens”.

“R” is for Review

Once Junie has completed each iteration, go through the code line by line to check and review her work. She’s pretty good at delivering what you asked for, but she doesn’t necessarily know how you want it. For example:

Nice job, Junie, but I have a few suggestions for improvement.

  1. Instead of creating a bufio.Scanner in main and passing a pointer to it into the askInt function, let’s eliminate some of that paperwork. Change askInt to take just the prompt string, and have it create the scanner internally.
  2. The askInt function shouldn’t print error messages and call os.Exit if there’s a scan error. Instead, have it return any error along with the integer result. Let main take care of all the printing and exiting.
  3. If there’s an error from strconv.Atoi, include the invalid input in the error message. For example, “Sorry, I didn’t understand %q. Please enter a whole number.”
  4. Move the shares calculation into its own function, so that we decouple the input/output code from the business logic. Have it return the share and remainder values, so that main can print them out.

When giving feedback, bundle all your comments together in one message. This lets Junie generate the new version of the program in a single step, saving tokens. If you keep making small comments and asking her to rebuild the whole program each time, you’ll find your pieces of eight—I mean, credits—dwindling rapidly.

Good programs have a harmonious architecture that makes overall sense: everything works the same way everywhere and it all seems to fit together neatly. Junie can’t achieve this without your guidance, so keep a hand on the tiller and help her ensure things slot neatly into a unified structure.

“A” is for Assess

Once Junie has finished the step you asked for, don’t just glance at the code and move on—take a moment to assess whether it actually does what it should. Does the program run cleanly? Do the functions behave as expected? Are there strange side effects lurking in the bilges, waiting to sink your ship later? [What did I just say?—Anna]

Now that you can see the program in action, you might realise it’s not quite what you want. If so, now’s the time to adjust course, either with Junie’s help or by making little steering inputs yourself.

If you’re happy with the assessment, though, you can move on to the next iterative step towards the final program:

Shiver me timbers, Junie, that be some fine work.

Could you now please move the business logic functions into a booty package in the project root, and put the main.go file into a cmd/booty subfolder?

Also, could ye change the plunder calculations so that the captain gets twice the share of a regular crewmember? Print out the captain’s share separately.

“T” is for Test

No old salt trusts a ship that hasn’t been through its sea-trials, and nor should you. As you and Junie build the program, check each new plank is watertight by adding tests to accompany each function. That way, you’ll know as soon as something springs a leak.

Arr, please add some unit tests now for the CalculateShares function. Generate at least ten test cases.

Move the askInt function into the booty package too, and add logic to check that the number entered is always 1 or greater, or return an appropriate error if it’s not.

Have the function take an io.Reader to read input from, and an io.Writer to print prompts to.

Generate two tests for this function, one for valid inputs, one for invalid inputs.

Junie can be a helpful shipmate when it comes to drafting tests, but don’t just accept her handiwork blindly. Ask yourself: What is this really testing? Are there hidden reefs—edge cases—that we’re missing? And, when the tests fail (they’re no use otherwise) do they print something helpful?

Tis a fine set of tests ye have there, Junie. Could you make them all run in parallel?

In the table tests, could you use a map of test cases keyed by name, and then use t.Run in the test loop with the map key as the subtest name? That’ll make it easier on any scurvy dogs trying to understand the failure output.

Don’t try to inspect the error string itself for invalid inputs; that leads to fragile tests. Instead, just check that AskInt returns any non-nil error for these cases.

“E” is for Evaluate

Machine learning is fine, but human learning is even better. After each task, take a little time to analyse what worked, and what could have gone better.

Were your prompts detailed enough? Did Junie sail safely into harbour, or did she end up grounded on a sandbar because her pilot was too busy splicing the mainbrace? Every voyage is a lesson that’ll help you sharpen your prompting skills, anticipate pitfalls, and become a steadier pirate cap’n for the next expedition.

If you remember the chart we’ve drawn here and use it to navigate your next project, with the help of Junie and GoLand, you’ll be ready to truly code like a PIRATE [That’s it, you’re walking the plank—Anna].

Anchors aweigh

Check out the booty calculator project to see what Junie and I built together—try using it to divvy up your own pirate booty with friends. It’s also kind of fun to say “booty”.

Until next time, shipmates, wishin’ ye fair winds and full sails!

Legal disclaimer: JetBrains s.r.o. does not advocate piracy, illegal seizure of vessels on the high seas, or the consumption of rum. Please swashbuckle responsibly.