How to Review and Refactor Code with GPT-4 (and ChatGPT)

Share this article

How to Review and Refactor Code with GPT-4 (and ChatGPT)

It’s time to enhance your coding process with AI-driven code improvement. The GPT family of models from OpenAI offers developers a wealth of opportunities to improve, review, fix, and even outsource code writing. Knowing how to use these large language models during the development process will soon become an essential tool in the developer toolkit.

Ever wondered how AI could transform your coding process? In this guide, we’ll demonstrate techniques for using ChatGPT or GPT-4 to review and refactor code, as well as discuss some limitations and provide handy resources for using these LLMs in your programming workflow.

We’ll start with ways we can review and refactor, and for each of these, you may want to experiment with different prompts and the provided techniques to unlock the full potential of AI-driven code improvement.

Note: I will use the term GPT4 during the content as this is the current model prompted for the containted examples. ChatGPT (GPT3.5) works in a similar way and can be used interchangeably.

Key Takeaways

  • Utilize GPT-4 for a streamlined code refactoring process that enhances readability, maintainability, and adherence to coding best practices, ultimately leading to more robust software.
  • Experiment with different prompts and techniques with GPT-4 to modernize old code, ensuring it aligns with contemporary programming standards and best practices.
  • Leverage GPT-4’s ability to detect and fix errors, significantly reducing debugging time and helping to maintain a secure and efficient codebase.
  • Employ GPT-4 to generate boilerplate code and unit tests, facilitating a faster startup for new projects and ensuring code reliability from day one.
  • Utilize a multi-prompt approach (prompt chaining) with GPT-4 to refine the refactoring process, enabling a more targeted and effective code review and overhaul.
  • Be mindful of GPT-4’s limitations, such as its potential to generate confidently incorrect code or outdated information, requiring careful oversight and validation by human developers.

Table of contents

Refactoring Code with GPT-4 and ChatGPT

Refactoring code is crucial for several reasons: it enhances readability and maintainability, making it easier for developers to understand and modify the code. It also helps prevent potential bugs and ensures that your code adheres to established best practices. Ultimately, refactoring can lead to more efficient, reliable, and robust software.

GPT-4 can significantly contribute to this process. By using GPT-4 to review and assess your code, you can quickly identify areas for improvement and create cleaner, more efficient code. Leveraging GPT-4’s capabilities can save time and reduce human errors in the process, resulting in more consistent adherence to coding standards.

Modernizing Old Code

You can quickly modernize your code by providing your old function to GPT-4 and ask it to refactor it to modern coding practices.

Note: This prompt example has introduced a logical error in the function. We’ve intentionally shown this example as a great as example of ‘you get what you ask for’. When asking ChatGPT to review the code for logical errors, it is able to identify them.

Prompt: Refactor the following code to modern es6 programming standards

Before:

function tempConvert(temp, scale) { // Vague function name
  var result = 0; // 'var' is so es2015
  if (scale == "C") { // Is this the correct way to compare strings?
    result = (temp - 32) * (5 / 9); // Magic numbers
  } else {
    result = (temp * (9 / 5)) + 32;
  }
  return result.toFixed(1) + "°" + (scale == "C" ? "F" : "C"); // This line feels a bit cluttered...
}

After:

/**
 * Converts a temperature between Celsius and Fahrenheit.
 * @param {number} temp - The temperature value to convert.
 * @param {string} scale - The temperature scale ('C' or 'F') to convert from.
 * @return {string} The converted temperature value, formatted with one decimal place and the appropriate unit.
 */
const tempConvert = (temp, scale) => {
  const isValidScale = scale === "C" || scale === "F";
  if (!isValidScale) {
    throw new Error("Invalid scale: must be 'C' or 'F'.");
  }

  const conversionFactor = 5 / 9; // <-- Note: This is not correct when 
  const result = scale === "C"
    ? (temp - 32) * conversionFactor
    : (temp * conversionFactor) + 32;

  const resultUnit = scale === "C" ? "F" : "C";
  return `${result.toFixed(1)}°${resultUnit}`;
}

In this refactored version, GPT4 quickly made the following improvements:

  1. Added JSDoc comments
  2. Converted the tempConvert function to an arrow function.
  3. Replaced var with const for immutable variables.
  4. Used strict equality checks (===) for string comparisons.
  5. Introduced a constant to eliminate magic numbers.
  6. Simplified the return statement with template literals.

