Pair Programming with AI

Published on

Get weekly handpicked updates on Swift and SwiftUI!

Over the past two weeks, with the assistance of AI, I have embarked on rebuilding my blog in an unfamiliar development environment using languages and frameworks that are new to me. Through this rebuilding process, I hope to gain some mastery of these new languages and frameworks. This article records some of my experiences working with AI.

WikipediA:

Pair programming is a software development technique in which two programmers work together at one workstation. One, the driver, writes code while the other, the observer or navigator, reviews each line of code as it is typed in. The two programmers switch roles frequently.

While reviewing, the observer also considers the “strategic” direction of the work, coming up with ideas for improvements and likely future problems to address. This is intended to free the driver to focus all of their attention on the “tactical” aspects of completing the current task, using the observer as a safety net and guide.

Opportunity

I plan to start synchronously publishing articles in both Chinese and English versions on my blog from next year (currently, the English version is published on Medium). At the same time, I also intend to update the visual design of the blog. Therefore, I have decided to carry out a comprehensive reconstruction of the blog.

This reconstruction is not only about changing the appearance, but also an opportunity to challenge myself and learn new technologies. I have chosen to use a completely new programming language with the goal of deepening my understanding of this new language, framework, and the development environment that I am less familiar with.

In previous projects, although I have used some AI services, it was more of an exploratory experience rather than a deep immersion. Therefore, this reconstruction has become an excellent opportunity for me to deeply experience the working effects of AI and its advantages and disadvantages.

To ensure that AI plays a key role in this reconstruction, I have set the following rules:

  • The usage of traditional search engines for obtaining information should not exceed 20%.
  • No seeking help from other developers.

In other words, AI will become my main source of information, partner, and assistant during this development and learning process. This collaboration, in a sense, is similar to a “pair programming” with AI, where AI also takes on the role of a teacher.

In this “pair programming,” I have used services such as GitHub Copilot, ChatGPT, Claude, and Warp (AI assistants), considering them as key partners in this programming journey.

The journey of collaboration with AI

Choosing Technology Stack

In this stage of choosing a technology stack, I relied mainly on ChatGPT and Claude. By providing them with detailed information about my technical background and specific requirements, I gradually clarified the programming languages, frameworks, and editors I needed through multiple rounds of communication.

The conversation with AI was both free and divergent. Whenever AI made suggestions or prompts, I would delve deeper into certain directions or details and periodically summarize my understanding to confirm with AI again. Compared to several months ago, GPT-4 and Claude 2 no longer just cater to the questioner; they promptly and politely point out errors in my understanding, effectively preventing me from going further down the wrong path. Ultimately, I chose TypeScript, Astro, TailWindCSS, and VSCode as the combination for the blog’s refactoring.

AI provided me with great help in this stage, improving the efficiency of obtaining valuable information and helping me make decisions quickly. This can be attributed to the following reasons:

  • Clear requirements: My requirements were clear and common, making them easy for AI to understand, simplifying the entire communication process.
  • Mature technology choices: The technology stack I chose consists of mature projects with active online communities and rich documentation. This information provides reliable semantic resources for AI, ensuring its in-depth understanding of these technologies.
  • Combining personal experience: Leveraging my experience in other programming languages, I used familiar languages, frameworks, and development environments as references in discussions to help AI better understand my needs. This also made it easier for me to understand the suggestions provided by AI.
  • Complementarity of multiple AI platforms: At this stage, I had discussions on both ChatGPT and Claude. Although in most cases, the information provided by the two platforms was similar, occasionally they offered different directions, which was equivalent to having an additional person in the discussion.
  • Human judgment is indispensable: Despite the reduction in the amount of information provided by AI compared to traditional searches, if the user lacks analytical ability and decisive decision-making, they may still struggle to make a choice. This is often encountered when discussing with generative AI. Users must possess strong analytical and decision-making skills; otherwise, excessive freedom may hinder achieving satisfactory results.

Setting up the Development Environment

Although I also use VSCode regularly, I have never used it as my primary development tool before. My knowledge of installing Node.js and using NPM is also relatively limited. In this regard, AI has helped me successfully build the development environment.

When it comes to answering command line operations and the problems encountered during the process, the AI assistant provided by Warp is the most convenient to use. When I encounter an error, all I need to do is click the ⚡️ button, and the AI assistant will automatically submit the relevant commands and outputs as context to the AI. In comparison, in GitHub Copilot, I need to manually select the output content that needs to be explained in order to ensure the completeness of the context. I can do this by using the AI option in the right-click menu or the shortcut command @workspace /explain #terminalSelection, which is slightly more cumbersome than Warp.

Unlike Xcode’s integrated testing environment, in VSCode, developers need to choose the appropriate testing framework and plugins based on the language and framework they are using. I encountered some difficulties in this process. Initially, I tried to install Jest based on the AI’s suggestion, but I couldn’t succeed due to compatibility issues with Astro. After several unsuccessful discussions with the AI, I turned to search engines, but still couldn’t find a solution. Eventually, I found an article online. The article mentioned a knowledge point that I had not encountered in the configuration before. I informed the AI about this knowledge point and provided more context information. Finally, with the guidance of the AI, I successfully configured the Jest framework.

However, in the subsequent unit testing, I found that Jest couldn’t work together with Astro’s runtime environment. By consulting Astro’s official documentation, I discovered that ViTest is a more suitable testing framework for Astro. The installation process of ViTest went smoothly and it could perfectly run tests involving Astro code.

