Post·technical
Adventures with ChatGPT, my Coding Sidekick
I've considered myself a healthy skeptic of Generative AI... until now.

As the majority of Americans now know, ChatGPT is a publicly available online chatbot released a little over six months ago. I’ve been using it first as a novelty, curious what it’s really capable of and what its limitations might be. Over time I’ve codified my personal use cases – times when I hoped to get some value out of it in my day to day life. At this point, while I wouldn’t say that it’s a critical part of my “life workflow”, it’s a major augmenting force, something I’m happy to be paying for and something I can easily point to for having made my life better.

It’s difficult to describe my feelings using ChatGPT in those first few weeks. Throughout the majority of my life, as someone who knows what computers are capable of, I’ve been painfully aware of the gap between mankind’s hopes for computing as expressed in science fiction, and reality as expressed in, I don’t know, Siri. I would quietly roll my eyes watching yet another unrealistic depiction of computer intelligence on the big screen. And yet, suddenly (so it seemed), computers have acquired an almost magical ability. The step function was remarkable, especially since other technologies I’ve followed (the Internet, smartphones, electric cars) emerged gradually – even if their adoption and impact on the world has been anything but. As a technologist who spends way too much of my life dealing with the limitations of computing, ranging from the challenges of tech projects at Hippo to figuring out what’s wrong this time with my parents’ PCs, interacting with ChatGPT was a breath of fresh air, and a teleportation to an earlier, more exciting time of my youth when computers triggered an unforgettable awe in me.

But I digress. I wanted to share my experiences using ChatCPT in one area that seemed particularly intriguing (and close to my heart): coding. Early on, I’ve read tweets, opinions and articles from others who boasted of ChatGPT having built fully functioning applications. I was pretty sure that the examples were likely cherry-picked and iterated on for maximum effect on social media. On the other hand, if there is one thing I would imagine a generative AI conversational system to be good at is creating content in a highly structured and logical domain – that is, in code. Of course, nothing beats in-person experience so I set out to write some code with the help of ChatGPT.

No production systems were harmed in the conducting of this experiment. I chose to make some progress on a personal project of mine, which seemed like a perfect application of the tool. Last year I had built a sort of “bespoke todo list on steroids” to keep me organized, and for a while now I’ve been meaning to add an Android widget for it. But I’ve never developed for Android, let alone built a widget for it. I’ve felt too impatient – maybe insecure? – to learn such a wildly different stack. I suspected I would have to trundle through low-quality tutorials, missing a key concept and getting stuck down the road. I imagined hours digging through Stack Overflow, trying to get some stupid thing to work and getting frustrated.

With ChatGPT, there was now another way. I would treat the tool as my coding sidekick, asking it to write, explain, and modify some code based on my prompts. I expected to do a lot of the wiring work (for example, updating the backend or setting up the auxiliary files in the Android app), reviewing a lot of code, and wading through a lot of false positives. I suspected that my requirements introduced some technical risk (quick few searches in the past showed that widgets have specific constraints which make writing code frustrating). I doubted that ChatGPT could write complete functionality for me, but in this case, I thought tweaking was going to be easier than writing everything from scratch, where I hardly knew how to even begin. Thus began the experiment.

Can you write the Kotlin code for an Android widget that makes an HTTP POST request to fetch json data for a list of items, and displays these items in a scrolling view? Each item should be preceded by a clickable button, and followed by a custom icon. The json data is an array of objects, and each object has three properties: the label to display on the button, the item’s text to display, and the name of the custom icon (stored as the project’s resource).

(Note: I really need to get in the habit of saying “please”. All our ChatGPT prompts are used to train future generations of the models so when AI becomes our overlord, I’m hoping that some courtesy now might spare me the worst fate…)

Lo and behold, ChatGPT came through wonderfully! I won’t bore you with the full response, but it:

  • Assumed a reasonable structure of the json data and gave me a sample
  • Gave me the data class corresponding to the json
  • Created a network helper for POST requests
  • Wrote the full code for the widget creation, the population of the list (which is nontrivial because of the limitations on Android widgets), and even the handling of button presses, and the metadata in XML configuration files
  • It helpfully told me what placeholders I should change in my actual project, and gave me a “TODO:” heads up that network operations should really run as a background thread