Issues:

  • Logic: This technique and prompt is adept at updating known coding practices but can turn a blind eye to business logic. The example below incorrectly refactors the conversion logic.

After (Take 2):

We the same prompt from … and voila, it returned a much better version of the function. This two, or more pass, approach is extremely effective.

...
function convertTemperature(temperature, scale) {
  const isValidScale = scale === "C" || scale === "F";
  if (!isValidScale) {
    throw new Error("Invalid scale: must be 'C' or 'F'.");
  }

  const convertedTemperature = scale === "C"
    ? (temperature * (9 / 5)) + 32
    : (temperature - 32) * (5 / 9);

  const resultUnit = scale === "C" ? "F" : "C";
  return `${convertedTemperature.toFixed(1)}°${resultUnit}`;
}

Adding Coding Best Practices or Principles

Your organisation or code base might use certain coding practices and styles that you want to keep. For situations like this, provide instructions to GPT4 on what particular coding practice, or style you’d like it to focus on.

Prompt: Review the following code and refactor it to make it more DRY and adopt the SOLID programming principles.

Note with the same input it has adopted the SOLID programming principle of Single Responsibility and split the function into 3. Unlike the ‘Modernize’ step earlier, it did not convert the function to an arrow function.

“By extracting the conversion logic into separate functions, we’ve improved the code’s adherence to the Single Responsibility Principle (part of SOLID), as each function now has a clear, focused purpose.”

function tempConvert(temp, scale) {
  const isValidScale = scale === "C" || scale === "F";
  if (!isValidScale) {
    throw new Error("Invalid scale: must be 'C' or 'F'.");
  }

  const result = scale === "C" ? celsiusToFahrenheit(temp) : fahrenheitToCelsius(temp);
  const resultUnit = scale === "C" ? "F" : "C";
  return `${result.toFixed(1)}°${resultUnit}`;
}

function celsiusToFahrenheit(temp) {
  const conversionFactor = 9 / 5;
  return (temp * conversionFactor) + 32;
}

function fahrenheitToCelsius(temp) {
  const conversionFactor = 5 / 9;
  return (temp - 32) * conversionFactor;
}

Detecting and Fixing Errors

Sometimes we are blind to the vulnerabilities or potential issues our code can create. Getting GPT-4 to review and address code issues can save you more than just time.

Prompt: Review this code for errors and refactor to fix any issues: ...

Input (Flawed) Function:

function updateTotalPrice(items, discountPercentage) {
  let totalPrice = 0;

  for (let i = 0; i < items.length; i++) {
    const item = items[i];
    totalPrice += item.price * item.quantity;
  }

  // Potential error: discountPercentage is not validated or checked for boundary conditions
  const discount = totalPrice * (discountPercentage / 100);
  totalPrice -= discount;

  return totalPrice;
}

Output:

function updateTotalPrice(items, discountPercentage) {
  // Fix 1: Validate input parameters
  if (!Array.isArray(items) || typeof discountPercentage !== 'number') {
    throw new Error('Invalid input parameters');
  }

  // Fix 2: Check for boundary conditions of discountPercentage
  if (discountPercentage < 0 || discountPercentage > 100) {
    throw new Error('Invalid discount percentage value. It should be between 0 and 100');
  }

  let totalPrice = 0;

  for (let i = 0; i < items.length; i++) {
    const item = items[i];
    
    // Fix 3: Validate item properties and types
    if (!item.hasOwnProperty('price') || !item.hasOwnProperty('quantity') || 
        typeof item.price !== 'number' || typeof item.quantity !== 'number') {
      throw new Error('Invalid item properties');
    }

    totalPrice += item.price * item.quantity;
  }

  const discount = totalPrice * (discountPercentage / 100);
  totalPrice -= discount;

  return totalPrice;
}

Changes that GPT-4 made:

  1. Added input parameter validation to ensure items is an array and discountPercentage is a number.
  2. Checked boundary conditions for discountPercentage to ensure it’s within the 0-100 range.
  3. Added validation for item properties and their types to ensure price and quantity are numbers.

Create Boilerplate Code (*my favourite)

Starting new projects can be a painful. GPT-4 doesn’t know your business logic but it can be used to kick off the boring boilerplate code on day 1. This isn’t technically refactoring but it’s amazing and can be part of an process in the programming lifecycle.