Therefore, in this project, I ended up configuring two testing frameworks: ViTest for Astro-specific tests, and Jest for other tests.

I’m not sure if it’s a configuration issue, but the default test code generated by GitHub Copilot through shortcut commands is based on Jest. In order to generate test code suitable for ViTest, I need to explicitly make this request through conversation.

From this experience, I realized that even with the help of AI and search engines, the most authoritative source of information is still the official documentation. Although AI has a considerable understanding of these documents, it sometimes misses key information. Therefore, the authority of the official documentation is irreplaceable and remains the preferred source of information.

Learning a New Language Through Code Reading

Reading the official templates provided by Astro has been the best way for me to understand Astro and learn TypeScript. At this stage, AI has played a decisive role as an assistant, greatly improving the efficiency of my learning process.

In an Astro project, the astro files may contain various elements such as TypeScript, JavaScript, HTML, CSS, as well as specific Astro tags and usage. For someone like me who had no prior experience with these, it was difficult to know where to start without the help of AI.

By having AI provide detailed explanations of the code, I gradually understand its structure and logic. Although Astro is relatively new compared to other frameworks, the AI knowledge base has a sufficient understanding of it. AI can clearly indicate the meaning of different parts of the code, and for areas that I don’t understand, I continue to ask for further explanations.

During this discussion process, I make full use of my knowledge of other programming languages and frameworks as a reference in conversations with AI. I also regularly summarize my understanding and ask AI to help correct any misconceptions. Additionally, as the discussions progress, I periodically ask for AI to provide a summary of previous discussions for record-keeping purposes.

The code explanations and discussions in this stage mainly take place in GitHub Copilot. Although GitHub Copilot performs well overall, there are a few things to keep in mind while using it:

  • If no specific code is selected, GitHub Copilot only explains the visible code in the current editing window.
  • To provide more context to GitHub Copilot, it is necessary to manually select the code you want to submit as the current context of the problem.
  • GitHub Copilot does not support discussions across multiple documents, so users need to integrate the contents of different documents themselves to form a complete context.
  • The answers from GitHub Copilot have a limited length, and if the answer is too long, the prompt may cover the already provided code, in which case assistance from ChatGPT or Claude may be needed.
  • In some cases, the quality of answers from GitHub Copilot may not be as good as ChatGPT.

Overall, AI has brought me great surprises in assisting my learning process. In the future, I plan to incorporate AI more into my learning process.

Coding Practices

Automatically generating code based on prompts is the best way for developers to experience the powerful capabilities of AI. GitHub Copilot, in particular, can understand developers’ intentions and generate high-quality code in real-time, which has sparked enthusiastic discussions among the developer community. For me, while this feature is indeed excellent, it has become a hindrance to my current needs.

In this blog refactoring project, I not only want to create a new blog but also hope to learn and master new languages and frameworks in the process. With GitHub Copilot enabled, as long as I provide enough prompts (comments), Copilot quickly generates results. At first, I thought this was a good approach. However, as I used it more, I found myself developing a habit of programming towards AI in a short amount of time: I focused more on the impact of comments on code generation rather than conceptualizing the specific code implementation. This contradicted my desire to master a new language through this refactoring. Relying on the code results given by AI only gave me the illusion that I had mastered it, when in reality I hadn’t.

After realizing this situation, I only enable GitHub Copilot’s real-time code generation feature when I am unable to implement it independently. Regardless of whether it is written well or poorly, I will try to write it myself first, and then let AI help me find issues and gradually improve the code’s readability and usability. During this process, I will consult AI for grammar details and let AI guide me in using programming paradigms that are more in line with TypeScript and more authentic code implementation methods.

Since the code for the same functionality will be repeatedly created multiple times, it is important to create unit tests in advance. In the process of constantly modifying the code, there are often situations where errors need to be corrected or optimized. With tests, problems can be discovered promptly.

In VSCode, whether it’s Jest or ViTest, automatic testing can be enabled, which means running the tests immediately after modifying the code. I hope Xcode can also provide similar capabilities.

With AI having the ability to quickly write code, many developers worry about being replaced by AI. As a developer, I believe that the key to avoiding being replaced is to continuously improve one’s own skills and demonstrate the value that AI cannot replace. Over-reliance on AI can indeed improve work efficiency in certain aspects or achieve results that were previously impossible, but in the long run, developers may gradually lose their own advantages and ultimately transform from users of AI tools to assistants of AI tools: human prompt generators.

Finally

After this period of close collaboration with AI products, I have come to realize the importance of maintaining personal technical growth and independent thinking while effectively utilizing AI. The rapid development of AI is unstoppable and will undoubtedly have a profound impact on all aspects of our lives and work in the future (in fact, it has already begun). In this era of increasingly popular AI, those who hope to continue to thrive must learn how to properly harness AI and demonstrate their unique value in this era.

The reconstruction work of the blog is still in progress and is expected to be completed by the end of the year.

I'm really looking forward to hearing your thoughts! Please Leave Your Comments Below to share your views and insights.

Fatbobman(东坡肘子)

I'm passionate about life and sharing knowledge. My blog focuses on Swift, SwiftUI, Core Data, and Swift Data. Follow my social media for the latest updates.

You can support me in the following ways