Granted, a good pattern matcher that scrapes Stack Overflow could do the above, but my first impression was overwhelmingly positive. I was particularly impressed at ChatGPT’s “default” level of information. It didn’t treat me like a beginner programmer, but it made sure to communicate assumptions and places where, as someone new to the stack, I could fall into traps. Perhaps there is, after all, a “universal” technical language that all programmers speak and that ChatGPT picked up as it was trained on all those Stack Overflow threads.

I quickly found that the key to both getting the value out of ChatGPT and testing its abilities is in the follow-ups.

Can you share the xml code for the layouts above?

ChatGPT did a great job here, too, remembering both my original prompt and its response, and making sure that the layouts were consistent while sharing the code it generated for multiple files. It even reminded me where to place the files.

More follow-ups:

And where do I add a reference to gson so that the build includes it? I think it’s in one of the gradle scripts, right? How do I modify makePostRequest above to take in POST parameters? The server returns json whose top level has three keys. How do I modify onDataSetChanged in MyWidgetFactory to extract an array that one of these keys is mapped to?

More superb performance, even with some IDE pointers (“After you have added this line, you should sync your project with the gradle files by clicking on Sync Now in the bar that appears at the top of the editor window.”), and a revision of the json data structure assumptions.

After an hour or so I paused to reflect on my experience so far. Doing this solo would have taken me over 20 hours, likely mired in frustrating tutorials and hard-to-parse Stack Overflow responses (if you complain about AI artifacts, you haven’t seen some of the arguably human responses to questions on that site!). Alternatively, I could ask someone to help me, and for a question that didn’t require reading a lot of code and that had a quick answer, that would be the optimal thing to do, but I couldn’t bear wasting a friend’s time on having them read or write hundreds of lines of code (ChatGPT generated over 400 lines by this point).

It’s been a surprisingly positive experience – magical, yes, but also fun and educational. I feel I’ve been able to short-circuit a lot of the boring part of learning a new stack. I still had to understand what’s going on – the incremental prompts allowed me to get my lessons in bite-sized pieces, but they also showed ChatGPT’s strength. In fact,

Takeaway #1. ChatGPT introduces a new paradigm of learning new technologies. What used to take hundreds of hours, with rabbit holes which help absorb knowledge with a high degree of inefficiency, is now a packed interactive adventure. Assuming what you want to build is complex enough and touches upon enough concepts, you will likely be able to internalize the material much faster.

I continued to build on my solution, adding local storage, coroutines, and more network activity. I found that

Takeaway #2. ChatGPT is able to hold a lot of context. Don’t be afraid to refer to code, prompts, or assumptions from earlier in the conversation.

Takeaway #3. Try to phrase your requests in increasing order of complexity, allowing ChatGPT to build on top of the solution it provided before.

Soon I encountered my first issue. After asking ChatGPT to add a click action, it gave me a snippet which referred to a non-existent variable. Let’s see if it’s able to fix it easily.

appWidgetId is not defined in getViewAt. I see it in MyWidgetProvider but not in MyWidgetFactory. How do I pass it to getViewAt?

ChatGPT obliged:

“Apologies for the confusion, you’re correct. The appWidgetId is not available in the MyWidgetFactory by default. To pass it to getViewAt(), you can …”

…and proceeded to fix the code for me.

In fact, as I started to approach some of the technically difficult pieces of my assignment, I ran into more issues:

The intent doesn’t get triggered when the icon is clicked. Do I need to set intent.action to something specific? I also still have the in the of my application in AndroidManifest. What could be an issue?

“Yes, you need to add a specific action to your Intent so that when it’s received in your AppWidgetProvider, you can differentiate it from other actions. In your getViewAt() method in MyWidgetFactory, add a specific action: …”

The intent is still not triggering. Is there something special about this being a widget that I should take into account? I read somewhere about PendingIntent, is this relevant here?

“My apologies for the confusion, you’re absolutely correct. Due to the way App Widgets work, we need to use PendingIntent for handling click events….”