Prompt: Write me a boilerplate Node.js function that will take a variable of type User, validate that the user has the right permissions, fetch an array of item type Posts from a postgres database and return them. Leave comments for business logic.

Create Unit Tests

Not only are unit tests important for your code base but they can be a useful way to quickly validate anything produced by GPT-4.

Prompt: Create 2 unit tests for the provided code. One for a successful condition and one for failure.

Transpiling Code

There are many reasons you may need to convert code from one language to another. You’ve found a repo with code for one language that you need in another, you’re moving code bases, or maybe your boss read an article on the latest front end framework and now you’re moving to {divisive new library}.

In any case, GPT-4 can provide assistance with a simple prompt.

Prompt: Rewrite the following code in Rust: ...

Add comments to code

If your code is self-explanatory but requires commenting, this can be a huge time-saver.

Prompt: Add comments to the following code ...

Tips for Better Refactoring

Like many things in life, with GPT-4, you get out what you put in. In this case, providing more context, instructions, and guidance will usually produce better results.

Here’s a short list of tips and techniques to improve your code refactoring:

  • Split your prompts: Try breaking your prompts and desired outcome across multiple steps. Keeping prompts to have a single outcome has shown to produce better results than combined prompts. For example, ask for a review, then ask for a refactor based on the review response. This may become less important in time as LLMs increase their token limit.
  • Give Examples: Provide expected inputs, data and outputs to improve accuracy quality.
  • Be Specific: Don’t be afraid to list exactly what you want, what you know, what is needed, and what not to include.
  • Ask it to Reflect: A technique called reflexion has been shown to increase GPT4’s accuracy. Basically ask it ‘Why were you wrong?’ or get it to reflect and review its own response.

A Multi Prompt Approach (Prompt Chaining)

Writing prompts for GPT-4 is much like writing functions. A well designed set of prompts is one where each has separated concerns and singular responsibilities. Here’s a simple chain of prompts to update, refactor, and review a piece of code. You may not need each step in your case.

You will notice that the produced function at the is very different to what we created earlier. In each step of the process we either improve the code or validate it’s efficacy before running the code on our system.

Note: The same input function from earlier was used but run on a different model and different day.

1. Modernize and Add Best Practices

Get GPT-4 to re-write your code into the style you want. As seen above, this step will generally result in coherent output, in the style you want, but may introduce errors, so we do it first.

Prompt: Review the following code and re-write it to modern es6 programming standards and formatting: {{tempConvert function from earlier}}

GPT-4 Response:

const tempConvert = (temp, scale) => { // More descriptive function name
  let result = 0; // Use 'let' instead of 'var'
  const fahrenheitToCelsius = (temp - 32) * (5 / 9);
  const celsiusToFahrenheit = (temp * (9 / 5)) + 32;

  if (scale === "C") { // Use strict equality operator (===) for comparison
    result = fahrenheitToCelsius;
  } else {
    result = celsiusToFahrenheit;
  }

  const convertedScale = scale === "C" ? "F" : "C";
  return `${result.toFixed(1)}°${convertedScale}`; // Use template literals for cleaner string concatenation
};

2. Review for Logical Errors and Security Concerns

Get a review of your code with recommendations to improve any logical or security concerns introduced. It’s important that we don’t ask for a refactor, just the reasoning behind wanting the refactor.

Prompt: Review your provided code 'tempConvert' for any logical or security concerns and provide a list of recommendations.

GPT-4 Response: Here are some recommendations for improving the tempConvert function to address logical concerns and make it more robust:

  1. Input validation: The function does not perform any input validation for the provided temp and scale parameters. This could result in unexpected behavior if the input is not in the expected format. To address this, you could add input validation checks:
if (typeof temp !== 'number' || (scale !== 'C' && scale !== 'F')) {
  throw new Error('Invalid input. Temp must be a number and scale must be either "C" or "F".');
}
  1. Unhandled scale value: If the scale parameter is not “C” or “F”, the function will still perform the Celsius to Fahrenheit conversion, which could be misleading. You could add a check to handle this case:
if (scale === 'C') {
  result = fahrenheitToCelsius;
} else if (scale === 'F') {
  result = celsiusToFahrenheit;
} else {
  throw new Error('Invalid scale value. Scale must be either "C" or "F".');
}
  1. Code readability: To improve readability and maintainability, you can separate the conversion logic into two separate functions for each conversion (Fahrenheit to Celsius and Celsius to Fahrenheit). This will make the code easier to understand and maintain:
const fahrenheitToCelsius = temp => (temp - 32) * (5 / 9);
const celsiusToFahrenheit = temp => (temp * (9 / 5)) + 32;

3. Validate the recommendations (Reflexion)

Validate the provided recommendations. As shown above reflexion is a powerful technique to improve the accuracy of the initial recommendations and try to eliminate any hallucinations.

This is not always required but it is worth asking if you are unsure about any recommendations. In our example, it just repeats the same recommendations. In this case, it did not provide any additional information but did confirm the recommendations were valid.

Prompt: Review your above recommendations. Tell me why you were wrong and if any recommendations were overlooked or incorrectly added?

GPT-4 Response: I apologize for any confusion. After reviewing the tempConvert function I provided earlier, I realized that I made an error in my previous response. I already incorporated strict equality (===) and template literals in the provided function.

However, my initial recommendations still apply to improve the function’s robustness and readability. To summarize, here are the updated recommendations:

  1. Input validation: Add input validation checks for the temp and scale parameters to ensure they are of the expected types and values: {code}
  1. Unhandled scale value: Handle cases where the scale parameter is not “C” or “F” to avoid misleading conversions: {code}
  1. Code readability: Separate the conversion logic into two separate functions to improve readability and maintainability: {code}

I hope this clears up any confusion. The above recommendations should enhance the logical flow of the tempConvert function and make it more robust in handling various input scenarios.

4. Write the code

Combine your reviews, recommendations and feedback and get GPT-4 to write your fancy new function.

Prompt: Re-write the convertTemp function based off your review and recommendations.


const fahrenheitToCelsius = temp => (temp - 32) * (5 / 9);
const celsiusToFahrenheit = temp => (temp * (9 / 5)) + 32;

const tempConvert = (temp, scale) => {
  if (typeof temp !== 'number' || (scale !== 'C' && scale !== 'F')) {
    throw new Error('Invalid input. Temp must be a number and scale must be either "C" or "F".');
  }

  let result = 0;

  if (scale === 'C') {
    result = fahrenheitToCelsius(temp);
  } else if (scale === 'F') {
    result = celsiusToFahrenheit(temp);
  } else {
    throw new Error('Invalid scale value. Scale must be either "C" or "F".');
  }

  const convertedScale = scale === "C" ? "F" : "C";
  return `${result.toFixed(1)}°${convertedScale}`;
};

5. Create Tests

Finally, we ask it to create some simple JavaScript tests that we can run locally and validate the results of our fancy new function.

Prompt: Create two vanilla javascript tests for the above tempConvert function. One that is expected to pass and one that is expected to fail.

GPT-4 Response: Here are two simple vanilla JavaScript tests for the tempConvert function, one expected to pass and the other expected to fail:

const testTempConvertPass = () => {
  const inputTemp = 32;
  const inputScale = 'C';
  const expectedResult = '0.0°C';

  const result = tempConvert(inputTemp, inputScale);

  if (result === expectedResult) {
    console.log('Test pass: tempConvert with valid input');
  } else {
    console.error(`Test fail: tempConvert with valid input. Expected ${expectedResult} but got ${result}`);
  }
};

const testTempConvertFail = () => {
  try {
    const inputTemp = 32;
    const inputScale = 'InvalidScale';
    tempConvert(inputTemp, inputScale);
    console.error('Test fail: tempConvert with invalid input should throw an error');
  } catch (error) {
    console.log('Test pass: tempConvert with invalid input');
  }
};

// Run the tests
testTempConvertPass();
testTempConvertFail();

Limitations

This article is very pro-AI, however these models are not perfect and cannot (yet) accurately replicate business logic, among other things. Here’s a list of things to look out for and avoid when using GPT-4 to review or refactor your code:

  • It can be (confidently) wrong: GPT4 is trained to sound convincing but that doesn’t mean its always right. Another great article on refactoring Golang with ChatGPT reported ‘It got rid of the type checks with the confident explanation that type-asserting a non-int value to an int type will return the zero value for the int type, but this is not correct and will panic.
  • Saving time upfront may not be worth it in the long run: Sure, GPT-4 can generate you 50 lines of code in a minute but it may end up taking you 45 minutes to debug and tweak it if it is not fit for your codebase. You would have been better off writing it yourself.
  • It can be out of date: The technology world moves fast. “GPT-4 generally lacks knowledge of events that have occurred after the vast majority of its data cuts off (September 2021). You may encounter issues with any newly updated library, framework, or technology.