This led me to probably the most important takeaway:

Takeaway #4. As humans, we still have to do the work guiding AI. We need to understand what code we’re writing and do a lot more work reviewing the code than we might otherwise be doing. There is value in doing some basic research and injecting ideas into the prompts, in case one of them helps our AI sidekick.

I found that there is an art to deciding when to start conversation threads. For an issue I ran into with button clicks not triggering, rather than polluting the main space, I created a new conversation. Since conversations don’t share context between them, that also gave me an opportunity to test how well ChatGPT can take in the code that I provide. In my prompt I pasted all the relevant code:

I have an Android Widget app written in kotlin. The app shows a ListView of items, each item consisting of a button and a TextView. The code shows the items correctly, but the button click listener that I set up never triggers. Could you help identify a problem in this code?

AndroidManifest.xml, inside <application>:

<receiver
    android:name=".TodayListWidget" ...

TodayListWidget.kt:

package com.example.widgettest
import android.appwidget.AppWidgetManager ...

today_list_widget.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto" ...

compileSdk and targetSdk are 32, targetApi is 31

ChatGPT’s (confident) answer didn’t solve my problem. Rather than give up I kept trying:

Unfortunately, I did that and the clicks are still not registering. The onReceive function is never called when I click any of the buttons. Any other ideas?

“My apologies for the confusion. I realized that there was a misunderstanding. Widgets use a different mechanism for registering click listeners….”

The second answer worked. Which brings me to Takeaway #5

Takeaway #5. More often than I would have thought, the first answer was incorrect but the second was correct. Don’t give up and ask for more ideas.

I’ve run into the above issue a lot, actually. Much of it was ChatGPT giving me an answer that works well in the context of an Android app, but that doesn’t work in a widget. It’s almost as if ChatGPT “forgot” that we’re working on a widget. Sometimes, reminding it in a prompt helped.

My adventure continues…

As the “baseline” code grew in size, I stopped relying on ChatGPT knowing the full context of my code. If there is an issue I’d like to solve, I present it with a “mini version” of the issue or just include the relevant excerpt, and ChatGPT handles this well – so far.

Writing this widget has been both easier, and harder than I imagined. Easier, in that I could basically dive into writing code without knowing kotlin, Android Studio, Android development, or widget development for Android! Harder, in that I ended up looking at code a lot – probably more than if I had just written it. I still had to think, troubleshoot, and do some online research, but with ChatGPT I had a perfect companion who knew the code inside out and was always eager to provide an answer. Often, the second or the third attempt was the successful one. If I pointed out what was wrong with its initial answer, it was more likely to arrive at the correct one. I had to be mindful of my prompts – what context did I already provide? What was missing? How can I articulate myself as clearly as possible? Which reminds me…

Takeaway #6. The ability to write clearly, concisely, and with a deep appreciation and awareness of what context I am – and I am not – sharing is critical when working with ChatGPT. True, the tool will try to compensate for lack of essential context, but early accuracy helps make future responses more effective. That said,…

Takeaway #7. I am torn about the conversational interface as the primary way to write code. On one hand, it’s a great interface for open-ended requests where alternatives (code, UI, search queries, discussion threads) fail. On the other hand, there is a high mental burden of having to think through and remember the context I’m sharing and ensuring that I’m clear in my prompts. When Chat GPT doesn’t give me an answer I need, I scratch my head trying to figure out how to approach the same question in “the right” way.

I’ve really just begun this adventure (and I’ll be the first to admit that one person building a pet project is very different from teams writing production-grade code), but two things are clear to me.

  • Software engineering as a discipline isn’t disappearing any time soon. Sorry, friends, if you were intending on retiring early.
  • If AI-augmented development via chat prevails (as opposed to through some other interface), software engineering is likely going to change significantly: The ability to write clear, concise prompts will be critical, as will be the ability to review the code and do rapid troubleshooting. You’ll be writing from scratch much less, and you will likely be less mired in useless Stack Overflow threads, but you will have to put yourself in the shoes of your AI partner more.

Disclaimer: No portion of the above post was written by ChatGPT. For now, I find writing exhilarating…