Conclusion

AI-powered programming is only new but it is here to stay. When used correctly it can save time and help us write better code. I hope you’ve enjoyed this article and have taken away some new skills to boost your programming productivity or error handling.

FAQs on How to Review and Refactor Code with GPT-4 (and ChatGPT)

What is the Role of GPT-4 in Code Refactoring?

GPT-4, or Generative Pretrained Transformer 3, is an artificial intelligence model that uses machine learning to produce human-like text. In the context of code refactoring, GPT-4 can be used to automate the process of improving the design of existing code without changing its external behavior. It can analyze the existing code, understand its functionality, and rewrite it in a more efficient and cleaner way. This can significantly reduce the time and effort required for code refactoring, making the development process more efficient.

How Does GPT-4 Understand Code?

GPT-4 uses a machine learning technique called transformer neural networks. These networks are designed to understand the context of the input they receive. When GPT-4 is given a piece of code, it uses this context understanding to interpret the code’s functionality. It can then generate new code that performs the same function but in a more efficient or cleaner way.

Can GPT-4 Handle Complex Code Refactoring Tasks?

While GPT-4 is incredibly powerful, it’s not perfect. It can handle many code refactoring tasks, but it may struggle with very complex or niche tasks. However, it’s continually learning and improving, so its capabilities are constantly expanding. It’s also worth noting that GPT-4 is a tool to assist developers, not replace them. It can automate many tasks, but a human developer is still needed to oversee the process and handle tasks beyond GPT-4’s capabilities.

How Can I Integrate GPT-4 into My Development Process?

Integrating GPT-4 into your development process can be done through the OpenAI API. This API allows you to send requests to the GPT-4 model and receive generated text in response. You can use this functionality to automate code refactoring tasks. However, it’s important to note that using the OpenAI API requires an understanding of how to work with APIs and the specific requirements of the OpenAI API.

What are the Limitations of Using GPT-4 for Code Refactoring?

While GPT-4 can automate many code refactoring tasks, it’s not without its limitations. It may struggle with very complex or niche tasks, and it requires oversight from a human developer to ensure the generated code is correct and efficient. Additionally, using GPT-4 requires access to the OpenAI API, which may not be feasible for all developers or organizations.

Can GPT-4 Refactor Code in Any Programming Language?

GPT-4 is a language-agnostic model, meaning it can understand and generate text in any language, including programming languages. However, its effectiveness may vary depending on the complexity of the language and the specific task at hand. It’s also worth noting that while GPT-4 can understand many programming languages, it’s not a substitute for a developer with expertise in a specific language.

How Accurate is GPT-4 in Code Refactoring?

The accuracy of GPT-4 in code refactoring can vary depending on the complexity of the task and the specific code involved. In general, GPT-4 is capable of producing high-quality, efficient code. However, it’s not infallible and should be used as a tool to assist developers, not replace them. It’s always important to review and test any code generated by GPT-4 to ensure it’s correct and efficient.

Can GPT-4 Help with Debugging Code?

GPT-4 can potentially assist with debugging code by analyzing the code and identifying potential issues or inefficiencies. However, its effectiveness in this area can vary depending on the complexity of the code and the specific issue. As with code refactoring, it’s important to review and test any changes suggested or made by GPT-4 to ensure they’re correct and beneficial.

Is GPT-4 Suitable for All Development Projects?

While GPT-4 can be a valuable tool for many development projects, it may not be suitable for all. Its effectiveness can vary depending on the complexity of the project and the specific tasks involved. Additionally, using GPT-4 requires access to the OpenAI API and an understanding of how to work with APIs, which may not be feasible for all projects or developers.

How Can I Learn More About Using GPT-4 for Code Refactoring?

There are many resources available for learning more about GPT-4 and its applications in code refactoring. The OpenAI website is a great place to start, as it provides detailed information about the GPT-4 model and the OpenAI API. There are also many online tutorials and articles that provide practical examples and advice for using GPT-4 in code refactoring.

Mark O'NeillMark O'Neill
View Author

Mark is the General Manager of SitePoint.com. He loves to read and write about technology, startups, programming languages, and no code tools.

gpt-4
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week